diff --git a/.clang_complete b/.clang_complete
index 79d0946b3320cb8732546341714e0686bdfcc08d..e35f74198f6bd22a22c1b547deb4711eb9d74e7a 100644
--- a/.clang_complete
+++ b/.clang_complete
@@ -4,5 +4,6 @@
 -Igens
 -I.
 -Ithird_party/boringssl/include
+-Ithird_party/benchmark/include
 -Ithird_party/zlib
 -Ithird_party/protobuf/src
diff --git a/.gitignore b/.gitignore
index 56e4b6d4b43e9b0c1becd55c01a26e1855d58cda..5e38f5fa01b273e81d9fd0526f707a783a66a5bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,7 @@ objs
 # Python items
 cython_debug/
 python_build/
-python_format_venv/
+yapf_virtual_environment/
 python_pylint_venv/
 .coverage*
 .eggs
@@ -115,3 +115,16 @@ bazel-testlogs
 
 # Debug output
 gdb.txt
+
+# ctags file
+tags
+
+# perf data
+perf.data
+perf.data.old
+
+# bm_diff
+bm_diff_new/
+bm_diff_old/
+bm_*.json
+
diff --git a/.gitmodules b/.gitmodules
index c8ca8ab046332dc65d9de36fcb69da09ea306205..144fd080ac970a02d509dd4653c407d48a7c4894 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -14,12 +14,13 @@
 [submodule "third_party/boringssl"]
 	path = third_party/boringssl
 	url = https://github.com/google/boringssl.git
-[submodule "third_party/thrift"]
-	path = third_party/thrift
-	url = https://github.com/apache/thrift.git
 [submodule "third_party/benchmark"]
 	path = third_party/benchmark
 	url = https://github.com/google/benchmark
 [submodule "third_party/boringssl-with-bazel"]
 	path = third_party/boringssl-with-bazel
 	url = https://boringssl.googlesource.com/boringssl
+[submodule "third_party/cares/cares"]
+	path = third_party/cares/cares
+	url = https://github.com/c-ares/c-ares.git
+	branch = cares-1_12_0
diff --git a/.pylintrc b/.pylintrc
index f7cf0588ac8976a6c4e613cd85992542541d576b..41027479061b42b3bbf67015f0e64449baa4e67b 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -3,34 +3,38 @@
 # not include "unused_" and "ignored_" by default?
 dummy-variables-rgx=^ignored_|^unused_
 
+[DESIGN]
+# NOTE(nathaniel): Not particularly attached to this value; it just seems to
+# be what works for us at the moment (excepting the dead-code-walking Beta
+# API).
+max-args=6
+
+[MISCELLANEOUS]
+# NOTE(nathaniel): We are big fans of "TODO(<issue link>): " and
+# "NOTE(<username or issue link>): ". We do not allow "TODO:",
+# "TODO(<username>):", "FIXME:", or anything else.
+notes=FIXME,XXX
+
 [MESSAGES CONTROL]
 
 #TODO: Enable missing-docstring
 #TODO: Enable too-few-public-methods
-#TODO: Enable too-many-arguments
 #TODO: Enable no-init
 #TODO: Enable duplicate-code
 #TODO: Enable invalid-name
-#TODO: Enable suppressed-message
 #TODO: Enable locally-disabled
 #TODO: Enable protected-access
 #TODO: Enable no-name-in-module
-#TODO: Enable unused-argument
-#TODO: Enable fixme
 #TODO: Enable wrong-import-order
-#TODO: Enable no-value-for-parameter
-#TODO: Enable cyclic-import
-#TODO: Enable redefined-outer-name
+# TODO(https://github.com/PyCQA/pylint/issues/59#issuecomment-283774279):
+# enable cyclic-import after a 1.7-or-later pylint release that recognizes our
+# disable=cyclic-import suppressions.
 #TODO: Enable too-many-instance-attributes
-#TODO: Enable broad-except
-#TODO: Enable too-many-locals
 #TODO: Enable too-many-lines
 #TODO: Enable redefined-variable-type
 #TODO: Enable next-method-called
 #TODO: Enable import-error
 #TODO: Enable useless-else-on-loop
-#TODO: Enable too-many-return-statements
 #TODO: Enable too-many-nested-blocks
-#TODO: Enable super-init-not-called
 
-disable=missing-docstring,too-few-public-methods,too-many-arguments,no-init,duplicate-code,invalid-name,suppressed-message,locally-disabled,protected-access,no-name-in-module,unused-argument,fixme,wrong-import-order,no-value-for-parameter,cyclic-import,redefined-outer-name,too-many-instance-attributes,broad-except,too-many-locals,too-many-lines,redefined-variable-type,next-method-called,import-error,useless-else-on-loop,too-many-return-statements,too-many-nested-blocks,super-init-not-called
+disable=missing-docstring,too-few-public-methods,no-init,duplicate-code,invalid-name,locally-disabled,protected-access,no-name-in-module,wrong-import-order,cyclic-import,too-many-instance-attributes,too-many-lines,redefined-variable-type,next-method-called,import-error,useless-else-on-loop,too-many-nested-blocks
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000000000000000000000000000000000000..700c61cceae6fc08bd5f9af7cff53569739c6e20
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,30 @@
+{
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "type": "node",
+            "request": "launch",
+            "name": "Mocha Tests",
+            "cwd": "${workspaceRoot}",
+            "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/mocha",
+            "windows": {
+                "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/mocha.cmd"
+            },
+            "runtimeArgs": [
+                "-u",
+                "tdd",
+                "--timeout",
+                "999999",
+                "--colors",
+                "${workspaceRoot}/src/node/test"
+            ],
+            "internalConsoleOptions": "openOnSessionStart"
+        },
+        {
+            "type": "node",
+            "request": "attach",
+            "name": "Attach to Process",
+            "port": 5858
+        }
+    ]
+}
diff --git a/BUILD b/BUILD
index ca0a1c56076b0496b8e3ffc3efd4c5032da565fb..62f0e1d2c5660e4b3cd39d944e46b5f0787cd0a8 100644
--- a/BUILD
+++ b/BUILD
@@ -35,13 +35,15 @@ exports_files(["LICENSE"])
 
 package(default_visibility = ["//visibility:public"])
 
-load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_proto_plugin")
+load("//bazel:grpc_build_system.bzl", "grpc_cc_library",
+     "grpc_proto_plugin", "grpc_cc_libraries")
 
-g_stands_for = "good"
+# This should be updated along with build.yaml
+g_stands_for = "gregarious"
 
-core_version = "2.0.0-dev"
+core_version = "3.0.0-dev"
 
-version = "1.1.0-dev"
+version = "1.4.0-dev"
 
 grpc_cc_library(
     name = "gpr",
@@ -52,28 +54,45 @@ grpc_cc_library(
     ],
 )
 
-grpc_cc_library(
-    name = "grpc",
+grpc_cc_libraries(
+    name_list = ["grpc", "grpc_unsecure",],
     srcs = [
         "src/core/lib/surface/init.c",
-        "src/core/plugin_registry/grpc_plugin_registry.c",
+    ],
+    additional_src_list = [
+        [
+            "src/core/plugin_registry/grpc_plugin_registry.c",
+        ],
+        [
+            "src/core/lib/surface/init_unsecure.c",
+            "src/core/plugin_registry/grpc_unsecure_plugin_registry.c",
+        ],
     ],
     language = "c",
     standalone = True,
     deps = [
         "census",
         "grpc_base",
-        "grpc_lb_policy_grpclb_secure",
         "grpc_lb_policy_pick_first",
         "grpc_lb_policy_round_robin",
         "grpc_load_reporting",
+        "grpc_max_age_filter",
         "grpc_resolver_dns_native",
         "grpc_resolver_sockaddr",
-        "grpc_secure",
         "grpc_transport_chttp2_client_insecure",
-        "grpc_transport_chttp2_client_secure",
         "grpc_transport_chttp2_server_insecure",
-        "grpc_transport_chttp2_server_secure",
+        "grpc_message_size_filter",
+        "grpc_deadline_filter",
+    ],
+    additional_dep_list = [
+        [
+            "grpc_secure",
+            "grpc_resolver_dns_ares",
+            "grpc_lb_policy_grpclb_secure",
+            "grpc_transport_chttp2_client_secure",
+            "grpc_transport_chttp2_server_secure",
+        ],
+        [],
     ],
 )
 
@@ -88,29 +107,7 @@ grpc_cc_library(
         "grpc_base",
         "grpc_transport_chttp2_client_secure",
         "grpc_transport_cronet_client_secure",
-    ],
-)
-
-grpc_cc_library(
-    name = "grpc_unsecure",
-    srcs = [
-        "src/core/lib/surface/init.c",
-        "src/core/lib/surface/init_unsecure.c",
-        "src/core/plugin_registry/grpc_unsecure_plugin_registry.c",
-    ],
-    language = "c",
-    standalone = True,
-    deps = [
-        "census",
-        "grpc_base",
-        "grpc_lb_policy_grpclb",
-        "grpc_lb_policy_pick_first",
-        "grpc_lb_policy_round_robin",
-        "grpc_load_reporting",
-        "grpc_resolver_dns_native",
-        "grpc_resolver_sockaddr",
-        "grpc_transport_chttp2_client_insecure",
-        "grpc_transport_chttp2_server_insecure",
+        "grpc_http_filters",
     ],
 )
 
@@ -154,13 +151,29 @@ grpc_cc_library(
     standalone = True,
     deps = [
         "gpr",
-        "grpc++_base",
+        "grpc++_base_unsecure",
         "grpc++_codegen_base",
         "grpc++_codegen_base_src",
         "grpc_unsecure",
     ],
 )
 
+grpc_cc_library(
+    name = "grpc++_error_details",
+    srcs = [
+        "src/cpp/util/error_details.cc",
+    ],
+    hdrs = [
+        "include/grpc++/support/error_details.h",
+    ],
+    language = "c++",
+    standalone = True,
+    deps = [
+        "grpc++",
+        "//src/proto/grpc/status:status_proto",
+    ],
+)
+
 grpc_cc_library(
     name = "grpc_plugin_support",
     srcs = [
@@ -185,11 +198,15 @@ grpc_cc_library(
         "src/compiler/objective_c_generator_helpers.h",
         "src/compiler/php_generator.h",
         "src/compiler/php_generator_helpers.h",
+        "src/compiler/protobuf_plugin.h",
         "src/compiler/python_generator.h",
+        "src/compiler/python_generator_helpers.h",
+        "src/compiler/python_private_generator.h",
         "src/compiler/ruby_generator.h",
         "src/compiler/ruby_generator_helpers-inl.h",
         "src/compiler/ruby_generator_map-inl.h",
         "src/compiler/ruby_generator_string-inl.h",
+        "src/compiler/schema_interface.h",
     ],
     external_deps = [
         "protobuf_clib",
@@ -309,6 +326,8 @@ grpc_cc_library(
         "src/core/lib/profiling/basic_timers.c",
         "src/core/lib/profiling/stap_timers.c",
         "src/core/lib/support/alloc.c",
+        "src/core/lib/support/arena.c",
+        "src/core/lib/support/atm.c",
         "src/core/lib/support/avl.c",
         "src/core/lib/support/backoff.c",
         "src/core/lib/support/cmdline.c",
@@ -353,9 +372,14 @@ grpc_cc_library(
     ],
     hdrs = [
         "src/core/lib/profiling/timers.h",
+        "src/core/lib/support/arena.h",
         "src/core/lib/support/backoff.h",
         "src/core/lib/support/block_annotate.h",
         "src/core/lib/support/env.h",
+        "src/core/lib/support/memory.h",
+        "src/core/lib/support/atomic.h",
+        "src/core/lib/support/atomic_with_atm.h",
+        "src/core/lib/support/atomic_with_std.h",
         "src/core/lib/support/mpscq.h",
         "src/core/lib/support/murmur_hash.h",
         "src/core/lib/support/spinlock.h",
@@ -411,7 +435,6 @@ grpc_cc_library(
         "include/grpc/impl/codegen/gpr_slice.h",
         "include/grpc/impl/codegen/gpr_types.h",
         "include/grpc/impl/codegen/port_platform.h",
-        "include/grpc/impl/codegen/slice.h",
         "include/grpc/impl/codegen/sync.h",
         "include/grpc/impl/codegen/sync_generic.h",
         "include/grpc/impl/codegen/sync_posix.h",
@@ -425,15 +448,10 @@ grpc_cc_library(
         "src/core/lib/channel/channel_args.c",
         "src/core/lib/channel/channel_stack.c",
         "src/core/lib/channel/channel_stack_builder.c",
-        "src/core/lib/channel/compress_filter.c",
         "src/core/lib/channel/connected_channel.c",
-        "src/core/lib/channel/deadline_filter.c",
         "src/core/lib/channel/handshaker.c",
         "src/core/lib/channel/handshaker_factory.c",
         "src/core/lib/channel/handshaker_registry.c",
-        "src/core/lib/channel/http_client_filter.c",
-        "src/core/lib/channel/http_server_filter.c",
-        "src/core/lib/channel/message_size_filter.c",
         "src/core/lib/compression/compression.c",
         "src/core/lib/compression/message_compress.c",
         "src/core/lib/debug/trace.c",
@@ -458,6 +476,7 @@ grpc_cc_library(
         "src/core/lib/iomgr/iomgr_uv.c",
         "src/core/lib/iomgr/iomgr_windows.c",
         "src/core/lib/iomgr/load_file.c",
+        "src/core/lib/iomgr/lockfree_event.c",
         "src/core/lib/iomgr/network_status_tracker.c",
         "src/core/lib/iomgr/polling_entity.c",
         "src/core/lib/iomgr/pollset_set_uv.c",
@@ -469,6 +488,7 @@ grpc_cc_library(
         "src/core/lib/iomgr/resolve_address_windows.c",
         "src/core/lib/iomgr/resource_quota.c",
         "src/core/lib/iomgr/sockaddr_utils.c",
+        "src/core/lib/iomgr/socket_factory_posix.c",
         "src/core/lib/iomgr/socket_mutator.c",
         "src/core/lib/iomgr/socket_utils_common_posix.c",
         "src/core/lib/iomgr/socket_utils_linux.c",
@@ -481,6 +501,9 @@ grpc_cc_library(
         "src/core/lib/iomgr/tcp_client_windows.c",
         "src/core/lib/iomgr/tcp_posix.c",
         "src/core/lib/iomgr/tcp_server_posix.c",
+        "src/core/lib/iomgr/tcp_server_utils_posix_common.c",
+        "src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c",
+        "src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c",
         "src/core/lib/iomgr/tcp_server_uv.c",
         "src/core/lib/iomgr/tcp_server_windows.c",
         "src/core/lib/iomgr/tcp_uv.c",
@@ -503,6 +526,7 @@ grpc_cc_library(
         "src/core/lib/json/json_reader.c",
         "src/core/lib/json/json_string.c",
         "src/core/lib/json/json_writer.c",
+        "src/core/lib/slice/b64.c",
         "src/core/lib/slice/percent_encoding.c",
         "src/core/lib/slice/slice.c",
         "src/core/lib/slice/slice_buffer.c",
@@ -521,8 +545,9 @@ grpc_cc_library(
         "src/core/lib/surface/channel_ping.c",
         "src/core/lib/surface/channel_stack_type.c",
         "src/core/lib/surface/completion_queue.c",
+        "src/core/lib/surface/completion_queue_factory.c",
         "src/core/lib/surface/event_string.c",
-        "src/core/lib/surface/lame_client.c",
+        "src/core/lib/surface/lame_client.cc",
         "src/core/lib/surface/metadata_array.c",
         "src/core/lib/surface/server.c",
         "src/core/lib/surface/validate_metadata.c",
@@ -545,16 +570,11 @@ grpc_cc_library(
         "src/core/lib/channel/channel_args.h",
         "src/core/lib/channel/channel_stack.h",
         "src/core/lib/channel/channel_stack_builder.h",
-        "src/core/lib/channel/compress_filter.h",
         "src/core/lib/channel/connected_channel.h",
         "src/core/lib/channel/context.h",
-        "src/core/lib/channel/deadline_filter.h",
         "src/core/lib/channel/handshaker.h",
         "src/core/lib/channel/handshaker_factory.h",
         "src/core/lib/channel/handshaker_registry.h",
-        "src/core/lib/channel/http_client_filter.h",
-        "src/core/lib/channel/http_server_filter.h",
-        "src/core/lib/channel/message_size_filter.h",
         "src/core/lib/compression/algorithm_metadata.h",
         "src/core/lib/compression/message_compress.h",
         "src/core/lib/debug/trace.h",
@@ -577,6 +597,7 @@ grpc_cc_library(
         "src/core/lib/iomgr/iomgr_internal.h",
         "src/core/lib/iomgr/iomgr_posix.h",
         "src/core/lib/iomgr/load_file.h",
+        "src/core/lib/iomgr/lockfree_event.h",
         "src/core/lib/iomgr/network_status_tracker.h",
         "src/core/lib/iomgr/polling_entity.h",
         "src/core/lib/iomgr/pollset.h",
@@ -591,6 +612,7 @@ grpc_cc_library(
         "src/core/lib/iomgr/sockaddr_posix.h",
         "src/core/lib/iomgr/sockaddr_utils.h",
         "src/core/lib/iomgr/sockaddr_windows.h",
+        "src/core/lib/iomgr/socket_factory_posix.h",
         "src/core/lib/iomgr/socket_mutator.h",
         "src/core/lib/iomgr/socket_utils.h",
         "src/core/lib/iomgr/socket_utils_posix.h",
@@ -599,6 +621,7 @@ grpc_cc_library(
         "src/core/lib/iomgr/tcp_client_posix.h",
         "src/core/lib/iomgr/tcp_posix.h",
         "src/core/lib/iomgr/tcp_server.h",
+        "src/core/lib/iomgr/tcp_server_utils_posix.h",
         "src/core/lib/iomgr/tcp_uv.h",
         "src/core/lib/iomgr/tcp_windows.h",
         "src/core/lib/iomgr/time_averaged_stats.h",
@@ -618,6 +641,7 @@ grpc_cc_library(
         "src/core/lib/json/json_common.h",
         "src/core/lib/json/json_reader.h",
         "src/core/lib/json/json_writer.h",
+        "src/core/lib/slice/b64.h",
         "src/core/lib/slice/percent_encoding.h",
         "src/core/lib/slice/slice_hash_table.h",
         "src/core/lib/slice/slice_internal.h",
@@ -629,6 +653,7 @@ grpc_cc_library(
         "src/core/lib/surface/channel_init.h",
         "src/core/lib/surface/channel_stack_type.h",
         "src/core/lib/surface/completion_queue.h",
+        "src/core/lib/surface/completion_queue_factory.h",
         "src/core/lib/surface/event_string.h",
         "src/core/lib/surface/init.h",
         "src/core/lib/surface/lame_client.h",
@@ -674,47 +699,108 @@ grpc_cc_library(
 grpc_cc_library(
     name = "grpc_client_channel",
     srcs = [
-        "src/core/ext/client_channel/channel_connectivity.c",
-        "src/core/ext/client_channel/client_channel.c",
-        "src/core/ext/client_channel/client_channel_factory.c",
-        "src/core/ext/client_channel/client_channel_plugin.c",
-        "src/core/ext/client_channel/connector.c",
-        "src/core/ext/client_channel/default_initial_connect_string.c",
-        "src/core/ext/client_channel/http_connect_handshaker.c",
-        "src/core/ext/client_channel/http_proxy.c",
-        "src/core/ext/client_channel/initial_connect_string.c",
-        "src/core/ext/client_channel/lb_policy.c",
-        "src/core/ext/client_channel/lb_policy_factory.c",
-        "src/core/ext/client_channel/lb_policy_registry.c",
-        "src/core/ext/client_channel/parse_address.c",
-        "src/core/ext/client_channel/proxy_mapper.c",
-        "src/core/ext/client_channel/proxy_mapper_registry.c",
-        "src/core/ext/client_channel/resolver.c",
-        "src/core/ext/client_channel/resolver_factory.c",
-        "src/core/ext/client_channel/resolver_registry.c",
-        "src/core/ext/client_channel/subchannel.c",
-        "src/core/ext/client_channel/subchannel_index.c",
-        "src/core/ext/client_channel/uri_parser.c",
+        "src/core/ext/filters/client_channel/channel_connectivity.c",
+        "src/core/ext/filters/client_channel/client_channel.c",
+        "src/core/ext/filters/client_channel/client_channel_factory.c",
+        "src/core/ext/filters/client_channel/client_channel_plugin.c",
+        "src/core/ext/filters/client_channel/connector.c",
+        "src/core/ext/filters/client_channel/http_connect_handshaker.c",
+        "src/core/ext/filters/client_channel/http_proxy.c",
+        "src/core/ext/filters/client_channel/lb_policy.c",
+        "src/core/ext/filters/client_channel/lb_policy_factory.c",
+        "src/core/ext/filters/client_channel/lb_policy_registry.c",
+        "src/core/ext/filters/client_channel/parse_address.c",
+        "src/core/ext/filters/client_channel/proxy_mapper.c",
+        "src/core/ext/filters/client_channel/proxy_mapper_registry.c",
+        "src/core/ext/filters/client_channel/resolver.c",
+        "src/core/ext/filters/client_channel/resolver_factory.c",
+        "src/core/ext/filters/client_channel/resolver_registry.c",
+        "src/core/ext/filters/client_channel/retry_throttle.c",
+        "src/core/ext/filters/client_channel/subchannel.c",
+        "src/core/ext/filters/client_channel/subchannel_index.c",
+        "src/core/ext/filters/client_channel/uri_parser.c",
+    ],
+    hdrs = [
+        "src/core/ext/filters/client_channel/client_channel.h",
+        "src/core/ext/filters/client_channel/client_channel_factory.h",
+        "src/core/ext/filters/client_channel/connector.h",
+        "src/core/ext/filters/client_channel/http_connect_handshaker.h",
+        "src/core/ext/filters/client_channel/http_proxy.h",
+        "src/core/ext/filters/client_channel/lb_policy.h",
+        "src/core/ext/filters/client_channel/lb_policy_factory.h",
+        "src/core/ext/filters/client_channel/lb_policy_registry.h",
+        "src/core/ext/filters/client_channel/parse_address.h",
+        "src/core/ext/filters/client_channel/proxy_mapper.h",
+        "src/core/ext/filters/client_channel/proxy_mapper_registry.h",
+        "src/core/ext/filters/client_channel/resolver.h",
+        "src/core/ext/filters/client_channel/resolver_factory.h",
+        "src/core/ext/filters/client_channel/resolver_registry.h",
+        "src/core/ext/filters/client_channel/retry_throttle.h",
+        "src/core/ext/filters/client_channel/subchannel.h",
+        "src/core/ext/filters/client_channel/subchannel_index.h",
+        "src/core/ext/filters/client_channel/uri_parser.h",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+        "grpc_deadline_filter",
+    ],
+)
+
+grpc_cc_library(
+    name = "grpc_max_age_filter",
+    srcs = [
+        "src/core/ext/filters/max_age/max_age_filter.c",
+    ],
+    hdrs = [
+        "src/core/ext/filters/max_age/max_age_filter.h",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+    ],
+)
+
+grpc_cc_library(
+    name = "grpc_deadline_filter",
+    srcs = [
+        "src/core/ext/filters/deadline/deadline_filter.c",
+    ],
+    hdrs = [
+        "src/core/ext/filters/deadline/deadline_filter.h",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+    ],
+)
+
+grpc_cc_library(
+    name = "grpc_message_size_filter",
+    srcs = [
+        "src/core/ext/filters/message_size/message_size_filter.c",
     ],
     hdrs = [
-        "src/core/ext/client_channel/client_channel.h",
-        "src/core/ext/client_channel/client_channel_factory.h",
-        "src/core/ext/client_channel/connector.h",
-        "src/core/ext/client_channel/http_connect_handshaker.h",
-        "src/core/ext/client_channel/http_proxy.h",
-        "src/core/ext/client_channel/initial_connect_string.h",
-        "src/core/ext/client_channel/lb_policy.h",
-        "src/core/ext/client_channel/lb_policy_factory.h",
-        "src/core/ext/client_channel/lb_policy_registry.h",
-        "src/core/ext/client_channel/parse_address.h",
-        "src/core/ext/client_channel/proxy_mapper.h",
-        "src/core/ext/client_channel/proxy_mapper_registry.h",
-        "src/core/ext/client_channel/resolver.h",
-        "src/core/ext/client_channel/resolver_factory.h",
-        "src/core/ext/client_channel/resolver_registry.h",
-        "src/core/ext/client_channel/subchannel.h",
-        "src/core/ext/client_channel/subchannel_index.h",
-        "src/core/ext/client_channel/uri_parser.h",
+        "src/core/ext/filters/message_size/message_size_filter.h",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+    ],
+)
+
+grpc_cc_library(
+    name = "grpc_http_filters",
+    hdrs = [
+        "src/core/ext/filters/http/message_compress/message_compress_filter.h",
+        "src/core/ext/filters/http/client/http_client_filter.h",
+        "src/core/ext/filters/http/server/http_server_filter.h",
+    ],
+    srcs = [
+        "src/core/ext/filters/http/message_compress/message_compress_filter.c",
+        "src/core/ext/filters/http/client/http_client_filter.c",
+        "src/core/ext/filters/http/server/http_server_filter.c",
+        "src/core/ext/filters/http/http_filters_plugin.c"
     ],
     language = "c",
     deps = [
@@ -733,6 +819,7 @@ grpc_cc_library(
         "include/grpc/impl/codegen/grpc_types.h",
         "include/grpc/impl/codegen/propagation_bits.h",
         "include/grpc/impl/codegen/status.h",
+        "include/grpc/impl/codegen/slice.h",
     ],
     deps = [
         "gpr_codegen",
@@ -742,16 +829,20 @@ grpc_cc_library(
 grpc_cc_library(
     name = "grpc_lb_policy_grpclb",
     srcs = [
-        "src/core/ext/lb_policy/grpclb/grpclb.c",
-        "src/core/ext/lb_policy/grpclb/grpclb_channel.c",
-        "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
-        "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
     ],
     hdrs = [
-        "src/core/ext/lb_policy/grpclb/grpclb.h",
-        "src/core/ext/lb_policy/grpclb/grpclb_channel.h",
-        "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
-        "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
     ],
     external_deps = [
         "nanopb",
@@ -766,16 +857,20 @@ grpc_cc_library(
 grpc_cc_library(
     name = "grpc_lb_policy_grpclb_secure",
     srcs = [
-        "src/core/ext/lb_policy/grpclb/grpclb.c",
-        "src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c",
-        "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
-        "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
     ],
     hdrs = [
-        "src/core/ext/lb_policy/grpclb/grpclb.h",
-        "src/core/ext/lb_policy/grpclb/grpclb_channel.h",
-        "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
-        "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
     ],
     external_deps = [
         "nanopb",
@@ -791,7 +886,7 @@ grpc_cc_library(
 grpc_cc_library(
     name = "grpc_lb_policy_pick_first",
     srcs = [
-        "src/core/ext/lb_policy/pick_first/pick_first.c",
+        "src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c",
     ],
     language = "c",
     deps = [
@@ -803,7 +898,7 @@ grpc_cc_library(
 grpc_cc_library(
     name = "grpc_lb_policy_round_robin",
     srcs = [
-        "src/core/ext/lb_policy/round_robin/round_robin.c",
+        "src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c",
     ],
     language = "c",
     deps = [
@@ -815,12 +910,12 @@ grpc_cc_library(
 grpc_cc_library(
     name = "grpc_load_reporting",
     srcs = [
-        "src/core/ext/load_reporting/load_reporting.c",
-        "src/core/ext/load_reporting/load_reporting_filter.c",
+        "src/core/ext/filters/load_reporting/load_reporting.c",
+        "src/core/ext/filters/load_reporting/load_reporting_filter.c",
     ],
     hdrs = [
-        "src/core/ext/load_reporting/load_reporting.h",
-        "src/core/ext/load_reporting/load_reporting_filter.h",
+        "src/core/ext/filters/load_reporting/load_reporting.h",
+        "src/core/ext/filters/load_reporting/load_reporting_filter.h",
     ],
     language = "c",
     deps = [
@@ -831,7 +926,28 @@ grpc_cc_library(
 grpc_cc_library(
     name = "grpc_resolver_dns_native",
     srcs = [
-        "src/core/ext/resolver/dns/native/dns_resolver.c",
+        "src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+        "grpc_client_channel",
+    ],
+)
+
+grpc_cc_library(
+    name = "grpc_resolver_dns_ares",
+    srcs = [
+        "src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c",
+        "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c",
+        "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c",
+    ],
+    hdrs = [
+        "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h",
+        "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h",
+    ],
+    external_deps = [
+        "cares",
     ],
     language = "c",
     deps = [
@@ -843,7 +959,7 @@ grpc_cc_library(
 grpc_cc_library(
     name = "grpc_resolver_sockaddr",
     srcs = [
-        "src/core/ext/resolver/sockaddr/sockaddr_resolver.c",
+        "src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c",
     ],
     language = "c",
     deps = [
@@ -877,7 +993,6 @@ grpc_cc_library(
         "src/core/lib/security/transport/security_handshaker.c",
         "src/core/lib/security/transport/server_auth_filter.c",
         "src/core/lib/security/transport/tsi_error.c",
-        "src/core/lib/security/util/b64.c",
         "src/core/lib/security/util/json_util.c",
         "src/core/lib/surface/init_secure.c",
     ],
@@ -900,7 +1015,6 @@ grpc_cc_library(
         "src/core/lib/security/transport/security_connector.h",
         "src/core/lib/security/transport/security_handshaker.h",
         "src/core/lib/security/transport/tsi_error.h",
-        "src/core/lib/security/util/b64.h",
         "src/core/lib/security/util/json_util.h",
     ],
     language = "c",
@@ -930,6 +1044,7 @@ grpc_cc_library(
         "src/core/ext/transport/chttp2/transport/hpack_encoder.c",
         "src/core/ext/transport/chttp2/transport/hpack_parser.c",
         "src/core/ext/transport/chttp2/transport/hpack_table.c",
+        "src/core/ext/transport/chttp2/transport/http2_settings.c",
         "src/core/ext/transport/chttp2/transport/huffsyms.c",
         "src/core/ext/transport/chttp2/transport/incoming_metadata.c",
         "src/core/ext/transport/chttp2/transport/parsing.c",
@@ -952,6 +1067,7 @@ grpc_cc_library(
         "src/core/ext/transport/chttp2/transport/hpack_encoder.h",
         "src/core/ext/transport/chttp2/transport/hpack_parser.h",
         "src/core/ext/transport/chttp2/transport/hpack_table.h",
+        "src/core/ext/transport/chttp2/transport/http2_settings.h",
         "src/core/ext/transport/chttp2/transport/huffsyms.h",
         "src/core/ext/transport/chttp2/transport/incoming_metadata.h",
         "src/core/ext/transport/chttp2/transport/internal.h",
@@ -962,6 +1078,7 @@ grpc_cc_library(
     deps = [
         "grpc_base",
         "grpc_transport_chttp2_alpn",
+        "grpc_http_filters",
     ],
 )
 
@@ -1094,16 +1211,18 @@ grpc_cc_library(
 grpc_cc_library(
     name = "tsi",
     srcs = [
-        "src/core/lib/tsi/fake_transport_security.c",
-        "src/core/lib/tsi/ssl_transport_security.c",
-        "src/core/lib/tsi/transport_security.c",
+        "src/core/tsi/fake_transport_security.c",
+        "src/core/tsi/ssl_transport_security.c",
+        "src/core/tsi/transport_security.c",
+        "src/core/tsi/transport_security_adapter.c",
     ],
     hdrs = [
-        "src/core/lib/tsi/fake_transport_security.h",
-        "src/core/lib/tsi/ssl_transport_security.h",
-        "src/core/lib/tsi/ssl_types.h",
-        "src/core/lib/tsi/transport_security.h",
-        "src/core/lib/tsi/transport_security_interface.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_adapter.h",
+        "src/core/tsi/transport_security_interface.h",
     ],
     external_deps = [
         "libssl",
@@ -1114,8 +1233,12 @@ grpc_cc_library(
     ],
 )
 
-grpc_cc_library(
-    name = "grpc++_base",
+grpc_cc_libraries(
+    name_list = ["grpc++_base", "grpc++_base_unsecure"],
+    additional_dep_list = [
+        ["grpc", ],
+        ["grpc_unsecure", ],
+    ],
     srcs = [
         "src/cpp/client/channel_cc.cc",
         "src/cpp/client/client_context.cc",
@@ -1132,6 +1255,7 @@ grpc_cc_library(
         "src/cpp/common/rpc_method.cc",
         "src/cpp/common/version_cc.cc",
         "src/cpp/server/async_generic_service.cc",
+        "src/cpp/server/channel_argument_option.cc",
         "src/cpp/server/create_default_thread_pool.cc",
         "src/cpp/server/dynamic_thread_pool.cc",
         "src/cpp/server/health/default_health_check_service.cc",
@@ -1149,7 +1273,7 @@ grpc_cc_library(
         "src/cpp/util/status.cc",
         "src/cpp/util/string_ref.cc",
         "src/cpp/util/time_cc.cc",
-    ],
+        ],
     hdrs = [
         "src/cpp/client/create_channel_internal.h",
         "src/cpp/common/channel_filter.h",
@@ -1158,7 +1282,7 @@ grpc_cc_library(
         "src/cpp/server/health/health.pb.h",
         "src/cpp/server/thread_pool_interface.h",
         "src/cpp/thread_manager/thread_manager.h",
-    ],
+        ],
     language = "c++",
     public_hdrs = [
         "include/grpc++/alarm.h",
@@ -1173,6 +1297,7 @@ grpc_cc_library(
         "include/grpc++/grpc++.h",
         "include/grpc++/health_check_service_interface.h",
         "include/grpc++/impl/call.h",
+        "include/grpc++/impl/channel_argument_option.h",
         "include/grpc++/impl/client_unary_call.h",
         "include/grpc++/impl/codegen/core_codegen.h",
         "include/grpc++/impl/grpc_library.h",
@@ -1207,9 +1332,8 @@ grpc_cc_library(
         "include/grpc++/support/stub_options.h",
         "include/grpc++/support/sync_stream.h",
         "include/grpc++/support/time.h",
-    ],
+        ],
     deps = [
-        "grpc",
         "grpc++_codegen_base",
     ],
 )
@@ -1243,7 +1367,6 @@ grpc_cc_library(
         "include/grpc++/impl/codegen/slice.h",
         "include/grpc++/impl/codegen/status.h",
         "include/grpc++/impl/codegen/status_code_enum.h",
-        "include/grpc++/impl/codegen/status_helper.h",
         "include/grpc++/impl/codegen/string_ref.h",
         "include/grpc++/impl/codegen/stub_options.h",
         "include/grpc++/impl/codegen/sync_stream.h",
@@ -1288,18 +1411,6 @@ grpc_cc_library(
     ],
 )
 
-grpc_cc_library(
-    name = "thrift_util",
-    language = "c++",
-    public_hdrs = [
-        "include/grpc++/impl/codegen/thrift_serializer.h",
-        "include/grpc++/impl/codegen/thrift_utils.h",
-    ],
-    deps = [
-        "grpc++_codegen_base",
-    ],
-)
-
 grpc_cc_library(
     name = "grpc++_reflection",
     srcs = [
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5694bd195e9bc10a618df63b99f17baf7184a396..f6c5f9e56d5c1b9cc71e5d011cc4723d96290636 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,9 +5,6 @@
 # This file can be regenerated from the template by running
 # tools/buildgen/generate_projects.sh
 #
-# Additionally, this is currently very experimental, and unsupported.
-# Further work will happen on that file.
-#
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -42,7 +39,7 @@
 cmake_minimum_required(VERSION 2.8)
 
 set(PACKAGE_NAME      "grpc")
-set(PACKAGE_VERSION   "1.2.0-dev")
+set(PACKAGE_VERSION   "1.4.0-dev")
 set(PACKAGE_STRING    "${PACKAGE_NAME} ${PACKAGE_VERSION}")
 set(PACKAGE_TARNAME   "${PACKAGE_NAME}-${PACKAGE_VERSION}")
 set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
@@ -60,6 +57,9 @@ endif()
 set(gRPC_ZLIB_PROVIDER "module" CACHE STRING "Provider of zlib library")
 set_property(CACHE gRPC_ZLIB_PROVIDER PROPERTY STRINGS "module" "package")
 
+set(gRPC_CARES_PROVIDER "module" CACHE STRING "Provider of c-ares library")
+set_property(CACHE gRPC_CARES_PROVIDER PROPERTY STRINGS "module" "package")
+
 set(gRPC_SSL_PROVIDER "module" CACHE STRING "Provider of ssl library")
 set_property(CACHE gRPC_SSL_PROVIDER PROPERTY STRINGS "module" "package")
 
@@ -126,6 +126,37 @@ elseif("${gRPC_ZLIB_PROVIDER}" STREQUAL "package")
   set(_gRPC_FIND_ZLIB "if(NOT ZLIB_FOUND)\n  find_package(ZLIB)\nendif()")
 endif()
 
+if("${gRPC_CARES_PROVIDER}" STREQUAL "module")
+  if(NOT CARES_ROOT_DIR)
+    set(CARES_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/c-ares)
+  endif()
+  string(TOLOWER ${CMAKE_SYSTEM_NAME} CARES_SYSTEM_NAME)
+  set(CARES_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/cares/cares")
+  set(CARES_BUILD_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/cares")
+  set(CARES_PLATFORM_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/cares/config_${CARES_SYSTEM_NAME}")
+  if(EXISTS "${CARES_ROOT_DIR}/CMakeLists.txt")
+    if("${CARES_SYSTEM_NAME}" MATCHES "windows")
+      add_definitions(-DCARES_STATICLIB=1)
+      add_definitions(-DWIN32_LEAN_AND_MEAN=1)
+    else()
+      add_definitions(-DHAVE_CONFIG_H=1)
+      add_definitions(-D_GNU_SOURCE=1)
+    endif()
+    add_subdirectory(src/c-ares third_party/cares)
+    if(TARGET cares)
+        set(_gRPC_CARES_LIBRARIES cares)
+    endif()
+  else()
+    message(WARNING "gRPC_CARES_PROVIDER is \"module\" but CARES_ROOT_DIR is wrong")
+  endif()
+elseif("${gRPC_CARES_PROVIDER}" STREQUAL "package")
+  find_package(CARES)
+  if(TARGET CARES::CARES)
+    set(_gRPC_CARES_LIBRARIES CARES::CARES)
+  endif()
+  set(_gRPC_FIND_CARES "if(NOT CARES_FOUND)\n  find_package(CARES)\nendif()")
+endif()
+
 if("${gRPC_PROTOBUF_PROVIDER}" STREQUAL "module")
   # Building the protobuf tests require gmock what is not part of a standard protobuf checkout.
   # Disable them unless they are explicitly requested from the cmake command line (when we assume
@@ -136,6 +167,7 @@ if("${gRPC_PROTOBUF_PROVIDER}" STREQUAL "module")
   if(NOT PROTOBUF_ROOT_DIR)
     set(PROTOBUF_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/protobuf)
   endif()
+  set(PROTOBUF_WELLKNOWN_IMPORT_DIR ${PROTOBUF_ROOT_DIR}/src)
   if(EXISTS "${PROTOBUF_ROOT_DIR}/cmake/CMakeLists.txt")
     set(protobuf_MSVC_STATIC_RUNTIME OFF CACHE BOOL "Link static runtime libraries")
     add_subdirectory(${PROTOBUF_ROOT_DIR}/cmake third_party/protobuf)
@@ -168,6 +200,7 @@ elseif("${gRPC_PROTOBUF_PROVIDER}" STREQUAL "package")
     find_package(Protobuf MODULE)
     set(_gRPC_FIND_PROTOBUF "if(NOT Protobuf_FOUND)\n  find_package(Protobuf)\nendif()")
   endif()
+  set(PROTOBUF_WELLKNOWN_IMPORT_DIR /usr/local/include)
 endif()
 
 if("${gRPC_SSL_PROVIDER}" STREQUAL "module")
@@ -236,8 +269,10 @@ if(NOT MSVC)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
 endif()
 
-if(UNIX)
-  set(_gRPC_ALLTARGETS_LIBRARIES dl rt m pthread)
+if(_gRPC_PLATFORM_MAC)
+  set(_gRPC_ALLTARGETS_LIBRARIES ${CMAKE_DL_LIBS} m pthread)
+elseif(UNIX)
+  set(_gRPC_ALLTARGETS_LIBRARIES ${CMAKE_DL_LIBS} rt m pthread)
 endif()
 
 if(WIN32 AND MSVC)
@@ -270,31 +305,32 @@ function(protobuf_generate_grpc_cpp)
     return()
   endif()
 
-  set(_protobuf_include_path -I .)
+  set(_protobuf_include_path -I . -I ${PROTOBUF_WELLKNOWN_IMPORT_DIR})
   foreach(FIL ${ARGN})
     get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
     get_filename_component(FIL_WE ${FIL} NAME_WE)
-    file(RELATIVE_PATH REL_FIL ${CMAKE_SOURCE_DIR} ${ABS_FIL})
+    file(RELATIVE_PATH REL_FIL ${CMAKE_CURRENT_SOURCE_DIR} ${ABS_FIL})
     get_filename_component(REL_DIR ${REL_FIL} DIRECTORY)
     set(RELFIL_WE "${REL_DIR}/${FIL_WE}")
-    
+
     add_custom_command(
       OUTPUT "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc"
              "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h"
+             "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}_mock.grpc.pb.h"
              "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc"
              "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h"
       COMMAND ${_gRPC_PROTOBUF_PROTOC}
-      ARGS --grpc_out=${_gRPC_PROTO_GENS_DIR}
+      ARGS --grpc_out=generate_mock_code=true:${_gRPC_PROTO_GENS_DIR}
            --cpp_out=${_gRPC_PROTO_GENS_DIR}
            --plugin=protoc-gen-grpc=$<TARGET_FILE:grpc_cpp_plugin>
            ${_protobuf_include_path}
            ${REL_FIL}
       DEPENDS ${ABS_FIL} ${_gRPC_PROTOBUF_PROTOC} grpc_cpp_plugin
-      WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
       COMMENT "Running gRPC C++ protocol buffer compiler on ${FIL}"
       VERBATIM)
-      
-      set_source_files_properties("${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h" PROPERTIES GENERATED TRUE)
+
+      set_source_files_properties("${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h"  "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}_mock.grpc.pb.h" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h" PROPERTIES GENERATED TRUE)
   endforeach()
 endfunction()
 
@@ -332,6 +368,7 @@ add_dependencies(buildtests_c alarm_test)
 add_dependencies(buildtests_c algorithm_test)
 add_dependencies(buildtests_c alloc_test)
 add_dependencies(buildtests_c alpn_test)
+add_dependencies(buildtests_c arena_test)
 add_dependencies(buildtests_c bad_server_response_test)
 add_dependencies(buildtests_c bdp_estimator_test)
 add_dependencies(buildtests_c bin_decoder_test)
@@ -353,9 +390,11 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_c dualstack_socket_test)
 endif()
 add_dependencies(buildtests_c endpoint_pair_test)
+add_dependencies(buildtests_c error_test)
 if(_gRPC_PLATFORM_LINUX)
 add_dependencies(buildtests_c ev_epoll_linux_test)
 endif()
+add_dependencies(buildtests_c fake_resolver_test)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_c fd_conservation_posix_test)
 endif()
@@ -436,10 +475,12 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_c memory_profile_test)
 endif()
 add_dependencies(buildtests_c message_compress_test)
+add_dependencies(buildtests_c minimal_stack_is_minimal_test)
 add_dependencies(buildtests_c mlog_test)
 add_dependencies(buildtests_c multiple_server_queues_test)
 add_dependencies(buildtests_c murmur_hash_test)
 add_dependencies(buildtests_c no_server_test)
+add_dependencies(buildtests_c parse_address_test)
 add_dependencies(buildtests_c percent_encoding_test)
 if(_gRPC_PLATFORM_LINUX)
 add_dependencies(buildtests_c pollset_set_test)
@@ -454,8 +495,8 @@ add_dependencies(buildtests_c secure_endpoint_test)
 add_dependencies(buildtests_c sequential_connectivity_test)
 add_dependencies(buildtests_c server_chttp2_test)
 add_dependencies(buildtests_c server_test)
-add_dependencies(buildtests_c set_initial_connect_string_test)
 add_dependencies(buildtests_c slice_buffer_test)
+add_dependencies(buildtests_c slice_hash_table_test)
 add_dependencies(buildtests_c slice_string_helpers_test)
 add_dependencies(buildtests_c slice_test)
 add_dependencies(buildtests_c sockaddr_resolver_test)
@@ -464,6 +505,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_c socket_utils_test)
 endif()
 add_dependencies(buildtests_c status_conversion_test)
+add_dependencies(buildtests_c stream_owned_slice_test)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_c tcp_client_posix_test)
 endif()
@@ -571,26 +613,47 @@ add_dependencies(buildtests_cxx alarm_cpp_test)
 add_dependencies(buildtests_cxx async_end2end_test)
 add_dependencies(buildtests_cxx auth_property_iterator_test)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+add_dependencies(buildtests_cxx bm_arena)
+endif()
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_cxx bm_call_create)
 endif()
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_cxx bm_chttp2_hpack)
 endif()
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+add_dependencies(buildtests_cxx bm_chttp2_transport)
+endif()
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_cxx bm_closure)
 endif()
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_cxx bm_cq)
 endif()
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+add_dependencies(buildtests_cxx bm_cq_multiple_threads)
+endif()
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_cxx bm_error)
 endif()
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
-add_dependencies(buildtests_cxx bm_fullstack)
+add_dependencies(buildtests_cxx bm_fullstack_streaming_ping_pong)
+endif()
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+add_dependencies(buildtests_cxx bm_fullstack_streaming_pump)
+endif()
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+add_dependencies(buildtests_cxx bm_fullstack_trickle)
+endif()
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+add_dependencies(buildtests_cxx bm_fullstack_unary_ping_pong)
 endif()
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_cxx bm_metadata)
 endif()
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+add_dependencies(buildtests_cxx bm_pollset)
+endif()
 add_dependencies(buildtests_cxx channel_arguments_test)
 add_dependencies(buildtests_cxx channel_filter_test)
 add_dependencies(buildtests_cxx cli_call_test)
@@ -606,12 +669,14 @@ add_dependencies(buildtests_cxx cxx_slice_test)
 add_dependencies(buildtests_cxx cxx_string_ref_test)
 add_dependencies(buildtests_cxx cxx_time_test)
 add_dependencies(buildtests_cxx end2end_test)
+add_dependencies(buildtests_cxx error_details_test)
 add_dependencies(buildtests_cxx filter_end2end_test)
 add_dependencies(buildtests_cxx generic_end2end_test)
 add_dependencies(buildtests_cxx golden_file_test)
 add_dependencies(buildtests_cxx grpc_cli)
 add_dependencies(buildtests_cxx grpc_tool_test)
 add_dependencies(buildtests_cxx grpclb_api_test)
+add_dependencies(buildtests_cxx grpclb_end2end_test)
 add_dependencies(buildtests_cxx grpclb_test)
 add_dependencies(buildtests_cxx health_service_end2end_test)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@@ -630,6 +695,7 @@ endif()
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_cxx json_run_localhost)
 endif()
+add_dependencies(buildtests_cxx memory_test)
 add_dependencies(buildtests_cxx metrics_client)
 add_dependencies(buildtests_cxx mock_test)
 add_dependencies(buildtests_cxx noop-benchmark)
@@ -651,6 +717,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_cxx secure_sync_unary_ping_pong_test)
 endif()
 add_dependencies(buildtests_cxx server_builder_plugin_test)
+add_dependencies(buildtests_cxx server_builder_test)
 add_dependencies(buildtests_cxx server_context_test_spouse_test)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_cxx server_crash_test)
@@ -677,6 +744,8 @@ add_library(gpr
   src/core/lib/profiling/basic_timers.c
   src/core/lib/profiling/stap_timers.c
   src/core/lib/support/alloc.c
+  src/core/lib/support/arena.c
+  src/core/lib/support/atm.c
   src/core/lib/support/avl.c
   src/core/lib/support/backoff.c
   src/core/lib/support/cmdline.c
@@ -740,6 +809,10 @@ target_include_directories(gpr
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -781,7 +854,6 @@ foreach(_hdr
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
-  include/grpc/impl/codegen/slice.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_generic.h
   include/grpc/impl/codegen/sync_posix.h
@@ -829,6 +901,10 @@ target_include_directories(gpr_test_util
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -845,15 +921,10 @@ add_library(grpc
   src/core/lib/channel/channel_args.c
   src/core/lib/channel/channel_stack.c
   src/core/lib/channel/channel_stack_builder.c
-  src/core/lib/channel/compress_filter.c
   src/core/lib/channel/connected_channel.c
-  src/core/lib/channel/deadline_filter.c
   src/core/lib/channel/handshaker.c
   src/core/lib/channel/handshaker_factory.c
   src/core/lib/channel/handshaker_registry.c
-  src/core/lib/channel/http_client_filter.c
-  src/core/lib/channel/http_server_filter.c
-  src/core/lib/channel/message_size_filter.c
   src/core/lib/compression/compression.c
   src/core/lib/compression/message_compress.c
   src/core/lib/debug/trace.c
@@ -878,6 +949,7 @@ add_library(grpc
   src/core/lib/iomgr/iomgr_uv.c
   src/core/lib/iomgr/iomgr_windows.c
   src/core/lib/iomgr/load_file.c
+  src/core/lib/iomgr/lockfree_event.c
   src/core/lib/iomgr/network_status_tracker.c
   src/core/lib/iomgr/polling_entity.c
   src/core/lib/iomgr/pollset_set_uv.c
@@ -889,6 +961,7 @@ add_library(grpc
   src/core/lib/iomgr/resolve_address_windows.c
   src/core/lib/iomgr/resource_quota.c
   src/core/lib/iomgr/sockaddr_utils.c
+  src/core/lib/iomgr/socket_factory_posix.c
   src/core/lib/iomgr/socket_mutator.c
   src/core/lib/iomgr/socket_utils_common_posix.c
   src/core/lib/iomgr/socket_utils_linux.c
@@ -901,6 +974,9 @@ add_library(grpc
   src/core/lib/iomgr/tcp_client_windows.c
   src/core/lib/iomgr/tcp_posix.c
   src/core/lib/iomgr/tcp_server_posix.c
+  src/core/lib/iomgr/tcp_server_utils_posix_common.c
+  src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
+  src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
   src/core/lib/iomgr/tcp_server_uv.c
   src/core/lib/iomgr/tcp_server_windows.c
   src/core/lib/iomgr/tcp_uv.c
@@ -923,6 +999,7 @@ add_library(grpc
   src/core/lib/json/json_reader.c
   src/core/lib/json/json_string.c
   src/core/lib/json/json_writer.c
+  src/core/lib/slice/b64.c
   src/core/lib/slice/percent_encoding.c
   src/core/lib/slice/slice.c
   src/core/lib/slice/slice_buffer.c
@@ -941,8 +1018,9 @@ add_library(grpc
   src/core/lib/surface/channel_ping.c
   src/core/lib/surface/channel_stack_type.c
   src/core/lib/surface/completion_queue.c
+  src/core/lib/surface/completion_queue_factory.c
   src/core/lib/surface/event_string.c
-  src/core/lib/surface/lame_client.c
+  src/core/lib/surface/lame_client.cc
   src/core/lib/surface/metadata_array.c
   src/core/lib/surface/server.c
   src/core/lib/surface/validate_metadata.c
@@ -974,6 +1052,7 @@ add_library(grpc
   src/core/ext/transport/chttp2/transport/hpack_encoder.c
   src/core/ext/transport/chttp2/transport/hpack_parser.c
   src/core/ext/transport/chttp2/transport/hpack_table.c
+  src/core/ext/transport/chttp2/transport/http2_settings.c
   src/core/ext/transport/chttp2/transport/huffsyms.c
   src/core/ext/transport/chttp2/transport/incoming_metadata.c
   src/core/ext/transport/chttp2/transport/parsing.c
@@ -982,6 +1061,10 @@ add_library(grpc
   src/core/ext/transport/chttp2/transport/varint.c
   src/core/ext/transport/chttp2/transport/writing.c
   src/core/ext/transport/chttp2/alpn/alpn.c
+  src/core/ext/filters/http/client/http_client_filter.c
+  src/core/ext/filters/http/http_filters_plugin.c
+  src/core/ext/filters/http/message_compress/message_compress_filter.c
+  src/core/ext/filters/http/server/http_server_filter.c
   src/core/lib/http/httpcli_security_connector.c
   src/core/lib/security/context/security_context.c
   src/core/lib/security/credentials/composite/composite_credentials.c
@@ -1004,53 +1087,58 @@ add_library(grpc
   src/core/lib/security/transport/security_handshaker.c
   src/core/lib/security/transport/server_auth_filter.c
   src/core/lib/security/transport/tsi_error.c
-  src/core/lib/security/util/b64.c
   src/core/lib/security/util/json_util.c
   src/core/lib/surface/init_secure.c
-  src/core/lib/tsi/fake_transport_security.c
-  src/core/lib/tsi/ssl_transport_security.c
-  src/core/lib/tsi/transport_security.c
+  src/core/tsi/fake_transport_security.c
+  src/core/tsi/ssl_transport_security.c
+  src/core/tsi/transport_security.c
+  src/core/tsi/transport_security_adapter.c
   src/core/ext/transport/chttp2/server/chttp2_server.c
   src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
-  src/core/ext/client_channel/channel_connectivity.c
-  src/core/ext/client_channel/client_channel.c
-  src/core/ext/client_channel/client_channel_factory.c
-  src/core/ext/client_channel/client_channel_plugin.c
-  src/core/ext/client_channel/connector.c
-  src/core/ext/client_channel/default_initial_connect_string.c
-  src/core/ext/client_channel/http_connect_handshaker.c
-  src/core/ext/client_channel/http_proxy.c
-  src/core/ext/client_channel/initial_connect_string.c
-  src/core/ext/client_channel/lb_policy.c
-  src/core/ext/client_channel/lb_policy_factory.c
-  src/core/ext/client_channel/lb_policy_registry.c
-  src/core/ext/client_channel/parse_address.c
-  src/core/ext/client_channel/proxy_mapper.c
-  src/core/ext/client_channel/proxy_mapper_registry.c
-  src/core/ext/client_channel/resolver.c
-  src/core/ext/client_channel/resolver_factory.c
-  src/core/ext/client_channel/resolver_registry.c
-  src/core/ext/client_channel/subchannel.c
-  src/core/ext/client_channel/subchannel_index.c
-  src/core/ext/client_channel/uri_parser.c
+  src/core/ext/filters/client_channel/channel_connectivity.c
+  src/core/ext/filters/client_channel/client_channel.c
+  src/core/ext/filters/client_channel/client_channel_factory.c
+  src/core/ext/filters/client_channel/client_channel_plugin.c
+  src/core/ext/filters/client_channel/connector.c
+  src/core/ext/filters/client_channel/http_connect_handshaker.c
+  src/core/ext/filters/client_channel/http_proxy.c
+  src/core/ext/filters/client_channel/lb_policy.c
+  src/core/ext/filters/client_channel/lb_policy_factory.c
+  src/core/ext/filters/client_channel/lb_policy_registry.c
+  src/core/ext/filters/client_channel/parse_address.c
+  src/core/ext/filters/client_channel/proxy_mapper.c
+  src/core/ext/filters/client_channel/proxy_mapper_registry.c
+  src/core/ext/filters/client_channel/resolver.c
+  src/core/ext/filters/client_channel/resolver_factory.c
+  src/core/ext/filters/client_channel/resolver_registry.c
+  src/core/ext/filters/client_channel/retry_throttle.c
+  src/core/ext/filters/client_channel/subchannel.c
+  src/core/ext/filters/client_channel/subchannel_index.c
+  src/core/ext/filters/client_channel/uri_parser.c
+  src/core/ext/filters/deadline/deadline_filter.c
   src/core/ext/transport/chttp2/client/chttp2_connector.c
   src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
   src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
   src/core/ext/transport/chttp2/client/insecure/channel_create.c
   src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
-  src/core/ext/lb_policy/grpclb/grpclb.c
-  src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c
-  src/core/ext/lb_policy/grpclb/load_balancer_api.c
-  src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
+  src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c
+  src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
+  src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c
+  src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c
+  src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c
+  src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
   third_party/nanopb/pb_common.c
   third_party/nanopb/pb_decode.c
   third_party/nanopb/pb_encode.c
-  src/core/ext/lb_policy/pick_first/pick_first.c
-  src/core/ext/lb_policy/round_robin/round_robin.c
-  src/core/ext/resolver/dns/native/dns_resolver.c
-  src/core/ext/resolver/sockaddr/sockaddr_resolver.c
-  src/core/ext/load_reporting/load_reporting.c
-  src/core/ext/load_reporting/load_reporting_filter.c
+  src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c
+  src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c
+  src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c
+  src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
+  src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
+  src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c
+  src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c
+  src/core/ext/filters/load_reporting/load_reporting.c
+  src/core/ext/filters/load_reporting/load_reporting_filter.c
   src/core/ext/census/base_resources.c
   src/core/ext/census/context.c
   src/core/ext/census/gen/census.pb.c
@@ -1065,6 +1153,8 @@ add_library(grpc
   src/core/ext/census/resource.c
   src/core/ext/census/trace_context.c
   src/core/ext/census/tracing.c
+  src/core/ext/filters/max_age/max_age_filter.c
+  src/core/ext/filters/message_size/message_size_filter.c
   src/core/plugin_registry/grpc_plugin_registry.c
 )
 
@@ -1088,6 +1178,10 @@ target_include_directories(grpc
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -1095,6 +1189,7 @@ target_link_libraries(grpc
   ${_gRPC_BASELIB_LIBRARIES}
   ${_gRPC_SSL_LIBRARIES}
   ${_gRPC_ZLIB_LIBRARIES}
+  ${_gRPC_CARES_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
   gpr
 )
@@ -1116,6 +1211,7 @@ foreach(_hdr
   include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/grpc_types.h
   include/grpc/impl/codegen/propagation_bits.h
+  include/grpc/impl/codegen/slice.h
   include/grpc/impl/codegen/status.h
   include/grpc/impl/codegen/atm.h
   include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -1124,7 +1220,6 @@ foreach(_hdr
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
-  include/grpc/impl/codegen/slice.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_generic.h
   include/grpc/impl/codegen/sync_posix.h
@@ -1154,15 +1249,10 @@ add_library(grpc_cronet
   src/core/lib/channel/channel_args.c
   src/core/lib/channel/channel_stack.c
   src/core/lib/channel/channel_stack_builder.c
-  src/core/lib/channel/compress_filter.c
   src/core/lib/channel/connected_channel.c
-  src/core/lib/channel/deadline_filter.c
   src/core/lib/channel/handshaker.c
   src/core/lib/channel/handshaker_factory.c
   src/core/lib/channel/handshaker_registry.c
-  src/core/lib/channel/http_client_filter.c
-  src/core/lib/channel/http_server_filter.c
-  src/core/lib/channel/message_size_filter.c
   src/core/lib/compression/compression.c
   src/core/lib/compression/message_compress.c
   src/core/lib/debug/trace.c
@@ -1187,6 +1277,7 @@ add_library(grpc_cronet
   src/core/lib/iomgr/iomgr_uv.c
   src/core/lib/iomgr/iomgr_windows.c
   src/core/lib/iomgr/load_file.c
+  src/core/lib/iomgr/lockfree_event.c
   src/core/lib/iomgr/network_status_tracker.c
   src/core/lib/iomgr/polling_entity.c
   src/core/lib/iomgr/pollset_set_uv.c
@@ -1198,6 +1289,7 @@ add_library(grpc_cronet
   src/core/lib/iomgr/resolve_address_windows.c
   src/core/lib/iomgr/resource_quota.c
   src/core/lib/iomgr/sockaddr_utils.c
+  src/core/lib/iomgr/socket_factory_posix.c
   src/core/lib/iomgr/socket_mutator.c
   src/core/lib/iomgr/socket_utils_common_posix.c
   src/core/lib/iomgr/socket_utils_linux.c
@@ -1210,6 +1302,9 @@ add_library(grpc_cronet
   src/core/lib/iomgr/tcp_client_windows.c
   src/core/lib/iomgr/tcp_posix.c
   src/core/lib/iomgr/tcp_server_posix.c
+  src/core/lib/iomgr/tcp_server_utils_posix_common.c
+  src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
+  src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
   src/core/lib/iomgr/tcp_server_uv.c
   src/core/lib/iomgr/tcp_server_windows.c
   src/core/lib/iomgr/tcp_uv.c
@@ -1232,6 +1327,7 @@ add_library(grpc_cronet
   src/core/lib/json/json_reader.c
   src/core/lib/json/json_string.c
   src/core/lib/json/json_writer.c
+  src/core/lib/slice/b64.c
   src/core/lib/slice/percent_encoding.c
   src/core/lib/slice/slice.c
   src/core/lib/slice/slice_buffer.c
@@ -1250,8 +1346,9 @@ add_library(grpc_cronet
   src/core/lib/surface/channel_ping.c
   src/core/lib/surface/channel_stack_type.c
   src/core/lib/surface/completion_queue.c
+  src/core/lib/surface/completion_queue_factory.c
   src/core/lib/surface/event_string.c
-  src/core/lib/surface/lame_client.c
+  src/core/lib/surface/lame_client.cc
   src/core/lib/surface/metadata_array.c
   src/core/lib/surface/server.c
   src/core/lib/surface/validate_metadata.c
@@ -1286,6 +1383,7 @@ add_library(grpc_cronet
   src/core/ext/transport/chttp2/transport/hpack_encoder.c
   src/core/ext/transport/chttp2/transport/hpack_parser.c
   src/core/ext/transport/chttp2/transport/hpack_table.c
+  src/core/ext/transport/chttp2/transport/http2_settings.c
   src/core/ext/transport/chttp2/transport/huffsyms.c
   src/core/ext/transport/chttp2/transport/incoming_metadata.c
   src/core/ext/transport/chttp2/transport/parsing.c
@@ -1294,27 +1392,31 @@ add_library(grpc_cronet
   src/core/ext/transport/chttp2/transport/varint.c
   src/core/ext/transport/chttp2/transport/writing.c
   src/core/ext/transport/chttp2/alpn/alpn.c
-  src/core/ext/client_channel/channel_connectivity.c
-  src/core/ext/client_channel/client_channel.c
-  src/core/ext/client_channel/client_channel_factory.c
-  src/core/ext/client_channel/client_channel_plugin.c
-  src/core/ext/client_channel/connector.c
-  src/core/ext/client_channel/default_initial_connect_string.c
-  src/core/ext/client_channel/http_connect_handshaker.c
-  src/core/ext/client_channel/http_proxy.c
-  src/core/ext/client_channel/initial_connect_string.c
-  src/core/ext/client_channel/lb_policy.c
-  src/core/ext/client_channel/lb_policy_factory.c
-  src/core/ext/client_channel/lb_policy_registry.c
-  src/core/ext/client_channel/parse_address.c
-  src/core/ext/client_channel/proxy_mapper.c
-  src/core/ext/client_channel/proxy_mapper_registry.c
-  src/core/ext/client_channel/resolver.c
-  src/core/ext/client_channel/resolver_factory.c
-  src/core/ext/client_channel/resolver_registry.c
-  src/core/ext/client_channel/subchannel.c
-  src/core/ext/client_channel/subchannel_index.c
-  src/core/ext/client_channel/uri_parser.c
+  src/core/ext/filters/http/client/http_client_filter.c
+  src/core/ext/filters/http/http_filters_plugin.c
+  src/core/ext/filters/http/message_compress/message_compress_filter.c
+  src/core/ext/filters/http/server/http_server_filter.c
+  src/core/ext/filters/client_channel/channel_connectivity.c
+  src/core/ext/filters/client_channel/client_channel.c
+  src/core/ext/filters/client_channel/client_channel_factory.c
+  src/core/ext/filters/client_channel/client_channel_plugin.c
+  src/core/ext/filters/client_channel/connector.c
+  src/core/ext/filters/client_channel/http_connect_handshaker.c
+  src/core/ext/filters/client_channel/http_proxy.c
+  src/core/ext/filters/client_channel/lb_policy.c
+  src/core/ext/filters/client_channel/lb_policy_factory.c
+  src/core/ext/filters/client_channel/lb_policy_registry.c
+  src/core/ext/filters/client_channel/parse_address.c
+  src/core/ext/filters/client_channel/proxy_mapper.c
+  src/core/ext/filters/client_channel/proxy_mapper_registry.c
+  src/core/ext/filters/client_channel/resolver.c
+  src/core/ext/filters/client_channel/resolver_factory.c
+  src/core/ext/filters/client_channel/resolver_registry.c
+  src/core/ext/filters/client_channel/retry_throttle.c
+  src/core/ext/filters/client_channel/subchannel.c
+  src/core/ext/filters/client_channel/subchannel_index.c
+  src/core/ext/filters/client_channel/uri_parser.c
+  src/core/ext/filters/deadline/deadline_filter.c
   src/core/lib/http/httpcli_security_connector.c
   src/core/lib/security/context/security_context.c
   src/core/lib/security/credentials/composite/composite_credentials.c
@@ -1337,15 +1439,15 @@ add_library(grpc_cronet
   src/core/lib/security/transport/security_handshaker.c
   src/core/lib/security/transport/server_auth_filter.c
   src/core/lib/security/transport/tsi_error.c
-  src/core/lib/security/util/b64.c
   src/core/lib/security/util/json_util.c
   src/core/lib/surface/init_secure.c
-  src/core/lib/tsi/fake_transport_security.c
-  src/core/lib/tsi/ssl_transport_security.c
-  src/core/lib/tsi/transport_security.c
+  src/core/tsi/fake_transport_security.c
+  src/core/tsi/ssl_transport_security.c
+  src/core/tsi/transport_security.c
+  src/core/tsi/transport_security_adapter.c
   src/core/ext/transport/chttp2/client/chttp2_connector.c
-  src/core/ext/load_reporting/load_reporting.c
-  src/core/ext/load_reporting/load_reporting_filter.c
+  src/core/ext/filters/load_reporting/load_reporting.c
+  src/core/ext/filters/load_reporting/load_reporting_filter.c
   src/core/plugin_registry/grpc_cronet_plugin_registry.c
 )
 
@@ -1369,6 +1471,10 @@ target_include_directories(grpc_cronet
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -1396,6 +1502,7 @@ foreach(_hdr
   include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/grpc_types.h
   include/grpc/impl/codegen/propagation_bits.h
+  include/grpc/impl/codegen/slice.h
   include/grpc/impl/codegen/status.h
   include/grpc/impl/codegen/atm.h
   include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -1404,7 +1511,6 @@ foreach(_hdr
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
-  include/grpc/impl/codegen/slice.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_generic.h
   include/grpc/impl/codegen/sync_posix.h
@@ -1438,7 +1544,7 @@ add_library(grpc_test_util
   test/core/security/oauth2_utils.c
   test/core/end2end/cq_verifier.c
   test/core/end2end/fake_resolver.c
-  test/core/end2end/fixtures/http_proxy.c
+  test/core/end2end/fixtures/http_proxy_fixture.c
   test/core/end2end/fixtures/proxy.c
   test/core/iomgr/endpoint_tests.c
   test/core/util/debugger_macros.c
@@ -1454,15 +1560,10 @@ add_library(grpc_test_util
   src/core/lib/channel/channel_args.c
   src/core/lib/channel/channel_stack.c
   src/core/lib/channel/channel_stack_builder.c
-  src/core/lib/channel/compress_filter.c
   src/core/lib/channel/connected_channel.c
-  src/core/lib/channel/deadline_filter.c
   src/core/lib/channel/handshaker.c
   src/core/lib/channel/handshaker_factory.c
   src/core/lib/channel/handshaker_registry.c
-  src/core/lib/channel/http_client_filter.c
-  src/core/lib/channel/http_server_filter.c
-  src/core/lib/channel/message_size_filter.c
   src/core/lib/compression/compression.c
   src/core/lib/compression/message_compress.c
   src/core/lib/debug/trace.c
@@ -1487,6 +1588,7 @@ add_library(grpc_test_util
   src/core/lib/iomgr/iomgr_uv.c
   src/core/lib/iomgr/iomgr_windows.c
   src/core/lib/iomgr/load_file.c
+  src/core/lib/iomgr/lockfree_event.c
   src/core/lib/iomgr/network_status_tracker.c
   src/core/lib/iomgr/polling_entity.c
   src/core/lib/iomgr/pollset_set_uv.c
@@ -1498,6 +1600,7 @@ add_library(grpc_test_util
   src/core/lib/iomgr/resolve_address_windows.c
   src/core/lib/iomgr/resource_quota.c
   src/core/lib/iomgr/sockaddr_utils.c
+  src/core/lib/iomgr/socket_factory_posix.c
   src/core/lib/iomgr/socket_mutator.c
   src/core/lib/iomgr/socket_utils_common_posix.c
   src/core/lib/iomgr/socket_utils_linux.c
@@ -1510,6 +1613,9 @@ add_library(grpc_test_util
   src/core/lib/iomgr/tcp_client_windows.c
   src/core/lib/iomgr/tcp_posix.c
   src/core/lib/iomgr/tcp_server_posix.c
+  src/core/lib/iomgr/tcp_server_utils_posix_common.c
+  src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
+  src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
   src/core/lib/iomgr/tcp_server_uv.c
   src/core/lib/iomgr/tcp_server_windows.c
   src/core/lib/iomgr/tcp_uv.c
@@ -1532,6 +1638,7 @@ add_library(grpc_test_util
   src/core/lib/json/json_reader.c
   src/core/lib/json/json_string.c
   src/core/lib/json/json_writer.c
+  src/core/lib/slice/b64.c
   src/core/lib/slice/percent_encoding.c
   src/core/lib/slice/slice.c
   src/core/lib/slice/slice_buffer.c
@@ -1550,8 +1657,9 @@ add_library(grpc_test_util
   src/core/lib/surface/channel_ping.c
   src/core/lib/surface/channel_stack_type.c
   src/core/lib/surface/completion_queue.c
+  src/core/lib/surface/completion_queue_factory.c
   src/core/lib/surface/event_string.c
-  src/core/lib/surface/lame_client.c
+  src/core/lib/surface/lame_client.cc
   src/core/lib/surface/metadata_array.c
   src/core/lib/surface/server.c
   src/core/lib/surface/validate_metadata.c
@@ -1591,6 +1699,10 @@ target_include_directories(grpc_test_util
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -1618,6 +1730,7 @@ foreach(_hdr
   include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/grpc_types.h
   include/grpc/impl/codegen/propagation_bits.h
+  include/grpc/impl/codegen/slice.h
   include/grpc/impl/codegen/status.h
   include/grpc/impl/codegen/atm.h
   include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -1626,7 +1739,6 @@ foreach(_hdr
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
-  include/grpc/impl/codegen/slice.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_generic.h
   include/grpc/impl/codegen/sync_posix.h
@@ -1645,7 +1757,7 @@ if (gRPC_BUILD_TESTS)
 add_library(grpc_test_util_unsecure
   test/core/end2end/cq_verifier.c
   test/core/end2end/fake_resolver.c
-  test/core/end2end/fixtures/http_proxy.c
+  test/core/end2end/fixtures/http_proxy_fixture.c
   test/core/end2end/fixtures/proxy.c
   test/core/iomgr/endpoint_tests.c
   test/core/util/debugger_macros.c
@@ -1680,6 +1792,10 @@ target_include_directories(grpc_test_util_unsecure
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -1700,15 +1816,10 @@ add_library(grpc_unsecure
   src/core/lib/channel/channel_args.c
   src/core/lib/channel/channel_stack.c
   src/core/lib/channel/channel_stack_builder.c
-  src/core/lib/channel/compress_filter.c
   src/core/lib/channel/connected_channel.c
-  src/core/lib/channel/deadline_filter.c
   src/core/lib/channel/handshaker.c
   src/core/lib/channel/handshaker_factory.c
   src/core/lib/channel/handshaker_registry.c
-  src/core/lib/channel/http_client_filter.c
-  src/core/lib/channel/http_server_filter.c
-  src/core/lib/channel/message_size_filter.c
   src/core/lib/compression/compression.c
   src/core/lib/compression/message_compress.c
   src/core/lib/debug/trace.c
@@ -1733,6 +1844,7 @@ add_library(grpc_unsecure
   src/core/lib/iomgr/iomgr_uv.c
   src/core/lib/iomgr/iomgr_windows.c
   src/core/lib/iomgr/load_file.c
+  src/core/lib/iomgr/lockfree_event.c
   src/core/lib/iomgr/network_status_tracker.c
   src/core/lib/iomgr/polling_entity.c
   src/core/lib/iomgr/pollset_set_uv.c
@@ -1744,6 +1856,7 @@ add_library(grpc_unsecure
   src/core/lib/iomgr/resolve_address_windows.c
   src/core/lib/iomgr/resource_quota.c
   src/core/lib/iomgr/sockaddr_utils.c
+  src/core/lib/iomgr/socket_factory_posix.c
   src/core/lib/iomgr/socket_mutator.c
   src/core/lib/iomgr/socket_utils_common_posix.c
   src/core/lib/iomgr/socket_utils_linux.c
@@ -1756,6 +1869,9 @@ add_library(grpc_unsecure
   src/core/lib/iomgr/tcp_client_windows.c
   src/core/lib/iomgr/tcp_posix.c
   src/core/lib/iomgr/tcp_server_posix.c
+  src/core/lib/iomgr/tcp_server_utils_posix_common.c
+  src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
+  src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
   src/core/lib/iomgr/tcp_server_uv.c
   src/core/lib/iomgr/tcp_server_windows.c
   src/core/lib/iomgr/tcp_uv.c
@@ -1778,6 +1894,7 @@ add_library(grpc_unsecure
   src/core/lib/json/json_reader.c
   src/core/lib/json/json_string.c
   src/core/lib/json/json_writer.c
+  src/core/lib/slice/b64.c
   src/core/lib/slice/percent_encoding.c
   src/core/lib/slice/slice.c
   src/core/lib/slice/slice_buffer.c
@@ -1796,8 +1913,9 @@ add_library(grpc_unsecure
   src/core/lib/surface/channel_ping.c
   src/core/lib/surface/channel_stack_type.c
   src/core/lib/surface/completion_queue.c
+  src/core/lib/surface/completion_queue_factory.c
   src/core/lib/surface/event_string.c
-  src/core/lib/surface/lame_client.c
+  src/core/lib/surface/lame_client.cc
   src/core/lib/surface/metadata_array.c
   src/core/lib/surface/server.c
   src/core/lib/surface/validate_metadata.c
@@ -1830,6 +1948,7 @@ add_library(grpc_unsecure
   src/core/ext/transport/chttp2/transport/hpack_encoder.c
   src/core/ext/transport/chttp2/transport/hpack_parser.c
   src/core/ext/transport/chttp2/transport/hpack_table.c
+  src/core/ext/transport/chttp2/transport/http2_settings.c
   src/core/ext/transport/chttp2/transport/huffsyms.c
   src/core/ext/transport/chttp2/transport/incoming_metadata.c
   src/core/ext/transport/chttp2/transport/parsing.c
@@ -1838,44 +1957,53 @@ add_library(grpc_unsecure
   src/core/ext/transport/chttp2/transport/varint.c
   src/core/ext/transport/chttp2/transport/writing.c
   src/core/ext/transport/chttp2/alpn/alpn.c
+  src/core/ext/filters/http/client/http_client_filter.c
+  src/core/ext/filters/http/http_filters_plugin.c
+  src/core/ext/filters/http/message_compress/message_compress_filter.c
+  src/core/ext/filters/http/server/http_server_filter.c
   src/core/ext/transport/chttp2/server/chttp2_server.c
   src/core/ext/transport/chttp2/client/insecure/channel_create.c
   src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
   src/core/ext/transport/chttp2/client/chttp2_connector.c
-  src/core/ext/client_channel/channel_connectivity.c
-  src/core/ext/client_channel/client_channel.c
-  src/core/ext/client_channel/client_channel_factory.c
-  src/core/ext/client_channel/client_channel_plugin.c
-  src/core/ext/client_channel/connector.c
-  src/core/ext/client_channel/default_initial_connect_string.c
-  src/core/ext/client_channel/http_connect_handshaker.c
-  src/core/ext/client_channel/http_proxy.c
-  src/core/ext/client_channel/initial_connect_string.c
-  src/core/ext/client_channel/lb_policy.c
-  src/core/ext/client_channel/lb_policy_factory.c
-  src/core/ext/client_channel/lb_policy_registry.c
-  src/core/ext/client_channel/parse_address.c
-  src/core/ext/client_channel/proxy_mapper.c
-  src/core/ext/client_channel/proxy_mapper_registry.c
-  src/core/ext/client_channel/resolver.c
-  src/core/ext/client_channel/resolver_factory.c
-  src/core/ext/client_channel/resolver_registry.c
-  src/core/ext/client_channel/subchannel.c
-  src/core/ext/client_channel/subchannel_index.c
-  src/core/ext/client_channel/uri_parser.c
-  src/core/ext/resolver/dns/native/dns_resolver.c
-  src/core/ext/resolver/sockaddr/sockaddr_resolver.c
-  src/core/ext/load_reporting/load_reporting.c
-  src/core/ext/load_reporting/load_reporting_filter.c
-  src/core/ext/lb_policy/grpclb/grpclb.c
-  src/core/ext/lb_policy/grpclb/grpclb_channel.c
-  src/core/ext/lb_policy/grpclb/load_balancer_api.c
-  src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
+  src/core/ext/filters/client_channel/channel_connectivity.c
+  src/core/ext/filters/client_channel/client_channel.c
+  src/core/ext/filters/client_channel/client_channel_factory.c
+  src/core/ext/filters/client_channel/client_channel_plugin.c
+  src/core/ext/filters/client_channel/connector.c
+  src/core/ext/filters/client_channel/http_connect_handshaker.c
+  src/core/ext/filters/client_channel/http_proxy.c
+  src/core/ext/filters/client_channel/lb_policy.c
+  src/core/ext/filters/client_channel/lb_policy_factory.c
+  src/core/ext/filters/client_channel/lb_policy_registry.c
+  src/core/ext/filters/client_channel/parse_address.c
+  src/core/ext/filters/client_channel/proxy_mapper.c
+  src/core/ext/filters/client_channel/proxy_mapper_registry.c
+  src/core/ext/filters/client_channel/resolver.c
+  src/core/ext/filters/client_channel/resolver_factory.c
+  src/core/ext/filters/client_channel/resolver_registry.c
+  src/core/ext/filters/client_channel/retry_throttle.c
+  src/core/ext/filters/client_channel/subchannel.c
+  src/core/ext/filters/client_channel/subchannel_index.c
+  src/core/ext/filters/client_channel/uri_parser.c
+  src/core/ext/filters/deadline/deadline_filter.c
+  src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c
+  src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
+  src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
+  src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c
+  src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c
+  src/core/ext/filters/load_reporting/load_reporting.c
+  src/core/ext/filters/load_reporting/load_reporting_filter.c
+  src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c
+  src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
+  src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c
+  src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c
+  src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c
+  src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
   third_party/nanopb/pb_common.c
   third_party/nanopb/pb_decode.c
   third_party/nanopb/pb_encode.c
-  src/core/ext/lb_policy/pick_first/pick_first.c
-  src/core/ext/lb_policy/round_robin/round_robin.c
+  src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c
+  src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c
   src/core/ext/census/base_resources.c
   src/core/ext/census/context.c
   src/core/ext/census/gen/census.pb.c
@@ -1890,6 +2018,8 @@ add_library(grpc_unsecure
   src/core/ext/census/resource.c
   src/core/ext/census/trace_context.c
   src/core/ext/census/tracing.c
+  src/core/ext/filters/max_age/max_age_filter.c
+  src/core/ext/filters/message_size/message_size_filter.c
   src/core/plugin_registry/grpc_unsecure_plugin_registry.c
 )
 
@@ -1913,6 +2043,10 @@ target_include_directories(grpc_unsecure
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -1939,6 +2073,7 @@ foreach(_hdr
   include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/grpc_types.h
   include/grpc/impl/codegen/propagation_bits.h
+  include/grpc/impl/codegen/slice.h
   include/grpc/impl/codegen/status.h
   include/grpc/impl/codegen/atm.h
   include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -1947,7 +2082,6 @@ foreach(_hdr
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
-  include/grpc/impl/codegen/slice.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_generic.h
   include/grpc/impl/codegen/sync_posix.h
@@ -1996,6 +2130,10 @@ target_include_directories(reconnect_server
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -2036,6 +2174,10 @@ target_include_directories(test_tcp_server
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -2074,6 +2216,7 @@ add_library(grpc++
   src/cpp/common/rpc_method.cc
   src/cpp/common/version_cc.cc
   src/cpp/server/async_generic_service.cc
+  src/cpp/server/channel_argument_option.cc
   src/cpp/server/create_default_thread_pool.cc
   src/cpp/server/dynamic_thread_pool.cc
   src/cpp/server/health/default_health_check_service.cc
@@ -2091,6 +2234,129 @@ add_library(grpc++
   src/cpp/util/status.cc
   src/cpp/util/string_ref.cc
   src/cpp/util/time_cc.cc
+  src/core/lib/channel/channel_args.c
+  src/core/lib/channel/channel_stack.c
+  src/core/lib/channel/channel_stack_builder.c
+  src/core/lib/channel/connected_channel.c
+  src/core/lib/channel/handshaker.c
+  src/core/lib/channel/handshaker_factory.c
+  src/core/lib/channel/handshaker_registry.c
+  src/core/lib/compression/compression.c
+  src/core/lib/compression/message_compress.c
+  src/core/lib/debug/trace.c
+  src/core/lib/http/format_request.c
+  src/core/lib/http/httpcli.c
+  src/core/lib/http/parser.c
+  src/core/lib/iomgr/closure.c
+  src/core/lib/iomgr/combiner.c
+  src/core/lib/iomgr/endpoint.c
+  src/core/lib/iomgr/endpoint_pair_posix.c
+  src/core/lib/iomgr/endpoint_pair_uv.c
+  src/core/lib/iomgr/endpoint_pair_windows.c
+  src/core/lib/iomgr/error.c
+  src/core/lib/iomgr/ev_epoll_linux.c
+  src/core/lib/iomgr/ev_poll_posix.c
+  src/core/lib/iomgr/ev_posix.c
+  src/core/lib/iomgr/exec_ctx.c
+  src/core/lib/iomgr/executor.c
+  src/core/lib/iomgr/iocp_windows.c
+  src/core/lib/iomgr/iomgr.c
+  src/core/lib/iomgr/iomgr_posix.c
+  src/core/lib/iomgr/iomgr_uv.c
+  src/core/lib/iomgr/iomgr_windows.c
+  src/core/lib/iomgr/load_file.c
+  src/core/lib/iomgr/lockfree_event.c
+  src/core/lib/iomgr/network_status_tracker.c
+  src/core/lib/iomgr/polling_entity.c
+  src/core/lib/iomgr/pollset_set_uv.c
+  src/core/lib/iomgr/pollset_set_windows.c
+  src/core/lib/iomgr/pollset_uv.c
+  src/core/lib/iomgr/pollset_windows.c
+  src/core/lib/iomgr/resolve_address_posix.c
+  src/core/lib/iomgr/resolve_address_uv.c
+  src/core/lib/iomgr/resolve_address_windows.c
+  src/core/lib/iomgr/resource_quota.c
+  src/core/lib/iomgr/sockaddr_utils.c
+  src/core/lib/iomgr/socket_factory_posix.c
+  src/core/lib/iomgr/socket_mutator.c
+  src/core/lib/iomgr/socket_utils_common_posix.c
+  src/core/lib/iomgr/socket_utils_linux.c
+  src/core/lib/iomgr/socket_utils_posix.c
+  src/core/lib/iomgr/socket_utils_uv.c
+  src/core/lib/iomgr/socket_utils_windows.c
+  src/core/lib/iomgr/socket_windows.c
+  src/core/lib/iomgr/tcp_client_posix.c
+  src/core/lib/iomgr/tcp_client_uv.c
+  src/core/lib/iomgr/tcp_client_windows.c
+  src/core/lib/iomgr/tcp_posix.c
+  src/core/lib/iomgr/tcp_server_posix.c
+  src/core/lib/iomgr/tcp_server_utils_posix_common.c
+  src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
+  src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
+  src/core/lib/iomgr/tcp_server_uv.c
+  src/core/lib/iomgr/tcp_server_windows.c
+  src/core/lib/iomgr/tcp_uv.c
+  src/core/lib/iomgr/tcp_windows.c
+  src/core/lib/iomgr/time_averaged_stats.c
+  src/core/lib/iomgr/timer_generic.c
+  src/core/lib/iomgr/timer_heap.c
+  src/core/lib/iomgr/timer_uv.c
+  src/core/lib/iomgr/udp_server.c
+  src/core/lib/iomgr/unix_sockets_posix.c
+  src/core/lib/iomgr/unix_sockets_posix_noop.c
+  src/core/lib/iomgr/wakeup_fd_cv.c
+  src/core/lib/iomgr/wakeup_fd_eventfd.c
+  src/core/lib/iomgr/wakeup_fd_nospecial.c
+  src/core/lib/iomgr/wakeup_fd_pipe.c
+  src/core/lib/iomgr/wakeup_fd_posix.c
+  src/core/lib/iomgr/workqueue_uv.c
+  src/core/lib/iomgr/workqueue_windows.c
+  src/core/lib/json/json.c
+  src/core/lib/json/json_reader.c
+  src/core/lib/json/json_string.c
+  src/core/lib/json/json_writer.c
+  src/core/lib/slice/b64.c
+  src/core/lib/slice/percent_encoding.c
+  src/core/lib/slice/slice.c
+  src/core/lib/slice/slice_buffer.c
+  src/core/lib/slice/slice_hash_table.c
+  src/core/lib/slice/slice_intern.c
+  src/core/lib/slice/slice_string_helpers.c
+  src/core/lib/surface/alarm.c
+  src/core/lib/surface/api_trace.c
+  src/core/lib/surface/byte_buffer.c
+  src/core/lib/surface/byte_buffer_reader.c
+  src/core/lib/surface/call.c
+  src/core/lib/surface/call_details.c
+  src/core/lib/surface/call_log_batch.c
+  src/core/lib/surface/channel.c
+  src/core/lib/surface/channel_init.c
+  src/core/lib/surface/channel_ping.c
+  src/core/lib/surface/channel_stack_type.c
+  src/core/lib/surface/completion_queue.c
+  src/core/lib/surface/completion_queue_factory.c
+  src/core/lib/surface/event_string.c
+  src/core/lib/surface/lame_client.cc
+  src/core/lib/surface/metadata_array.c
+  src/core/lib/surface/server.c
+  src/core/lib/surface/validate_metadata.c
+  src/core/lib/surface/version.c
+  src/core/lib/transport/bdp_estimator.c
+  src/core/lib/transport/byte_stream.c
+  src/core/lib/transport/connectivity_state.c
+  src/core/lib/transport/error_utils.c
+  src/core/lib/transport/metadata.c
+  src/core/lib/transport/metadata_batch.c
+  src/core/lib/transport/pid_controller.c
+  src/core/lib/transport/service_config.c
+  src/core/lib/transport/static_metadata.c
+  src/core/lib/transport/status_conversion.c
+  src/core/lib/transport/timeout_encoding.c
+  src/core/lib/transport/transport.c
+  src/core/lib/transport/transport_op_string.c
+  third_party/nanopb/pb_common.c
+  third_party/nanopb/pb_decode.c
+  third_party/nanopb/pb_encode.c
   src/cpp/codegen/codegen_init.cc
 )
 
@@ -2114,6 +2380,10 @@ target_include_directories(grpc++
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
@@ -2124,6 +2394,7 @@ target_link_libraries(grpc++
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
   grpc
+  gpr
 )
 
 foreach(_hdr
@@ -2139,6 +2410,7 @@ foreach(_hdr
   include/grpc++/grpc++.h
   include/grpc++/health_check_service_interface.h
   include/grpc++/impl/call.h
+  include/grpc++/impl/channel_argument_option.h
   include/grpc++/impl/client_unary_call.h
   include/grpc++/impl/codegen/core_codegen.h
   include/grpc++/impl/grpc_library.h
@@ -2196,7 +2468,6 @@ foreach(_hdr
   include/grpc++/impl/codegen/slice.h
   include/grpc++/impl/codegen/status.h
   include/grpc++/impl/codegen/status_code_enum.h
-  include/grpc++/impl/codegen/status_helper.h
   include/grpc++/impl/codegen/string_ref.h
   include/grpc++/impl/codegen/stub_options.h
   include/grpc++/impl/codegen/sync_stream.h
@@ -2207,6 +2478,7 @@ foreach(_hdr
   include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/grpc_types.h
   include/grpc/impl/codegen/propagation_bits.h
+  include/grpc/impl/codegen/slice.h
   include/grpc/impl/codegen/status.h
   include/grpc/impl/codegen/atm.h
   include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -2215,11 +2487,20 @@ foreach(_hdr
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
-  include/grpc/impl/codegen/slice.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_windows.h
+  include/grpc/byte_buffer.h
+  include/grpc/byte_buffer_reader.h
+  include/grpc/compression.h
+  include/grpc/grpc.h
+  include/grpc/grpc_posix.h
+  include/grpc/grpc_security_constants.h
+  include/grpc/load_reporting.h
+  include/grpc/slice.h
+  include/grpc/slice_buffer.h
+  include/grpc/status.h
   include/grpc++/impl/codegen/proto_utils.h
   include/grpc++/impl/codegen/config_protobuf.h
 )
@@ -2260,6 +2541,7 @@ add_library(grpc++_cronet
   src/cpp/common/rpc_method.cc
   src/cpp/common/version_cc.cc
   src/cpp/server/async_generic_service.cc
+  src/cpp/server/channel_argument_option.cc
   src/cpp/server/create_default_thread_pool.cc
   src/cpp/server/dynamic_thread_pool.cc
   src/cpp/server/health/default_health_check_service.cc
@@ -2277,42 +2559,13 @@ add_library(grpc++_cronet
   src/cpp/util/status.cc
   src/cpp/util/string_ref.cc
   src/cpp/util/time_cc.cc
-  src/cpp/codegen/codegen_init.cc
-  src/core/ext/transport/chttp2/client/insecure/channel_create.c
-  src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
-  src/core/ext/transport/chttp2/client/chttp2_connector.c
-  src/core/ext/transport/chttp2/transport/bin_decoder.c
-  src/core/ext/transport/chttp2/transport/bin_encoder.c
-  src/core/ext/transport/chttp2/transport/chttp2_plugin.c
-  src/core/ext/transport/chttp2/transport/chttp2_transport.c
-  src/core/ext/transport/chttp2/transport/frame_data.c
-  src/core/ext/transport/chttp2/transport/frame_goaway.c
-  src/core/ext/transport/chttp2/transport/frame_ping.c
-  src/core/ext/transport/chttp2/transport/frame_rst_stream.c
-  src/core/ext/transport/chttp2/transport/frame_settings.c
-  src/core/ext/transport/chttp2/transport/frame_window_update.c
-  src/core/ext/transport/chttp2/transport/hpack_encoder.c
-  src/core/ext/transport/chttp2/transport/hpack_parser.c
-  src/core/ext/transport/chttp2/transport/hpack_table.c
-  src/core/ext/transport/chttp2/transport/huffsyms.c
-  src/core/ext/transport/chttp2/transport/incoming_metadata.c
-  src/core/ext/transport/chttp2/transport/parsing.c
-  src/core/ext/transport/chttp2/transport/stream_lists.c
-  src/core/ext/transport/chttp2/transport/stream_map.c
-  src/core/ext/transport/chttp2/transport/varint.c
-  src/core/ext/transport/chttp2/transport/writing.c
   src/core/lib/channel/channel_args.c
   src/core/lib/channel/channel_stack.c
   src/core/lib/channel/channel_stack_builder.c
-  src/core/lib/channel/compress_filter.c
   src/core/lib/channel/connected_channel.c
-  src/core/lib/channel/deadline_filter.c
   src/core/lib/channel/handshaker.c
   src/core/lib/channel/handshaker_factory.c
   src/core/lib/channel/handshaker_registry.c
-  src/core/lib/channel/http_client_filter.c
-  src/core/lib/channel/http_server_filter.c
-  src/core/lib/channel/message_size_filter.c
   src/core/lib/compression/compression.c
   src/core/lib/compression/message_compress.c
   src/core/lib/debug/trace.c
@@ -2337,6 +2590,7 @@ add_library(grpc++_cronet
   src/core/lib/iomgr/iomgr_uv.c
   src/core/lib/iomgr/iomgr_windows.c
   src/core/lib/iomgr/load_file.c
+  src/core/lib/iomgr/lockfree_event.c
   src/core/lib/iomgr/network_status_tracker.c
   src/core/lib/iomgr/polling_entity.c
   src/core/lib/iomgr/pollset_set_uv.c
@@ -2348,6 +2602,7 @@ add_library(grpc++_cronet
   src/core/lib/iomgr/resolve_address_windows.c
   src/core/lib/iomgr/resource_quota.c
   src/core/lib/iomgr/sockaddr_utils.c
+  src/core/lib/iomgr/socket_factory_posix.c
   src/core/lib/iomgr/socket_mutator.c
   src/core/lib/iomgr/socket_utils_common_posix.c
   src/core/lib/iomgr/socket_utils_linux.c
@@ -2360,6 +2615,9 @@ add_library(grpc++_cronet
   src/core/lib/iomgr/tcp_client_windows.c
   src/core/lib/iomgr/tcp_posix.c
   src/core/lib/iomgr/tcp_server_posix.c
+  src/core/lib/iomgr/tcp_server_utils_posix_common.c
+  src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
+  src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
   src/core/lib/iomgr/tcp_server_uv.c
   src/core/lib/iomgr/tcp_server_windows.c
   src/core/lib/iomgr/tcp_uv.c
@@ -2382,6 +2640,7 @@ add_library(grpc++_cronet
   src/core/lib/json/json_reader.c
   src/core/lib/json/json_string.c
   src/core/lib/json/json_writer.c
+  src/core/lib/slice/b64.c
   src/core/lib/slice/percent_encoding.c
   src/core/lib/slice/slice.c
   src/core/lib/slice/slice_buffer.c
@@ -2400,8 +2659,9 @@ add_library(grpc++_cronet
   src/core/lib/surface/channel_ping.c
   src/core/lib/surface/channel_stack_type.c
   src/core/lib/surface/completion_queue.c
+  src/core/lib/surface/completion_queue_factory.c
   src/core/lib/surface/event_string.c
-  src/core/lib/surface/lame_client.c
+  src/core/lib/surface/lame_client.cc
   src/core/lib/surface/metadata_array.c
   src/core/lib/surface/server.c
   src/core/lib/surface/validate_metadata.c
@@ -2419,28 +2679,60 @@ add_library(grpc++_cronet
   src/core/lib/transport/timeout_encoding.c
   src/core/lib/transport/transport.c
   src/core/lib/transport/transport_op_string.c
+  third_party/nanopb/pb_common.c
+  third_party/nanopb/pb_decode.c
+  third_party/nanopb/pb_encode.c
+  src/cpp/codegen/codegen_init.cc
+  src/core/ext/transport/chttp2/client/insecure/channel_create.c
+  src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
+  src/core/ext/transport/chttp2/client/chttp2_connector.c
+  src/core/ext/transport/chttp2/transport/bin_decoder.c
+  src/core/ext/transport/chttp2/transport/bin_encoder.c
+  src/core/ext/transport/chttp2/transport/chttp2_plugin.c
+  src/core/ext/transport/chttp2/transport/chttp2_transport.c
+  src/core/ext/transport/chttp2/transport/frame_data.c
+  src/core/ext/transport/chttp2/transport/frame_goaway.c
+  src/core/ext/transport/chttp2/transport/frame_ping.c
+  src/core/ext/transport/chttp2/transport/frame_rst_stream.c
+  src/core/ext/transport/chttp2/transport/frame_settings.c
+  src/core/ext/transport/chttp2/transport/frame_window_update.c
+  src/core/ext/transport/chttp2/transport/hpack_encoder.c
+  src/core/ext/transport/chttp2/transport/hpack_parser.c
+  src/core/ext/transport/chttp2/transport/hpack_table.c
+  src/core/ext/transport/chttp2/transport/http2_settings.c
+  src/core/ext/transport/chttp2/transport/huffsyms.c
+  src/core/ext/transport/chttp2/transport/incoming_metadata.c
+  src/core/ext/transport/chttp2/transport/parsing.c
+  src/core/ext/transport/chttp2/transport/stream_lists.c
+  src/core/ext/transport/chttp2/transport/stream_map.c
+  src/core/ext/transport/chttp2/transport/varint.c
+  src/core/ext/transport/chttp2/transport/writing.c
   src/core/ext/transport/chttp2/alpn/alpn.c
-  src/core/ext/client_channel/channel_connectivity.c
-  src/core/ext/client_channel/client_channel.c
-  src/core/ext/client_channel/client_channel_factory.c
-  src/core/ext/client_channel/client_channel_plugin.c
-  src/core/ext/client_channel/connector.c
-  src/core/ext/client_channel/default_initial_connect_string.c
-  src/core/ext/client_channel/http_connect_handshaker.c
-  src/core/ext/client_channel/http_proxy.c
-  src/core/ext/client_channel/initial_connect_string.c
-  src/core/ext/client_channel/lb_policy.c
-  src/core/ext/client_channel/lb_policy_factory.c
-  src/core/ext/client_channel/lb_policy_registry.c
-  src/core/ext/client_channel/parse_address.c
-  src/core/ext/client_channel/proxy_mapper.c
-  src/core/ext/client_channel/proxy_mapper_registry.c
-  src/core/ext/client_channel/resolver.c
-  src/core/ext/client_channel/resolver_factory.c
-  src/core/ext/client_channel/resolver_registry.c
-  src/core/ext/client_channel/subchannel.c
-  src/core/ext/client_channel/subchannel_index.c
-  src/core/ext/client_channel/uri_parser.c
+  src/core/ext/filters/http/client/http_client_filter.c
+  src/core/ext/filters/http/http_filters_plugin.c
+  src/core/ext/filters/http/message_compress/message_compress_filter.c
+  src/core/ext/filters/http/server/http_server_filter.c
+  src/core/ext/filters/client_channel/channel_connectivity.c
+  src/core/ext/filters/client_channel/client_channel.c
+  src/core/ext/filters/client_channel/client_channel_factory.c
+  src/core/ext/filters/client_channel/client_channel_plugin.c
+  src/core/ext/filters/client_channel/connector.c
+  src/core/ext/filters/client_channel/http_connect_handshaker.c
+  src/core/ext/filters/client_channel/http_proxy.c
+  src/core/ext/filters/client_channel/lb_policy.c
+  src/core/ext/filters/client_channel/lb_policy_factory.c
+  src/core/ext/filters/client_channel/lb_policy_registry.c
+  src/core/ext/filters/client_channel/parse_address.c
+  src/core/ext/filters/client_channel/proxy_mapper.c
+  src/core/ext/filters/client_channel/proxy_mapper_registry.c
+  src/core/ext/filters/client_channel/resolver.c
+  src/core/ext/filters/client_channel/resolver_factory.c
+  src/core/ext/filters/client_channel/resolver_registry.c
+  src/core/ext/filters/client_channel/retry_throttle.c
+  src/core/ext/filters/client_channel/subchannel.c
+  src/core/ext/filters/client_channel/subchannel_index.c
+  src/core/ext/filters/client_channel/uri_parser.c
+  src/core/ext/filters/deadline/deadline_filter.c
   src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
   src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
   src/core/ext/transport/chttp2/server/chttp2_server.c
@@ -2458,9 +2750,6 @@ add_library(grpc++_cronet
   src/core/ext/census/resource.c
   src/core/ext/census/trace_context.c
   src/core/ext/census/tracing.c
-  third_party/nanopb/pb_common.c
-  third_party/nanopb/pb_decode.c
-  third_party/nanopb/pb_encode.c
 )
 
 if(WIN32 AND MSVC)
@@ -2483,6 +2772,10 @@ target_include_directories(grpc++_cronet
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
@@ -2509,6 +2802,7 @@ foreach(_hdr
   include/grpc++/grpc++.h
   include/grpc++/health_check_service_interface.h
   include/grpc++/impl/call.h
+  include/grpc++/impl/channel_argument_option.h
   include/grpc++/impl/client_unary_call.h
   include/grpc++/impl/codegen/core_codegen.h
   include/grpc++/impl/grpc_library.h
@@ -2566,7 +2860,6 @@ foreach(_hdr
   include/grpc++/impl/codegen/slice.h
   include/grpc++/impl/codegen/status.h
   include/grpc++/impl/codegen/status_code_enum.h
-  include/grpc++/impl/codegen/status_helper.h
   include/grpc++/impl/codegen/string_ref.h
   include/grpc++/impl/codegen/stub_options.h
   include/grpc++/impl/codegen/sync_stream.h
@@ -2577,6 +2870,7 @@ foreach(_hdr
   include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/grpc_types.h
   include/grpc/impl/codegen/propagation_bits.h
+  include/grpc/impl/codegen/slice.h
   include/grpc/impl/codegen/status.h
   include/grpc/impl/codegen/atm.h
   include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -2585,7 +2879,6 @@ foreach(_hdr
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
-  include/grpc/impl/codegen/slice.h
   include/grpc/impl/codegen/sync.h
   include/grpc/impl/codegen/sync_generic.h
   include/grpc/impl/codegen/sync_posix.h
@@ -2618,32 +2911,31 @@ if (gRPC_INSTALL)
   )
 endif()
 
-if (gRPC_BUILD_TESTS)
 
-add_library(grpc++_proto_reflection_desc_db
-  test/cpp/util/proto_reflection_descriptor_database.cc
-  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.cc
-  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc
-  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.h
-  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h
+add_library(grpc++_error_details
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/status/status.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/status/status.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/status/status.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/status/status.grpc.pb.h
+  src/cpp/util/error_details.cc
 )
 
 if(WIN32 AND MSVC)
-  set_target_properties(grpc++_proto_reflection_desc_db PROPERTIES COMPILE_PDB_NAME "grpc++_proto_reflection_desc_db"
+  set_target_properties(grpc++_error_details PROPERTIES COMPILE_PDB_NAME "grpc++_error_details"
     COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
   )
   if (gRPC_INSTALL)
-    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_proto_reflection_desc_db.pdb
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_error_details.pdb
       DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
     )
   endif()
 endif()
 
 protobuf_generate_grpc_cpp(
-  src/proto/grpc/reflection/v1alpha/reflection.proto
+  src/proto/grpc/status/status.proto
 )
 
-target_include_directories(grpc++_proto_reflection_desc_db
+target_include_directories(grpc++_error_details
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -2651,20 +2943,23 @@ target_include_directories(grpc++_proto_reflection_desc_db
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
-target_link_libraries(grpc++_proto_reflection_desc_db
+target_link_libraries(grpc++_error_details
+  ${_gRPC_BASELIB_LIBRARIES}
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
   grpc++
 )
 
 foreach(_hdr
-  include/grpc++/impl/codegen/config_protobuf.h
+  include/grpc++/support/error_details.h
 )
   string(REPLACE "include/" "" _path ${_hdr})
   get_filename_component(_path ${_path} PATH)
@@ -2673,11 +2968,19 @@ foreach(_hdr
   )
 endforeach()
 
-endif (gRPC_BUILD_TESTS)
 
-add_library(grpc++_reflection
-  src/cpp/ext/proto_server_reflection.cc
-  src/cpp/ext/proto_server_reflection_plugin.cc
+if (gRPC_INSTALL)
+  install(TARGETS grpc++_error_details EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+if (gRPC_BUILD_TESTS)
+
+add_library(grpc++_proto_reflection_desc_db
+  test/cpp/util/proto_reflection_descriptor_database.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.h
@@ -2685,11 +2988,11 @@ add_library(grpc++_reflection
 )
 
 if(WIN32 AND MSVC)
-  set_target_properties(grpc++_reflection PROPERTIES COMPILE_PDB_NAME "grpc++_reflection"
+  set_target_properties(grpc++_proto_reflection_desc_db PROPERTIES COMPILE_PDB_NAME "grpc++_proto_reflection_desc_db"
     COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
   )
   if (gRPC_INSTALL)
-    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_reflection.pdb
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_proto_reflection_desc_db.pdb
       DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
     )
   endif()
@@ -2699,7 +3002,7 @@ protobuf_generate_grpc_cpp(
   src/proto/grpc/reflection/v1alpha/reflection.proto
 )
 
-target_include_directories(grpc++_reflection
+target_include_directories(grpc++_proto_reflection_desc_db
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -2707,11 +3010,77 @@ target_include_directories(grpc++_reflection
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
-target_link_libraries(grpc++_reflection
+target_link_libraries(grpc++_proto_reflection_desc_db
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc++
+)
+
+foreach(_hdr
+  include/grpc++/impl/codegen/config_protobuf.h
+)
+  string(REPLACE "include/" "" _path ${_hdr})
+  get_filename_component(_path ${_path} PATH)
+  install(FILES ${_hdr}
+    DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_path}"
+  )
+endforeach()
+
+endif (gRPC_BUILD_TESTS)
+
+add_library(grpc++_reflection
+  src/cpp/ext/proto_server_reflection.cc
+  src/cpp/ext/proto_server_reflection_plugin.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h
+)
+
+if(WIN32 AND MSVC)
+  set_target_properties(grpc++_reflection PROPERTIES COMPILE_PDB_NAME "grpc++_reflection"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_reflection.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/reflection/v1alpha/reflection.proto
+)
+
+target_include_directories(grpc++_reflection
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${BENCHMARK}/include
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(grpc++_reflection
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
   grpc++
@@ -2762,9 +3131,15 @@ target_include_directories(grpc++_test_config
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -2790,6 +3165,7 @@ add_library(grpc++_test_util
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_mock.grpc.pb.h
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h
@@ -2835,9 +3211,15 @@ target_include_directories(grpc++_test_util
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -2874,7 +3256,6 @@ foreach(_hdr
   include/grpc++/impl/codegen/slice.h
   include/grpc++/impl/codegen/status.h
   include/grpc++/impl/codegen/status_code_enum.h
-  include/grpc++/impl/codegen/status_helper.h
   include/grpc++/impl/codegen/string_ref.h
   include/grpc++/impl/codegen/stub_options.h
   include/grpc++/impl/codegen/sync_stream.h
@@ -2885,6 +3266,7 @@ foreach(_hdr
   include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/grpc_types.h
   include/grpc/impl/codegen/propagation_bits.h
+  include/grpc/impl/codegen/slice.h
   include/grpc/impl/codegen/status.h
   include/grpc/impl/codegen/atm.h
   include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -2893,15 +3275,12 @@ foreach(_hdr
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
-  include/grpc/impl/codegen/slice.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_windows.h
   include/grpc++/impl/codegen/proto_utils.h
   include/grpc++/impl/codegen/config_protobuf.h
-  include/grpc++/impl/codegen/thrift_serializer.h
-  include/grpc++/impl/codegen/thrift_utils.h
 )
   string(REPLACE "include/" "" _path ${_hdr})
   get_filename_component(_path ${_path} PATH)
@@ -2931,6 +3310,7 @@ add_library(grpc++_unsecure
   src/cpp/common/rpc_method.cc
   src/cpp/common/version_cc.cc
   src/cpp/server/async_generic_service.cc
+  src/cpp/server/channel_argument_option.cc
   src/cpp/server/create_default_thread_pool.cc
   src/cpp/server/dynamic_thread_pool.cc
   src/cpp/server/health/default_health_check_service.cc
@@ -2948,6 +3328,129 @@ add_library(grpc++_unsecure
   src/cpp/util/status.cc
   src/cpp/util/string_ref.cc
   src/cpp/util/time_cc.cc
+  src/core/lib/channel/channel_args.c
+  src/core/lib/channel/channel_stack.c
+  src/core/lib/channel/channel_stack_builder.c
+  src/core/lib/channel/connected_channel.c
+  src/core/lib/channel/handshaker.c
+  src/core/lib/channel/handshaker_factory.c
+  src/core/lib/channel/handshaker_registry.c
+  src/core/lib/compression/compression.c
+  src/core/lib/compression/message_compress.c
+  src/core/lib/debug/trace.c
+  src/core/lib/http/format_request.c
+  src/core/lib/http/httpcli.c
+  src/core/lib/http/parser.c
+  src/core/lib/iomgr/closure.c
+  src/core/lib/iomgr/combiner.c
+  src/core/lib/iomgr/endpoint.c
+  src/core/lib/iomgr/endpoint_pair_posix.c
+  src/core/lib/iomgr/endpoint_pair_uv.c
+  src/core/lib/iomgr/endpoint_pair_windows.c
+  src/core/lib/iomgr/error.c
+  src/core/lib/iomgr/ev_epoll_linux.c
+  src/core/lib/iomgr/ev_poll_posix.c
+  src/core/lib/iomgr/ev_posix.c
+  src/core/lib/iomgr/exec_ctx.c
+  src/core/lib/iomgr/executor.c
+  src/core/lib/iomgr/iocp_windows.c
+  src/core/lib/iomgr/iomgr.c
+  src/core/lib/iomgr/iomgr_posix.c
+  src/core/lib/iomgr/iomgr_uv.c
+  src/core/lib/iomgr/iomgr_windows.c
+  src/core/lib/iomgr/load_file.c
+  src/core/lib/iomgr/lockfree_event.c
+  src/core/lib/iomgr/network_status_tracker.c
+  src/core/lib/iomgr/polling_entity.c
+  src/core/lib/iomgr/pollset_set_uv.c
+  src/core/lib/iomgr/pollset_set_windows.c
+  src/core/lib/iomgr/pollset_uv.c
+  src/core/lib/iomgr/pollset_windows.c
+  src/core/lib/iomgr/resolve_address_posix.c
+  src/core/lib/iomgr/resolve_address_uv.c
+  src/core/lib/iomgr/resolve_address_windows.c
+  src/core/lib/iomgr/resource_quota.c
+  src/core/lib/iomgr/sockaddr_utils.c
+  src/core/lib/iomgr/socket_factory_posix.c
+  src/core/lib/iomgr/socket_mutator.c
+  src/core/lib/iomgr/socket_utils_common_posix.c
+  src/core/lib/iomgr/socket_utils_linux.c
+  src/core/lib/iomgr/socket_utils_posix.c
+  src/core/lib/iomgr/socket_utils_uv.c
+  src/core/lib/iomgr/socket_utils_windows.c
+  src/core/lib/iomgr/socket_windows.c
+  src/core/lib/iomgr/tcp_client_posix.c
+  src/core/lib/iomgr/tcp_client_uv.c
+  src/core/lib/iomgr/tcp_client_windows.c
+  src/core/lib/iomgr/tcp_posix.c
+  src/core/lib/iomgr/tcp_server_posix.c
+  src/core/lib/iomgr/tcp_server_utils_posix_common.c
+  src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
+  src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
+  src/core/lib/iomgr/tcp_server_uv.c
+  src/core/lib/iomgr/tcp_server_windows.c
+  src/core/lib/iomgr/tcp_uv.c
+  src/core/lib/iomgr/tcp_windows.c
+  src/core/lib/iomgr/time_averaged_stats.c
+  src/core/lib/iomgr/timer_generic.c
+  src/core/lib/iomgr/timer_heap.c
+  src/core/lib/iomgr/timer_uv.c
+  src/core/lib/iomgr/udp_server.c
+  src/core/lib/iomgr/unix_sockets_posix.c
+  src/core/lib/iomgr/unix_sockets_posix_noop.c
+  src/core/lib/iomgr/wakeup_fd_cv.c
+  src/core/lib/iomgr/wakeup_fd_eventfd.c
+  src/core/lib/iomgr/wakeup_fd_nospecial.c
+  src/core/lib/iomgr/wakeup_fd_pipe.c
+  src/core/lib/iomgr/wakeup_fd_posix.c
+  src/core/lib/iomgr/workqueue_uv.c
+  src/core/lib/iomgr/workqueue_windows.c
+  src/core/lib/json/json.c
+  src/core/lib/json/json_reader.c
+  src/core/lib/json/json_string.c
+  src/core/lib/json/json_writer.c
+  src/core/lib/slice/b64.c
+  src/core/lib/slice/percent_encoding.c
+  src/core/lib/slice/slice.c
+  src/core/lib/slice/slice_buffer.c
+  src/core/lib/slice/slice_hash_table.c
+  src/core/lib/slice/slice_intern.c
+  src/core/lib/slice/slice_string_helpers.c
+  src/core/lib/surface/alarm.c
+  src/core/lib/surface/api_trace.c
+  src/core/lib/surface/byte_buffer.c
+  src/core/lib/surface/byte_buffer_reader.c
+  src/core/lib/surface/call.c
+  src/core/lib/surface/call_details.c
+  src/core/lib/surface/call_log_batch.c
+  src/core/lib/surface/channel.c
+  src/core/lib/surface/channel_init.c
+  src/core/lib/surface/channel_ping.c
+  src/core/lib/surface/channel_stack_type.c
+  src/core/lib/surface/completion_queue.c
+  src/core/lib/surface/completion_queue_factory.c
+  src/core/lib/surface/event_string.c
+  src/core/lib/surface/lame_client.cc
+  src/core/lib/surface/metadata_array.c
+  src/core/lib/surface/server.c
+  src/core/lib/surface/validate_metadata.c
+  src/core/lib/surface/version.c
+  src/core/lib/transport/bdp_estimator.c
+  src/core/lib/transport/byte_stream.c
+  src/core/lib/transport/connectivity_state.c
+  src/core/lib/transport/error_utils.c
+  src/core/lib/transport/metadata.c
+  src/core/lib/transport/metadata_batch.c
+  src/core/lib/transport/pid_controller.c
+  src/core/lib/transport/service_config.c
+  src/core/lib/transport/static_metadata.c
+  src/core/lib/transport/status_conversion.c
+  src/core/lib/transport/timeout_encoding.c
+  src/core/lib/transport/transport.c
+  src/core/lib/transport/transport_op_string.c
+  third_party/nanopb/pb_common.c
+  third_party/nanopb/pb_decode.c
+  third_party/nanopb/pb_encode.c
   src/cpp/codegen/codegen_init.cc
 )
 
@@ -2971,6 +3474,10 @@ target_include_directories(grpc++_unsecure
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
@@ -2996,6 +3503,7 @@ foreach(_hdr
   include/grpc++/grpc++.h
   include/grpc++/health_check_service_interface.h
   include/grpc++/impl/call.h
+  include/grpc++/impl/channel_argument_option.h
   include/grpc++/impl/client_unary_call.h
   include/grpc++/impl/codegen/core_codegen.h
   include/grpc++/impl/grpc_library.h
@@ -3053,7 +3561,6 @@ foreach(_hdr
   include/grpc++/impl/codegen/slice.h
   include/grpc++/impl/codegen/status.h
   include/grpc++/impl/codegen/status_code_enum.h
-  include/grpc++/impl/codegen/status_helper.h
   include/grpc++/impl/codegen/string_ref.h
   include/grpc++/impl/codegen/stub_options.h
   include/grpc++/impl/codegen/sync_stream.h
@@ -3064,6 +3571,7 @@ foreach(_hdr
   include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/grpc_types.h
   include/grpc/impl/codegen/propagation_bits.h
+  include/grpc/impl/codegen/slice.h
   include/grpc/impl/codegen/status.h
   include/grpc/impl/codegen/atm.h
   include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -3072,11 +3580,20 @@ foreach(_hdr
   include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
-  include/grpc/impl/codegen/slice.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_windows.h
+  include/grpc/byte_buffer.h
+  include/grpc/byte_buffer_reader.h
+  include/grpc/compression.h
+  include/grpc/grpc.h
+  include/grpc/grpc_posix.h
+  include/grpc/grpc_security_constants.h
+  include/grpc/load_reporting.h
+  include/grpc/slice.h
+  include/grpc/slice_buffer.h
+  include/grpc/status.h
 )
   string(REPLACE "include/" "" _path ${_hdr})
   get_filename_component(_path ${_path} PATH)
@@ -3096,6 +3613,56 @@ endif()
 
 if (gRPC_BUILD_TESTS)
 
+add_library(grpc_benchmark
+  test/cpp/microbenchmarks/helpers.cc
+)
+
+if(WIN32 AND MSVC)
+  set_target_properties(grpc_benchmark PROPERTIES COMPILE_PDB_NAME "grpc_benchmark"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc_benchmark.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
+
+target_include_directories(grpc_benchmark
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${BENCHMARK}/include
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(grpc_benchmark
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  benchmark
+  grpc++
+  grpc_test_util
+  grpc
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
 add_library(grpc_cli_libs
   test/cpp/util/cli_call.cc
   test/cpp/util/cli_credentials.cc
@@ -3131,9 +3698,15 @@ target_include_directories(grpc_cli_libs
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -3186,6 +3759,10 @@ target_include_directories(grpc_plugin_support
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
@@ -3262,9 +3839,15 @@ target_include_directories(http2_client_main
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -3313,9 +3896,15 @@ target_include_directories(interop_client_helper
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -3379,9 +3968,15 @@ target_include_directories(interop_client_main
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -3426,9 +4021,15 @@ target_include_directories(interop_server_helper
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -3491,9 +4092,15 @@ target_include_directories(interop_server_lib
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -3538,9 +4145,15 @@ target_include_directories(interop_server_main
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -3575,6 +4188,7 @@ add_library(qps
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.grpc.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.pb.h
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.grpc.pb.h
+  test/cpp/qps/benchmark_config.cc
   test/cpp/qps/client_async.cc
   test/cpp/qps/client_sync.cc
   test/cpp/qps/driver.cc
@@ -3584,7 +4198,6 @@ add_library(qps
   test/cpp/qps/server_async.cc
   test/cpp/qps/server_sync.cc
   test/cpp/qps/usage_timer.cc
-  test/cpp/util/benchmark_config.cc
 )
 
 if(WIN32 AND MSVC)
@@ -3622,9 +4235,15 @@ target_include_directories(qps
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -3663,6 +4282,10 @@ target_include_directories(grpc_csharp_ext
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -3684,6 +4307,94 @@ endif()
 
 if (gRPC_BUILD_TESTS)
 
+add_library(ares
+  third_party/cares/cares/ares__close_sockets.c
+  third_party/cares/cares/ares__get_hostent.c
+  third_party/cares/cares/ares__read_line.c
+  third_party/cares/cares/ares__timeval.c
+  third_party/cares/cares/ares_cancel.c
+  third_party/cares/cares/ares_create_query.c
+  third_party/cares/cares/ares_data.c
+  third_party/cares/cares/ares_destroy.c
+  third_party/cares/cares/ares_expand_name.c
+  third_party/cares/cares/ares_expand_string.c
+  third_party/cares/cares/ares_fds.c
+  third_party/cares/cares/ares_free_hostent.c
+  third_party/cares/cares/ares_free_string.c
+  third_party/cares/cares/ares_getenv.c
+  third_party/cares/cares/ares_gethostbyaddr.c
+  third_party/cares/cares/ares_gethostbyname.c
+  third_party/cares/cares/ares_getnameinfo.c
+  third_party/cares/cares/ares_getopt.c
+  third_party/cares/cares/ares_getsock.c
+  third_party/cares/cares/ares_init.c
+  third_party/cares/cares/ares_library_init.c
+  third_party/cares/cares/ares_llist.c
+  third_party/cares/cares/ares_mkquery.c
+  third_party/cares/cares/ares_nowarn.c
+  third_party/cares/cares/ares_options.c
+  third_party/cares/cares/ares_parse_a_reply.c
+  third_party/cares/cares/ares_parse_aaaa_reply.c
+  third_party/cares/cares/ares_parse_mx_reply.c
+  third_party/cares/cares/ares_parse_naptr_reply.c
+  third_party/cares/cares/ares_parse_ns_reply.c
+  third_party/cares/cares/ares_parse_ptr_reply.c
+  third_party/cares/cares/ares_parse_soa_reply.c
+  third_party/cares/cares/ares_parse_srv_reply.c
+  third_party/cares/cares/ares_parse_txt_reply.c
+  third_party/cares/cares/ares_platform.c
+  third_party/cares/cares/ares_process.c
+  third_party/cares/cares/ares_query.c
+  third_party/cares/cares/ares_search.c
+  third_party/cares/cares/ares_send.c
+  third_party/cares/cares/ares_strcasecmp.c
+  third_party/cares/cares/ares_strdup.c
+  third_party/cares/cares/ares_strerror.c
+  third_party/cares/cares/ares_timeout.c
+  third_party/cares/cares/ares_version.c
+  third_party/cares/cares/ares_writev.c
+  third_party/cares/cares/bitncmp.c
+  third_party/cares/cares/inet_net_pton.c
+  third_party/cares/cares/inet_ntop.c
+  third_party/cares/cares/windows_port.c
+)
+
+if(WIN32 AND MSVC)
+  set_target_properties(ares PROPERTIES COMPILE_PDB_NAME "ares"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ares.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
+
+target_include_directories(ares
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${BENCHMARK}/include
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(ares
+  ${_gRPC_SSL_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
 add_library(bad_client_test
   test/core/bad_client/bad_client.c
 )
@@ -3708,6 +4419,10 @@ target_include_directories(bad_client_test
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -3747,6 +4462,10 @@ target_include_directories(bad_ssl_test_server
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -3767,6 +4486,7 @@ add_library(end2end_tests
   test/core/end2end/end2end_test_utils.c
   test/core/end2end/tests/authority_not_supported.c
   test/core/end2end/tests/bad_hostname.c
+  test/core/end2end/tests/bad_ping.c
   test/core/end2end/tests/binary_metadata.c
   test/core/end2end/tests/call_creds.c
   test/core/end2end/tests/cancel_after_accept.c
@@ -3792,6 +4512,8 @@ add_library(end2end_tests
   test/core/end2end/tests/large_metadata.c
   test/core/end2end/tests/load_reporting_hook.c
   test/core/end2end/tests/max_concurrent_streams.c
+  test/core/end2end/tests/max_connection_age.c
+  test/core/end2end/tests/max_connection_idle.c
   test/core/end2end/tests/max_message_length.c
   test/core/end2end/tests/negative_deadline.c
   test/core/end2end/tests/network_status_change.c
@@ -3837,6 +4559,10 @@ target_include_directories(end2end_tests
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -3858,6 +4584,7 @@ add_library(end2end_nosec_tests
   test/core/end2end/end2end_test_utils.c
   test/core/end2end/tests/authority_not_supported.c
   test/core/end2end/tests/bad_hostname.c
+  test/core/end2end/tests/bad_ping.c
   test/core/end2end/tests/binary_metadata.c
   test/core/end2end/tests/cancel_after_accept.c
   test/core/end2end/tests/cancel_after_client_done.c
@@ -3882,6 +4609,8 @@ add_library(end2end_nosec_tests
   test/core/end2end/tests/large_metadata.c
   test/core/end2end/tests/load_reporting_hook.c
   test/core/end2end/tests/max_concurrent_streams.c
+  test/core/end2end/tests/max_connection_age.c
+  test/core/end2end/tests/max_connection_idle.c
   test/core/end2end/tests/max_message_length.c
   test/core/end2end/tests/negative_deadline.c
   test/core/end2end/tests/network_status_change.c
@@ -3927,6 +4656,10 @@ target_include_directories(end2end_nosec_tests
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${BENCHMARK}/include
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -3956,6 +4689,10 @@ target_include_directories(alarm_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -3983,6 +4720,10 @@ target_include_directories(algorithm_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4010,6 +4751,10 @@ target_include_directories(alloc_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4035,6 +4780,10 @@ target_include_directories(alpn_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4049,12 +4798,12 @@ target_link_libraries(alpn_test
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 
-add_executable(bad_server_response_test
-  test/core/end2end/bad_server_response_test.c
+add_executable(arena_test
+  test/core/support/arena_test.c
 )
 
 
-target_include_directories(bad_server_response_test
+target_include_directories(arena_test
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -4062,13 +4811,46 @@ target_include_directories(bad_server_response_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
-target_link_libraries(bad_server_response_test
+target_link_libraries(arena_test
   ${_gRPC_ALLTARGETS_LIBRARIES}
-  test_tcp_server
-  grpc_test_util
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(bad_server_response_test
+  test/core/end2end/bad_server_response_test.c
+)
+
+
+target_include_directories(bad_server_response_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(bad_server_response_test
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  test_tcp_server
+  grpc_test_util
   grpc
   gpr_test_util
   gpr
@@ -4090,6 +4872,10 @@ target_include_directories(bdp_estimator_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4117,6 +4903,10 @@ target_include_directories(bin_decoder_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4142,6 +4932,10 @@ target_include_directories(bin_encoder_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4167,6 +4961,10 @@ target_include_directories(census_context_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4194,6 +4992,10 @@ target_include_directories(census_resource_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4221,6 +5023,10 @@ target_include_directories(census_trace_context_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4248,6 +5054,10 @@ target_include_directories(channel_create_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4275,6 +5085,10 @@ target_include_directories(chttp2_hpack_encoder_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4302,6 +5116,10 @@ target_include_directories(chttp2_stream_map_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4329,6 +5147,10 @@ target_include_directories(chttp2_varint_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4356,6 +5178,10 @@ target_include_directories(combiner_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4383,6 +5209,10 @@ target_include_directories(compression_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4410,6 +5240,10 @@ target_include_directories(concurrent_connectivity_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4437,6 +5271,10 @@ target_include_directories(connection_refused_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4464,6 +5302,10 @@ target_include_directories(dns_resolver_connectivity_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4491,6 +5333,10 @@ target_include_directories(dns_resolver_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4519,6 +5365,10 @@ target_include_directories(dualstack_socket_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4547,6 +5397,10 @@ target_include_directories(endpoint_pair_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4558,6 +5412,37 @@ target_link_libraries(endpoint_pair_test
   gpr
 )
 
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(error_test
+  test/core/iomgr/error_test.c
+)
+
+
+target_include_directories(error_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(error_test
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX)
@@ -4575,6 +5460,10 @@ target_include_directories(ev_epoll_linux_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4587,6 +5476,37 @@ target_link_libraries(ev_epoll_linux_test
 )
 
 endif()
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(fake_resolver_test
+  test/core/client_channel/resolvers/fake_resolver_test.c
+)
+
+
+target_include_directories(fake_resolver_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(fake_resolver_test
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@@ -4604,6 +5524,10 @@ target_include_directories(fd_conservation_posix_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4633,6 +5557,10 @@ target_include_directories(fd_posix_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4661,6 +5589,10 @@ target_include_directories(fling_client
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4688,6 +5620,10 @@ target_include_directories(fling_server
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4716,6 +5652,10 @@ target_include_directories(fling_stream_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4745,6 +5685,10 @@ target_include_directories(fling_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4772,6 +5716,10 @@ target_include_directories(gen_hpack_tables
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4804,6 +5752,10 @@ target_include_directories(gen_legal_metadata_characters
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4834,6 +5786,10 @@ target_include_directories(gen_percent_encoding_tables
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4866,6 +5822,10 @@ target_include_directories(goaway_server_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4894,6 +5854,10 @@ target_include_directories(gpr_avl_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4919,6 +5883,10 @@ target_include_directories(gpr_backoff_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4944,6 +5912,10 @@ target_include_directories(gpr_cmdline_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4969,6 +5941,10 @@ target_include_directories(gpr_cpu_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -4994,6 +5970,10 @@ target_include_directories(gpr_env_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5019,6 +5999,10 @@ target_include_directories(gpr_histogram_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5044,6 +6028,10 @@ target_include_directories(gpr_host_port_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5069,6 +6057,10 @@ target_include_directories(gpr_log_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5094,6 +6086,10 @@ target_include_directories(gpr_mpscq_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5119,6 +6115,10 @@ target_include_directories(gpr_spinlock_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5144,6 +6144,10 @@ target_include_directories(gpr_stack_lockfree_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5169,6 +6173,10 @@ target_include_directories(gpr_string_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5194,6 +6202,10 @@ target_include_directories(gpr_sync_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5219,6 +6231,10 @@ target_include_directories(gpr_thd_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5244,6 +6260,10 @@ target_include_directories(gpr_time_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5269,6 +6289,10 @@ target_include_directories(gpr_tls_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5294,6 +6318,10 @@ target_include_directories(gpr_useful_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5319,6 +6347,10 @@ target_include_directories(grpc_auth_context_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5334,7 +6366,7 @@ endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 
 add_executable(grpc_b64_test
-  test/core/security/b64_test.c
+  test/core/slice/b64_test.c
 )
 
 
@@ -5346,6 +6378,10 @@ target_include_directories(grpc_b64_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5373,6 +6409,10 @@ target_include_directories(grpc_byte_buffer_reader_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5400,6 +6440,10 @@ target_include_directories(grpc_channel_args_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5427,6 +6471,10 @@ target_include_directories(grpc_channel_stack_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5454,6 +6502,10 @@ target_include_directories(grpc_completion_queue_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5481,6 +6533,10 @@ target_include_directories(grpc_completion_queue_threading_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5507,6 +6563,10 @@ target_include_directories(grpc_create_jwt
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5541,6 +6601,10 @@ target_include_directories(grpc_credentials_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5568,6 +6632,10 @@ target_include_directories(grpc_fetch_oauth2
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5595,6 +6663,10 @@ target_include_directories(grpc_invalid_channel_args_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5623,6 +6695,10 @@ target_include_directories(grpc_json_token_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5651,6 +6727,10 @@ target_include_directories(grpc_jwt_verifier_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5677,6 +6757,10 @@ target_include_directories(grpc_print_google_default_creds_token
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5710,6 +6794,10 @@ target_include_directories(grpc_security_connector_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5736,6 +6824,10 @@ target_include_directories(grpc_verify_jwt
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5770,6 +6862,10 @@ target_include_directories(handshake_client
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5800,6 +6896,10 @@ target_include_directories(handshake_server
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5829,6 +6929,10 @@ target_include_directories(hpack_parser_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5856,6 +6960,10 @@ target_include_directories(hpack_table_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5883,6 +6991,10 @@ target_include_directories(http_parser_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5910,6 +7022,10 @@ target_include_directories(httpcli_format_request_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5938,6 +7054,10 @@ target_include_directories(httpcli_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5967,6 +7087,10 @@ target_include_directories(httpscli_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -5995,6 +7119,10 @@ target_include_directories(init_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6022,6 +7150,10 @@ target_include_directories(invalid_call_argument_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6049,6 +7181,10 @@ target_include_directories(json_rewrite
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6074,6 +7210,10 @@ target_include_directories(json_rewrite_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6101,6 +7241,10 @@ target_include_directories(json_stream_error_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6128,6 +7272,10 @@ target_include_directories(json_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6155,6 +7303,10 @@ target_include_directories(lame_client_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6182,6 +7334,10 @@ target_include_directories(lb_policies_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6209,6 +7365,10 @@ target_include_directories(load_file_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6236,6 +7396,10 @@ target_include_directories(memory_profile_client
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6263,6 +7427,10 @@ target_include_directories(memory_profile_server
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6291,6 +7459,10 @@ target_include_directories(memory_profile_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6319,6 +7491,10 @@ target_include_directories(message_compress_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6333,6 +7509,37 @@ target_link_libraries(message_compress_test
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 
+add_executable(minimal_stack_is_minimal_test
+  test/core/channel/minimal_stack_is_minimal_test.c
+)
+
+
+target_include_directories(minimal_stack_is_minimal_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(minimal_stack_is_minimal_test
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
 add_executable(mlog_test
   test/core/census/mlog_test.c
 )
@@ -6346,6 +7553,10 @@ target_include_directories(mlog_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6373,6 +7584,10 @@ target_include_directories(multiple_server_queues_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6400,6 +7615,10 @@ target_include_directories(murmur_hash_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6425,6 +7644,10 @@ target_include_directories(no_server_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6439,6 +7662,37 @@ target_link_libraries(no_server_test
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 
+add_executable(parse_address_test
+  test/core/client_channel/parse_address_test.c
+)
+
+
+target_include_directories(parse_address_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(parse_address_test
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
 add_executable(percent_encoding_test
   test/core/slice/percent_encoding_test.c
 )
@@ -6452,6 +7706,10 @@ target_include_directories(percent_encoding_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6480,6 +7738,10 @@ target_include_directories(pollset_set_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6509,6 +7771,10 @@ target_include_directories(resolve_address_posix_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6537,6 +7803,10 @@ target_include_directories(resolve_address_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6564,6 +7834,10 @@ target_include_directories(resource_quota_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6591,6 +7865,10 @@ target_include_directories(secure_channel_create_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6618,6 +7896,10 @@ target_include_directories(secure_endpoint_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6645,6 +7927,10 @@ target_include_directories(sequential_connectivity_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6672,6 +7958,10 @@ target_include_directories(server_chttp2_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6699,6 +7989,10 @@ target_include_directories(server_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6713,12 +8007,12 @@ target_link_libraries(server_test
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 
-add_executable(set_initial_connect_string_test
-  test/core/client_channel/set_initial_connect_string_test.c
+add_executable(slice_buffer_test
+  test/core/slice/slice_buffer_test.c
 )
 
 
-target_include_directories(set_initial_connect_string_test
+target_include_directories(slice_buffer_test
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -6726,12 +8020,15 @@ target_include_directories(set_initial_connect_string_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
-target_link_libraries(set_initial_connect_string_test
+target_link_libraries(slice_buffer_test
   ${_gRPC_ALLTARGETS_LIBRARIES}
-  test_tcp_server
   grpc_test_util
   grpc
   gpr_test_util
@@ -6741,12 +8038,12 @@ target_link_libraries(set_initial_connect_string_test
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 
-add_executable(slice_buffer_test
-  test/core/slice/slice_buffer_test.c
+add_executable(slice_hash_table_test
+  test/core/slice/slice_hash_table_test.c
 )
 
 
-target_include_directories(slice_buffer_test
+target_include_directories(slice_hash_table_test
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -6754,10 +8051,14 @@ target_include_directories(slice_buffer_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
-target_link_libraries(slice_buffer_test
+target_link_libraries(slice_hash_table_test
   ${_gRPC_ALLTARGETS_LIBRARIES}
   grpc_test_util
   grpc
@@ -6781,6 +8082,10 @@ target_include_directories(slice_string_helpers_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6808,6 +8113,10 @@ target_include_directories(slice_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6835,6 +8144,10 @@ target_include_directories(sockaddr_resolver_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6862,6 +8175,10 @@ target_include_directories(sockaddr_utils_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6890,6 +8207,10 @@ target_include_directories(socket_utils_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6918,6 +8239,10 @@ target_include_directories(status_conversion_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6929,6 +8254,37 @@ target_link_libraries(status_conversion_test
   gpr
 )
 
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(stream_owned_slice_test
+  test/core/transport/stream_owned_slice_test.c
+)
+
+
+target_include_directories(stream_owned_slice_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(stream_owned_slice_test
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@@ -6946,6 +8302,10 @@ target_include_directories(tcp_client_posix_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -6974,6 +8334,10 @@ target_include_directories(tcp_client_uv_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -7002,6 +8366,10 @@ target_include_directories(tcp_posix_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -7031,6 +8399,10 @@ target_include_directories(tcp_server_posix_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -7059,6 +8431,10 @@ target_include_directories(tcp_server_uv_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -7086,6 +8462,10 @@ target_include_directories(time_averaged_stats_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -7113,6 +8493,10 @@ target_include_directories(timeout_encoding_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -7140,6 +8524,10 @@ target_include_directories(timer_heap_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -7167,6 +8555,10 @@ target_include_directories(timer_list_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -7194,6 +8586,10 @@ target_include_directories(transport_connectivity_state_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -7221,6 +8617,10 @@ target_include_directories(transport_metadata_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -7248,27 +8648,289 @@ target_include_directories(transport_pid_controller_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(transport_pid_controller_test
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+
+add_executable(transport_security_test
+  test/core/tsi/transport_security_test.c
+)
+
+
+target_include_directories(transport_security_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
-target_link_libraries(transport_pid_controller_test
+target_link_libraries(transport_security_test
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif()
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+
+add_executable(udp_server_test
+  test/core/iomgr/udp_server_test.c
+)
+
+
+target_include_directories(udp_server_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(udp_server_test
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif()
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(uri_parser_test
+  test/core/client_channel/uri_parser_test.c
+)
+
+
+target_include_directories(uri_parser_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(uri_parser_test
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+
+add_executable(wakeup_fd_cv_test
+  test/core/iomgr/wakeup_fd_cv_test.c
+)
+
+
+target_include_directories(wakeup_fd_cv_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(wakeup_fd_cv_test
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif()
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(alarm_cpp_test
+  test/cpp/common/alarm_cpp_test.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(alarm_cpp_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(alarm_cpp_test
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(async_end2end_test
+  test/cpp/end2end/async_end2end_test.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(async_end2end_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(async_end2end_test
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(auth_property_iterator_test
+  test/cpp/common/auth_property_iterator_test.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(auth_property_iterator_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(auth_property_iterator_test
+  ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc++_test_util
   grpc_test_util
+  grpc++
   grpc
   gpr_test_util
   gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
 )
 
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
-add_executable(transport_security_test
-  test/core/tsi/transport_security_test.c
+add_executable(bm_arena
+  test/cpp/microbenchmarks/bm_arena.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
-target_include_directories(transport_security_test
+target_include_directories(bm_arena
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -7276,15 +8938,30 @@ target_include_directories(transport_security_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
-target_link_libraries(transport_security_test
+target_link_libraries(bm_arena
+  ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_benchmark
+  benchmark
+  grpc++_test_util
   grpc_test_util
+  grpc++
   grpc
   gpr_test_util
   gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
 )
 
 endif()
@@ -7292,12 +8969,14 @@ endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
-add_executable(udp_server_test
-  test/core/iomgr/udp_server_test.c
+add_executable(bm_call_create
+  test/cpp/microbenchmarks/bm_call_create.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
-target_include_directories(udp_server_test
+target_include_directories(bm_call_create
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -7305,27 +8984,45 @@ target_include_directories(udp_server_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
-target_link_libraries(udp_server_test
+target_link_libraries(bm_call_create
+  ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_benchmark
+  benchmark
+  grpc++_test_util
   grpc_test_util
+  grpc++
   grpc
   gpr_test_util
   gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
 )
 
 endif()
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
-add_executable(uri_parser_test
-  test/core/client_channel/uri_parser_test.c
+add_executable(bm_chttp2_hpack
+  test/cpp/microbenchmarks/bm_chttp2_hpack.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
-target_include_directories(uri_parser_test
+target_include_directories(bm_chttp2_hpack
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -7333,27 +9030,45 @@ target_include_directories(uri_parser_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
-target_link_libraries(uri_parser_test
+target_link_libraries(bm_chttp2_hpack
+  ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_benchmark
+  benchmark
+  grpc++_test_util
   grpc_test_util
+  grpc++
   grpc
   gpr_test_util
   gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
 )
 
+endif()
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
-add_executable(wakeup_fd_cv_test
-  test/core/iomgr/wakeup_fd_cv_test.c
+add_executable(bm_chttp2_transport
+  test/cpp/microbenchmarks/bm_chttp2_transport.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
-target_include_directories(wakeup_fd_cv_test
+target_include_directories(bm_chttp2_transport
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -7361,28 +9076,45 @@ target_include_directories(wakeup_fd_cv_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
-target_link_libraries(wakeup_fd_cv_test
+target_link_libraries(bm_chttp2_transport
+  ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_benchmark
+  benchmark
+  grpc++_test_util
   grpc_test_util
+  grpc++
   grpc
   gpr_test_util
   gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
 )
 
 endif()
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
-add_executable(alarm_cpp_test
-  test/cpp/common/alarm_cpp_test.cc
-  third_party/googletest/src/gtest-all.cc
+add_executable(bm_closure
+  test/cpp/microbenchmarks/bm_closure.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
-target_include_directories(alarm_cpp_test
+target_include_directories(bm_closure
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -7390,15 +9122,23 @@ target_include_directories(alarm_cpp_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
-target_link_libraries(alarm_cpp_test
+target_link_libraries(bm_closure
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_benchmark
+  benchmark
   grpc++_test_util
   grpc_test_util
   grpc++
@@ -7408,16 +9148,19 @@ target_link_libraries(alarm_cpp_test
   ${_gRPC_GFLAGS_LIBRARIES}
 )
 
+endif()
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
-add_executable(async_end2end_test
-  test/cpp/end2end/async_end2end_test.cc
-  third_party/googletest/src/gtest-all.cc
+add_executable(bm_cq
+  test/cpp/microbenchmarks/bm_cq.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
-target_include_directories(async_end2end_test
+target_include_directories(bm_cq
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -7425,15 +9168,23 @@ target_include_directories(async_end2end_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
-target_link_libraries(async_end2end_test
+target_link_libraries(bm_cq
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_benchmark
+  benchmark
   grpc++_test_util
   grpc_test_util
   grpc++
@@ -7443,16 +9194,19 @@ target_link_libraries(async_end2end_test
   ${_gRPC_GFLAGS_LIBRARIES}
 )
 
+endif()
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
-add_executable(auth_property_iterator_test
-  test/cpp/common/auth_property_iterator_test.cc
-  third_party/googletest/src/gtest-all.cc
+add_executable(bm_cq_multiple_threads
+  test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
-target_include_directories(auth_property_iterator_test
+target_include_directories(bm_cq_multiple_threads
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -7460,15 +9214,23 @@ target_include_directories(auth_property_iterator_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
-target_link_libraries(auth_property_iterator_test
+target_link_libraries(bm_cq_multiple_threads
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_benchmark
+  benchmark
   grpc++_test_util
   grpc_test_util
   grpc++
@@ -7478,17 +9240,19 @@ target_link_libraries(auth_property_iterator_test
   ${_gRPC_GFLAGS_LIBRARIES}
 )
 
+endif()
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
-add_executable(bm_call_create
-  test/cpp/microbenchmarks/bm_call_create.cc
-  third_party/googletest/src/gtest-all.cc
+add_executable(bm_error
+  test/cpp/microbenchmarks/bm_error.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
-target_include_directories(bm_call_create
+target_include_directories(bm_error
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -7496,15 +9260,22 @@ target_include_directories(bm_call_create
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
-target_link_libraries(bm_call_create
+target_link_libraries(bm_error
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_benchmark
   benchmark
   grpc++_test_util
   grpc_test_util
@@ -7520,13 +9291,14 @@ endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
-add_executable(bm_chttp2_hpack
-  test/cpp/microbenchmarks/bm_chttp2_hpack.cc
-  third_party/googletest/src/gtest-all.cc
+add_executable(bm_fullstack_streaming_ping_pong
+  test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
-target_include_directories(bm_chttp2_hpack
+target_include_directories(bm_fullstack_streaming_ping_pong
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -7534,15 +9306,22 @@ target_include_directories(bm_chttp2_hpack
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
-target_link_libraries(bm_chttp2_hpack
+target_link_libraries(bm_fullstack_streaming_ping_pong
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_benchmark
   benchmark
   grpc++_test_util
   grpc_test_util
@@ -7558,13 +9337,14 @@ endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
-add_executable(bm_closure
-  test/cpp/microbenchmarks/bm_closure.cc
-  third_party/googletest/src/gtest-all.cc
+add_executable(bm_fullstack_streaming_pump
+  test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
-target_include_directories(bm_closure
+target_include_directories(bm_fullstack_streaming_pump
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -7572,15 +9352,22 @@ target_include_directories(bm_closure
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
-target_link_libraries(bm_closure
+target_link_libraries(bm_fullstack_streaming_pump
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_benchmark
   benchmark
   grpc++_test_util
   grpc_test_util
@@ -7596,13 +9383,14 @@ endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
-add_executable(bm_cq
-  test/cpp/microbenchmarks/bm_cq.cc
-  third_party/googletest/src/gtest-all.cc
+add_executable(bm_fullstack_trickle
+  test/cpp/microbenchmarks/bm_fullstack_trickle.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
-target_include_directories(bm_cq
+target_include_directories(bm_fullstack_trickle
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -7610,15 +9398,22 @@ target_include_directories(bm_cq
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
-target_link_libraries(bm_cq
+target_link_libraries(bm_fullstack_trickle
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_benchmark
   benchmark
   grpc++_test_util
   grpc_test_util
@@ -7634,13 +9429,14 @@ endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
-add_executable(bm_error
-  test/cpp/microbenchmarks/bm_error.cc
-  third_party/googletest/src/gtest-all.cc
+add_executable(bm_fullstack_unary_ping_pong
+  test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
-target_include_directories(bm_error
+target_include_directories(bm_fullstack_unary_ping_pong
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -7648,15 +9444,22 @@ target_include_directories(bm_error
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
-target_link_libraries(bm_error
+target_link_libraries(bm_fullstack_unary_ping_pong
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_benchmark
   benchmark
   grpc++_test_util
   grpc_test_util
@@ -7672,13 +9475,14 @@ endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
-add_executable(bm_fullstack
-  test/cpp/microbenchmarks/bm_fullstack.cc
-  third_party/googletest/src/gtest-all.cc
+add_executable(bm_metadata
+  test/cpp/microbenchmarks/bm_metadata.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
-target_include_directories(bm_fullstack
+target_include_directories(bm_metadata
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -7686,15 +9490,22 @@ target_include_directories(bm_fullstack
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
-target_link_libraries(bm_fullstack
+target_link_libraries(bm_metadata
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_benchmark
   benchmark
   grpc++_test_util
   grpc_test_util
@@ -7710,13 +9521,14 @@ endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
-add_executable(bm_metadata
-  test/cpp/microbenchmarks/bm_metadata.cc
-  third_party/googletest/src/gtest-all.cc
+add_executable(bm_pollset
+  test/cpp/microbenchmarks/bm_pollset.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
-target_include_directories(bm_metadata
+target_include_directories(bm_pollset
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
@@ -7724,17 +9536,26 @@ target_include_directories(bm_metadata
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
-target_link_libraries(bm_metadata
+target_link_libraries(bm_pollset
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_benchmark
   benchmark
+  grpc++_test_util
   grpc_test_util
+  grpc++
   grpc
   gpr_test_util
   gpr
@@ -7747,7 +9568,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(channel_arguments_test
   test/cpp/common/channel_arguments_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -7759,9 +9581,15 @@ target_include_directories(channel_arguments_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -7779,7 +9607,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(channel_filter_test
   test/cpp/common/channel_filter_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -7791,9 +9620,15 @@ target_include_directories(channel_filter_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -7811,7 +9646,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(cli_call_test
   test/cpp/util/cli_call_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -7823,9 +9659,15 @@ target_include_directories(cli_call_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -7848,7 +9690,8 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 add_executable(client_crash_test
   test/cpp/end2end/client_crash_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -7860,9 +9703,15 @@ target_include_directories(client_crash_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -7884,7 +9733,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(client_crash_test_server
   test/cpp/end2end/client_crash_test_server.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -7896,9 +9746,15 @@ target_include_directories(client_crash_test_server
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -7939,7 +9795,8 @@ add_executable(codegen_test_full
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.pb.h
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.grpc.pb.h
   test/cpp/codegen/codegen_test_full.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 protobuf_generate_grpc_cpp(
@@ -7966,9 +9823,15 @@ target_include_directories(codegen_test_full
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8007,7 +9870,8 @@ add_executable(codegen_test_minimal
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.grpc.pb.h
   test/cpp/codegen/codegen_test_minimal.cc
   src/cpp/codegen/codegen_init.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 protobuf_generate_grpc_cpp(
@@ -8034,15 +9898,23 @@ target_include_directories(codegen_test_minimal
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
 target_link_libraries(codegen_test_minimal
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc
+  gpr
   ${_gRPC_GFLAGS_LIBRARIES}
 )
 
@@ -8051,7 +9923,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(credentials_test
   test/cpp/client/credentials_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -8063,9 +9936,15 @@ target_include_directories(credentials_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8083,7 +9962,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(cxx_byte_buffer_test
   test/cpp/util/byte_buffer_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -8095,9 +9975,15 @@ target_include_directories(cxx_byte_buffer_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8117,7 +10003,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(cxx_slice_test
   test/cpp/util/slice_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -8129,9 +10016,15 @@ target_include_directories(cxx_slice_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8151,7 +10044,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(cxx_string_ref_test
   test/cpp/util/string_ref_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -8163,9 +10057,15 @@ target_include_directories(cxx_string_ref_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8181,7 +10081,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(cxx_time_test
   test/cpp/util/time_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -8193,9 +10094,15 @@ target_include_directories(cxx_time_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8215,7 +10122,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(end2end_test
   test/cpp/end2end/end2end_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -8227,9 +10135,15 @@ target_include_directories(end2end_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8248,9 +10162,55 @@ target_link_libraries(end2end_test
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 
+add_executable(error_details_test
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h
+  test/cpp/util/error_details_test.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/echo_messages.proto
+)
+
+target_include_directories(error_details_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(error_details_test
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc++_error_details
+  grpc++
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
 add_executable(filter_end2end_test
   test/cpp/end2end/filter_end2end_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -8262,9 +10222,15 @@ target_include_directories(filter_end2end_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8285,7 +10251,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(generic_end2end_test
   test/cpp/end2end/generic_end2end_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -8297,9 +10264,15 @@ target_include_directories(generic_end2end_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8324,7 +10297,8 @@ add_executable(golden_file_test
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/compiler_test.pb.h
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/compiler_test.grpc.pb.h
   test/cpp/codegen/golden_file_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 protobuf_generate_grpc_cpp(
@@ -8339,9 +10313,15 @@ target_include_directories(golden_file_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8359,7 +10339,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(grpc_cli
   test/cpp/util/grpc_cli.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -8371,9 +10352,15 @@ target_include_directories(grpc_cli
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8404,6 +10391,10 @@ target_include_directories(grpc_cpp_plugin
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
@@ -8438,6 +10429,10 @@ target_include_directories(grpc_csharp_plugin
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
@@ -8472,6 +10467,10 @@ target_include_directories(grpc_node_plugin
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
@@ -8506,6 +10505,10 @@ target_include_directories(grpc_objective_c_plugin
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
@@ -8540,6 +10543,10 @@ target_include_directories(grpc_php_plugin
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
@@ -8574,6 +10581,10 @@ target_include_directories(grpc_python_plugin
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
@@ -8608,6 +10619,10 @@ target_include_directories(grpc_ruby_plugin
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
@@ -8640,7 +10655,8 @@ add_executable(grpc_tool_test
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h
   test/cpp/util/grpc_tool_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 protobuf_generate_grpc_cpp(
@@ -8658,9 +10674,15 @@ target_include_directories(grpc_tool_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8688,7 +10710,8 @@ add_executable(grpclb_api_test
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.h
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.h
   test/cpp/grpclb/grpclb_api_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 protobuf_generate_grpc_cpp(
@@ -8703,9 +10726,15 @@ target_include_directories(grpclb_api_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8722,13 +10751,63 @@ target_link_libraries(grpclb_api_test
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 
+add_executable(grpclb_end2end_test
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.h
+  test/cpp/end2end/grpclb_end2end_test.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/lb/v1/load_balancer.proto
+)
+
+target_include_directories(grpclb_end2end_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(grpclb_end2end_test
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
 add_executable(grpclb_test
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.h
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.h
   test/cpp/grpclb/grpclb_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 protobuf_generate_grpc_cpp(
@@ -8743,9 +10822,15 @@ target_include_directories(grpclb_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8766,7 +10851,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(health_service_end2end_test
   test/cpp/end2end/health_service_end2end_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -8778,9 +10864,15 @@ target_include_directories(health_service_end2end_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8801,7 +10893,8 @@ if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 add_executable(http2_client
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -8813,9 +10906,15 @@ target_include_directories(http2_client
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8837,7 +10936,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(hybrid_end2end_test
   test/cpp/end2end/hybrid_end2end_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -8849,9 +10949,15 @@ target_include_directories(hybrid_end2end_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8872,7 +10978,8 @@ if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 add_executable(interop_client
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -8884,9 +10991,15 @@ target_include_directories(interop_client
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8911,7 +11024,8 @@ if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 add_executable(interop_server
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -8923,9 +11037,15 @@ target_include_directories(interop_server
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8952,7 +11072,8 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 add_executable(interop_test
   test/cpp/interop/interop_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -8964,9 +11085,15 @@ target_include_directories(interop_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -8988,7 +11115,8 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 add_executable(json_run_localhost
   test/cpp/qps/json_run_localhost.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9000,9 +11128,15 @@ target_include_directories(json_run_localhost
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9023,13 +11157,55 @@ endif()
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 
+add_executable(memory_test
+  test/core/support/memory_test.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(memory_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(memory_test
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
 add_executable(metrics_client
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/metrics.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/metrics.grpc.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/metrics.pb.h
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/metrics.grpc.pb.h
   test/cpp/interop/metrics_client.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 protobuf_generate_grpc_cpp(
@@ -9044,9 +11220,15 @@ target_include_directories(metrics_client
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9065,7 +11247,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(mock_test
   test/cpp/end2end/mock_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9077,9 +11260,15 @@ target_include_directories(mock_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9100,7 +11289,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(noop-benchmark
   test/cpp/microbenchmarks/noop-benchmark.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9112,9 +11302,15 @@ target_include_directories(noop-benchmark
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9130,7 +11326,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(proto_server_reflection_test
   test/cpp/end2end/proto_server_reflection_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9142,9 +11339,15 @@ target_include_directories(proto_server_reflection_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9167,7 +11370,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(proto_utils_test
   test/cpp/codegen/proto_utils_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9179,9 +11383,15 @@ target_include_directories(proto_utils_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9199,7 +11409,8 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 add_executable(qps_interarrival_test
   test/cpp/qps/qps_interarrival_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9211,9 +11422,15 @@ target_include_directories(qps_interarrival_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9236,7 +11453,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(qps_json_driver
   test/cpp/qps/qps_json_driver.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9248,9 +11466,15 @@ target_include_directories(qps_json_driver
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9274,7 +11498,8 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 add_executable(qps_openloop_test
   test/cpp/qps/qps_openloop_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9286,9 +11511,15 @@ target_include_directories(qps_openloop_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9312,7 +11543,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(qps_worker
   test/cpp/qps/worker.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9324,9 +11556,15 @@ target_include_directories(qps_worker
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9361,7 +11599,8 @@ add_executable(reconnect_interop_client
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h
   test/cpp/interop/reconnect_interop_client.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 protobuf_generate_grpc_cpp(
@@ -9382,9 +11621,15 @@ target_include_directories(reconnect_interop_client
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9418,7 +11663,8 @@ add_executable(reconnect_interop_server
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h
   test/cpp/interop/reconnect_interop_server.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 protobuf_generate_grpc_cpp(
@@ -9439,9 +11685,15 @@ target_include_directories(reconnect_interop_server
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9465,7 +11717,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(round_robin_end2end_test
   test/cpp/end2end/round_robin_end2end_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9477,9 +11730,15 @@ target_include_directories(round_robin_end2end_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9500,7 +11759,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(secure_auth_context_test
   test/cpp/common/secure_auth_context_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9512,9 +11772,15 @@ target_include_directories(secure_auth_context_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9536,7 +11802,8 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 add_executable(secure_sync_unary_ping_pong_test
   test/cpp/qps/secure_sync_unary_ping_pong_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9548,9 +11815,15 @@ target_include_directories(secure_sync_unary_ping_pong_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9573,7 +11846,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(server_builder_plugin_test
   test/cpp/end2end/server_builder_plugin_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9585,9 +11859,15 @@ target_include_directories(server_builder_plugin_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9606,9 +11886,66 @@ target_link_libraries(server_builder_plugin_test
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 
+add_executable(server_builder_test
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h
+  test/cpp/server/server_builder_test.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/echo_messages.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/echo.proto
+)
+
+target_include_directories(server_builder_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(server_builder_test
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc++_test_util
+  grpc_test_util
+  gpr_test_util
+  grpc++
+  grpc
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
 add_executable(server_context_test_spouse_test
   test/cpp/test/server_context_test_spouse_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9620,9 +11957,15 @@ target_include_directories(server_context_test_spouse_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9643,7 +11986,8 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 add_executable(server_crash_test
   test/cpp/end2end/server_crash_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9655,9 +11999,15 @@ target_include_directories(server_crash_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9679,7 +12029,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(server_crash_test_client
   test/cpp/end2end/server_crash_test_client.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9691,9 +12042,15 @@ target_include_directories(server_crash_test_client
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9714,7 +12071,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(shutdown_test
   test/cpp/end2end/shutdown_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9726,9 +12084,15 @@ target_include_directories(shutdown_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9749,7 +12113,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(status_test
   test/cpp/util/status_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9761,9 +12126,15 @@ target_include_directories(status_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9784,7 +12155,8 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 add_executable(streaming_throughput_test
   test/cpp/end2end/streaming_throughput_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9796,9 +12168,15 @@ target_include_directories(streaming_throughput_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9838,9 +12216,9 @@ add_executable(stress_test
   test/cpp/interop/interop_client.cc
   test/cpp/interop/stress_interop_client.cc
   test/cpp/interop/stress_test.cc
-  test/cpp/util/create_test_channel.cc
   test/cpp/util/metrics_server.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 protobuf_generate_grpc_cpp(
@@ -9864,9 +12242,15 @@ target_include_directories(stress_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9888,7 +12272,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(thread_manager_test
   test/cpp/thread_manager/thread_manager_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9900,9 +12285,15 @@ target_include_directories(thread_manager_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9921,7 +12312,8 @@ if (gRPC_BUILD_TESTS)
 
 add_executable(thread_stress_test
   test/cpp/end2end/thread_stress_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9933,9 +12325,15 @@ target_include_directories(thread_stress_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -9957,7 +12355,8 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 add_executable(writes_per_rpc_test
   test/cpp/performance/writes_per_rpc_test.cc
-  third_party/googletest/src/gtest-all.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
 )
 
 
@@ -9969,9 +12368,15 @@ target_include_directories(writes_per_rpc_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
-  PRIVATE third_party/googletest/include
-  PRIVATE third_party/googletest
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
   PRIVATE ${_gRPC_PROTO_GENS_DIR}
 )
 
@@ -10004,6 +12409,10 @@ target_include_directories(public_headers_must_be_c89
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10029,6 +12438,10 @@ target_include_directories(badreq_bad_client_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10058,6 +12471,10 @@ target_include_directories(connection_prefix_bad_client_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10087,6 +12504,10 @@ target_include_directories(head_of_line_blocking_bad_client_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10116,6 +12537,10 @@ target_include_directories(headers_bad_client_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10145,6 +12570,10 @@ target_include_directories(initial_settings_frame_bad_client_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10174,6 +12603,10 @@ target_include_directories(large_metadata_bad_client_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10203,6 +12636,10 @@ target_include_directories(server_registered_method_bad_client_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10232,6 +12669,10 @@ target_include_directories(simple_request_bad_client_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10261,6 +12702,10 @@ target_include_directories(unknown_frame_bad_client_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10290,6 +12735,10 @@ target_include_directories(window_overflow_bad_client_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10320,6 +12769,10 @@ target_include_directories(bad_ssl_cert_server
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10350,6 +12803,10 @@ target_include_directories(bad_ssl_cert_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10378,6 +12835,10 @@ target_include_directories(h2_census_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10406,6 +12867,10 @@ target_include_directories(h2_compress_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10434,6 +12899,10 @@ target_include_directories(h2_fakesec_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10463,6 +12932,10 @@ target_include_directories(h2_fd_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10492,6 +12965,10 @@ target_include_directories(h2_full_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10521,6 +12998,10 @@ target_include_directories(h2_full+pipe_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10550,6 +13031,10 @@ target_include_directories(h2_full+trace_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10578,6 +13063,10 @@ target_include_directories(h2_http_proxy_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10606,6 +13095,10 @@ target_include_directories(h2_load_reporting_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10634,6 +13127,10 @@ target_include_directories(h2_oauth2_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10662,6 +13159,10 @@ target_include_directories(h2_proxy_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10690,6 +13191,10 @@ target_include_directories(h2_sockpair_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10718,6 +13223,10 @@ target_include_directories(h2_sockpair+trace_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10746,6 +13255,10 @@ target_include_directories(h2_sockpair_1byte_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10774,6 +13287,10 @@ target_include_directories(h2_ssl_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10802,6 +13319,10 @@ target_include_directories(h2_ssl_cert_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10830,6 +13351,10 @@ target_include_directories(h2_ssl_proxy_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10859,6 +13384,10 @@ target_include_directories(h2_uds_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10888,6 +13417,10 @@ target_include_directories(h2_census_nosec_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10916,6 +13449,10 @@ target_include_directories(h2_compress_nosec_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10945,6 +13482,10 @@ target_include_directories(h2_fd_nosec_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -10974,6 +13515,10 @@ target_include_directories(h2_full_nosec_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11003,6 +13548,10 @@ target_include_directories(h2_full+pipe_nosec_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11032,6 +13581,10 @@ target_include_directories(h2_full+trace_nosec_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11060,6 +13613,10 @@ target_include_directories(h2_http_proxy_nosec_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11088,6 +13645,10 @@ target_include_directories(h2_load_reporting_nosec_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11116,6 +13677,10 @@ target_include_directories(h2_proxy_nosec_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11144,6 +13709,10 @@ target_include_directories(h2_sockpair_nosec_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11172,6 +13741,10 @@ target_include_directories(h2_sockpair+trace_nosec_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11200,6 +13773,10 @@ target_include_directories(h2_sockpair_1byte_nosec_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11229,6 +13806,10 @@ target_include_directories(h2_uds_nosec_test
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11259,6 +13840,10 @@ target_include_directories(api_fuzzer_one_entry
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11287,6 +13872,10 @@ target_include_directories(client_fuzzer_one_entry
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11315,6 +13904,10 @@ target_include_directories(hpack_parser_fuzzer_test_one_entry
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11343,6 +13936,10 @@ target_include_directories(http_request_fuzzer_test_one_entry
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11371,6 +13968,10 @@ target_include_directories(http_response_fuzzer_test_one_entry
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11399,6 +14000,10 @@ target_include_directories(json_fuzzer_test_one_entry
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11427,6 +14032,10 @@ target_include_directories(nanopb_fuzzer_response_test_one_entry
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11455,6 +14064,10 @@ target_include_directories(nanopb_fuzzer_serverlist_test_one_entry
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11483,6 +14096,10 @@ target_include_directories(percent_decode_fuzzer_one_entry
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11511,6 +14128,10 @@ target_include_directories(percent_encode_fuzzer_one_entry
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11539,6 +14160,10 @@ target_include_directories(server_fuzzer_one_entry
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11567,6 +14192,10 @@ target_include_directories(ssl_server_fuzzer_one_entry
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
@@ -11595,6 +14224,10 @@ target_include_directories(uri_fuzzer_test_one_entry
   PRIVATE ${BENCHMARK_ROOT_DIR}/include
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
diff --git a/INSTALL.md b/INSTALL.md
index 24f088ea4926dd93132c15faa08a3307de82781d..6cfa1b6cbaf34ad1c9b6557cf2b75e159ebd611d 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -1,4 +1,4 @@
-#If you are in a hurry
+# If you are in a hurry
 
 For language-specific installation instructions for gRPC runtime, please
 refer to these documents
@@ -14,25 +14,44 @@ refer to these documents
  * [Ruby](src/ruby): `gem install grpc`
 
 
-#Pre-requisites
+# Pre-requisites
 
-##Linux
+## Linux
 
 ```sh
  $ [sudo] apt-get install build-essential autoconf libtool
 ```
 
-##Mac OSX
+If you plan to build from source and run tests, install the following as well:
+```sh
+ $ [sudo] apt-get install libgflags-dev libgtest-dev
+ $ [sudo] apt-get install clang libc++-dev
+```
+
+## macOS 
 
-For a Mac system, git is not available by default. You will first need to
-install Xcode from the Mac AppStore and then run the following command from a
-terminal:
+On a Mac, you will first need to
+install Xcode or
+[Command Line Tools for Xcode](https://developer.apple.com/download/more/)
+and then run the following command from a terminal:
 
 ```sh
  $ [sudo] xcode-select --install
 ```
 
-##Protoc
+To build gRPC from source, you may also need to install the following
+packages, which you can get from [Homebrew](https://brew.sh):
+
+```sh
+ $ brew install autoconf automake libtool shtool
+```
+
+If you plan to build from source and run tests, install the following as well:
+```sh
+ $ brew install gflags
+```
+
+## Protoc
 
 By default gRPC uses [protocol buffers](https://github.com/google/protobuf),
 you will need the `protoc` compiler to generate stub server and client code.
@@ -43,7 +62,7 @@ repository recursively and it detects that you don't already have it
 installed.
 
 
-#Build from Source
+# Build from Source
 
 For developers who are interested to contribute, here is how to compile the
 gRPC C Core library.
@@ -56,16 +75,16 @@ gRPC C Core library.
  $ [sudo] make install
 ```
 
-##Windows
+## Windows
 
 There are several ways to build under Windows, of varying complexity depending
 on experience with the tools involved.
 
-###Pre-generated Visual Studio solution
+### Pre-generated Visual Studio solution
 
 The pre-generated VS projects & solution are checked into the repository under the [vsprojects](/vsprojects) directory.
-  
-###Building using CMake (with BoringSSL)
+
+### Building using CMake (with BoringSSL)
 - Install [CMake](https://cmake.org/download/).
 - Install [Active State Perl](http://www.activestate.com/activeperl/) (`choco install activeperl`)
 - Install [Ninja](https://ninja-build.org/) (`choco install ninja`)
@@ -81,14 +100,14 @@ The pre-generated VS projects & solution are checked into the repository under t
 ```
 NOTE: Currently you can only use Ninja to build using cmake on Windows (because of the boringssl dependency).
 
-###msys2 (with mingw)
+### msys2 (with mingw)
 
 The Makefile (and source code) should support msys2's mingw32 and mingw64
 compilers. Building with msys2's native compiler is also possible, but
 difficult.
 
 This approach requires having [msys2](https://msys2.github.io/) installed.
-  
+
 ```
 # Install prerequisites
 MSYS2$ pacman -S autoconf automake gcc libtool mingw-w64-x86_64-toolchain perl pkg-config zlib
diff --git a/Makefile b/Makefile
index c16b4ff8ea6bb954104717388bc34a296b733f61..1a8ee553ca3c14f30533cb7fd2dc0f960b6af06a 100644
--- a/Makefile
+++ b/Makefile
@@ -92,9 +92,47 @@ CC_opt = $(DEFAULT_CC)
 CXX_opt = $(DEFAULT_CXX)
 LD_opt = $(DEFAULT_CC)
 LDXX_opt = $(DEFAULT_CXX)
+CXXFLAGS_opt = -fno-exceptions
 CPPFLAGS_opt = -O2
 DEFINES_opt = NDEBUG
 
+VALID_CONFIG_asan-trace-cmp = 1
+REQUIRE_CUSTOM_LIBRARIES_asan-trace-cmp = 1
+CC_asan-trace-cmp = clang
+CXX_asan-trace-cmp = clang++
+LD_asan-trace-cmp = clang++
+LDXX_asan-trace-cmp = clang++
+CPPFLAGS_asan-trace-cmp = -O0 -fsanitize-coverage=edge -fsanitize-coverage=trace-cmp -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
+LDFLAGS_asan-trace-cmp = -fsanitize=address
+
+VALID_CONFIG_dbg = 1
+CC_dbg = $(DEFAULT_CC)
+CXX_dbg = $(DEFAULT_CXX)
+LD_dbg = $(DEFAULT_CC)
+LDXX_dbg = $(DEFAULT_CXX)
+CXXFLAGS_dbg = -fno-exceptions
+CPPFLAGS_dbg = -O0
+DEFINES_dbg = _DEBUG DEBUG
+
+VALID_CONFIG_asan = 1
+REQUIRE_CUSTOM_LIBRARIES_asan = 1
+CC_asan = clang
+CXX_asan = clang++
+LD_asan = clang++
+LDXX_asan = clang++
+CPPFLAGS_asan = -O0 -fsanitize-coverage=edge -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
+LDFLAGS_asan = -fsanitize=address
+
+VALID_CONFIG_msan = 1
+REQUIRE_CUSTOM_LIBRARIES_msan = 1
+CC_msan = clang
+CXX_msan = clang++
+LD_msan = clang++
+LDXX_msan = clang++
+CPPFLAGS_msan = -O0 -fsanitize-coverage=edge -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
+
 VALID_CONFIG_basicprof = 1
 CC_basicprof = $(DEFAULT_CC)
 CXX_basicprof = $(DEFAULT_CXX)
@@ -116,27 +154,39 @@ VALID_CONFIG_asan-noleaks = 1
 REQUIRE_CUSTOM_LIBRARIES_asan-noleaks = 1
 CC_asan-noleaks = clang
 CXX_asan-noleaks = clang++
-LD_asan-noleaks = clang
+LD_asan-noleaks = clang++
 LDXX_asan-noleaks = clang++
 CPPFLAGS_asan-noleaks = -O0 -fsanitize-coverage=edge -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
 LDFLAGS_asan-noleaks = -fsanitize=address
 
-VALID_CONFIG_asan-trace-cmp = 1
-REQUIRE_CUSTOM_LIBRARIES_asan-trace-cmp = 1
-CC_asan-trace-cmp = clang
-CXX_asan-trace-cmp = clang++
-LD_asan-trace-cmp = clang
-LDXX_asan-trace-cmp = clang++
-CPPFLAGS_asan-trace-cmp = -O0 -fsanitize-coverage=edge -fsanitize-coverage=trace-cmp -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
-LDFLAGS_asan-trace-cmp = -fsanitize=address
+VALID_CONFIG_c++-compat = 1
+CC_c++-compat = $(DEFAULT_CC)
+CXX_c++-compat = $(DEFAULT_CXX)
+LD_c++-compat = $(DEFAULT_CC)
+LDXX_c++-compat = $(DEFAULT_CXX)
+CFLAGS_c++-compat = -Wc++-compat
+CPPFLAGS_c++-compat = -O0
+DEFINES_c++-compat = _DEBUG DEBUG
 
-VALID_CONFIG_dbg = 1
-CC_dbg = $(DEFAULT_CC)
-CXX_dbg = $(DEFAULT_CXX)
-LD_dbg = $(DEFAULT_CC)
-LDXX_dbg = $(DEFAULT_CXX)
-CPPFLAGS_dbg = -O0
-DEFINES_dbg = _DEBUG DEBUG
+VALID_CONFIG_ubsan = 1
+REQUIRE_CUSTOM_LIBRARIES_ubsan = 1
+CC_ubsan = clang
+CXX_ubsan = clang++
+LD_ubsan = clang++
+LDXX_ubsan = clang++
+CPPFLAGS_ubsan = -O0 -fsanitize-coverage=edge -fsanitize=undefined -fno-omit-frame-pointer -Wno-unused-command-line-argument -Wvarargs
+LDFLAGS_ubsan = -fsanitize=undefined,unsigned-integer-overflow
+DEFINES_ubsan = NDEBUG GRPC_UBSAN
+
+VALID_CONFIG_tsan = 1
+REQUIRE_CUSTOM_LIBRARIES_tsan = 1
+CC_tsan = clang
+CXX_tsan = clang++
+LD_tsan = clang++
+LDXX_tsan = clang++
+CPPFLAGS_tsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
+LDFLAGS_tsan = -fsanitize=thread
+DEFINES_tsan = GRPC_TSAN
 
 VALID_CONFIG_stapprof = 1
 CC_stapprof = $(DEFAULT_CC)
@@ -164,44 +214,13 @@ CPPFLAGS_memcheck = -O0
 LDFLAGS_memcheck = -rdynamic
 DEFINES_memcheck = _DEBUG DEBUG
 
-VALID_CONFIG_asan = 1
-REQUIRE_CUSTOM_LIBRARIES_asan = 1
-CC_asan = clang
-CXX_asan = clang++
-LD_asan = clang
-LDXX_asan = clang++
-CPPFLAGS_asan = -O0 -fsanitize-coverage=edge -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
-LDFLAGS_asan = -fsanitize=address
-
-VALID_CONFIG_tsan = 1
-REQUIRE_CUSTOM_LIBRARIES_tsan = 1
-CC_tsan = clang
-CXX_tsan = clang++
-LD_tsan = clang
-LDXX_tsan = clang++
-CPPFLAGS_tsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
-LDFLAGS_tsan = -fsanitize=thread
-DEFINES_tsan = GRPC_TSAN
-
-VALID_CONFIG_ubsan = 1
-REQUIRE_CUSTOM_LIBRARIES_ubsan = 1
-CC_ubsan = clang
-CXX_ubsan = clang++
-LD_ubsan = clang
-LDXX_ubsan = clang++
-CPPFLAGS_ubsan = -O0 -fsanitize-coverage=edge -fsanitize=undefined,unsigned-integer-overflow -fno-omit-frame-pointer -Wno-unused-command-line-argument -Wvarargs
-LDFLAGS_ubsan = -fsanitize=undefined,unsigned-integer-overflow
-DEFINES_ubsan = NDEBUG
-
-VALID_CONFIG_msan = 1
-REQUIRE_CUSTOM_LIBRARIES_msan = 1
-CC_msan = clang
-CXX_msan = clang++
-LD_msan = clang
-LDXX_msan = clang++
-CPPFLAGS_msan = -O0 -fsanitize-coverage=edge -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
+VALID_CONFIG_lto = 1
+CC_lto = $(DEFAULT_CC)
+CXX_lto = $(DEFAULT_CXX)
+LD_lto = $(DEFAULT_CC)
+LDXX_lto = $(DEFAULT_CXX)
+CPPFLAGS_lto = -O2
+DEFINES_lto = NDEBUG
 
 VALID_CONFIG_mutrace = 1
 CC_mutrace = $(DEFAULT_CC)
@@ -401,7 +420,7 @@ AROPTS = $(GRPC_CROSS_AROPTS) # e.g., rc --target=elf32-little
 USE_BUILT_PROTOC = false
 endif
 
-GTEST_LIB = -Ithird_party/googletest/include -Ithird_party/googletest third_party/googletest/src/gtest-all.cc
+GTEST_LIB = -Ithird_party/googletest/googletest/include -Ithird_party/googletest/googletest third_party/googletest/googletest/src/gtest-all.cc -Ithird_party/googletest/googlemock/include -Ithird_party/googletest/googlemock third_party/googletest/googlemock/src/gmock-all.cc
 GTEST_LIB += -lgflags
 ifeq ($(V),1)
 E = @:
@@ -411,9 +430,9 @@ E = @echo
 Q = @
 endif
 
-CORE_VERSION = 3.0.0-dev
-CPP_VERSION = 1.2.0-dev
-CSHARP_VERSION = 1.2.0-dev
+CORE_VERSION = 4.0.0-dev
+CPP_VERSION = 1.4.0-dev
+CSHARP_VERSION = 1.4.0-dev
 
 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
 CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -461,11 +480,11 @@ SHARED_EXT_CORE = dll
 SHARED_EXT_CPP = dll
 SHARED_EXT_CSHARP = dll
 SHARED_PREFIX =
-SHARED_VERSION_CORE = -3
+SHARED_VERSION_CORE = -4
 SHARED_VERSION_CPP = -1
 SHARED_VERSION_CSHARP = -1
 else ifeq ($(SYSTEM),Darwin)
-EXECUTABLE_SUFFIX = 
+EXECUTABLE_SUFFIX =
 SHARED_EXT_CORE = dylib
 SHARED_EXT_CPP = dylib
 SHARED_EXT_CSHARP = dylib
@@ -474,7 +493,7 @@ SHARED_VERSION_CORE =
 SHARED_VERSION_CPP =
 SHARED_VERSION_CSHARP =
 else
-EXECUTABLE_SUFFIX = 
+EXECUTABLE_SUFFIX =
 SHARED_EXT_CORE = so.$(CORE_VERSION)
 SHARED_EXT_CPP = so.$(CPP_VERSION)
 SHARED_EXT_CSHARP = so.$(CSHARP_VERSION)
@@ -495,6 +514,7 @@ OPENSSL_ALPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.2 openssl
 OPENSSL_NPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.1 openssl
 ZLIB_CHECK_CMD = $(PKG_CONFIG) --exists zlib
 PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.0.0 protobuf
+CARES_CHECK_CMD = $(PKG_CONFIG) --exists libcares
 else # HAS_PKG_CONFIG
 
 ifeq ($(SYSTEM),MINGW32)
@@ -508,6 +528,7 @@ OPENSSL_NPN_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/open
 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 $(NO_W_EXTRA_SEMI) -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)
+CARES_CHECK_CMD = $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $(TMPOUT) test/build/c-ares.c -lcares $(LDFLAGS)
 
 endif # HAS_PKG_CONFIG
 
@@ -547,12 +568,17 @@ HAS_SYSTEM_PROTOBUF ?= $(HAS_SYSTEM_PROTOBUF_VERIFY)
 ifeq ($(HAS_SYSTEM_PROTOBUF),true)
 CACHE_MK += HAS_SYSTEM_PROTOBUF = true,
 endif
+HAS_SYSTEM_CARES ?=  $(shell $(CARES_CHECK_CMD) 2> /dev/null && echo true || echo false)
+ifeq ($(HAS_SYSTEM_CARES),true)
+CACHE_MK += HAS_SYSTEM_CARES = true,
+endif
 else
 # override system libraries if the config requires a custom compiled library
 HAS_SYSTEM_OPENSSL_ALPN = false
 HAS_SYSTEM_OPENSSL_NPN = false
 HAS_SYSTEM_ZLIB = false
 HAS_SYSTEM_PROTOBUF = false
+HAS_SYSTEM_CARES = false
 endif
 
 HAS_PROTOC ?= $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false)
@@ -611,6 +637,12 @@ else
 HAS_EMBEDDED_PROTOBUF = true
 endif
 
+ifeq ($(wildcard third_party/cares/cares/ares.h),)
+HAS_EMBEDDED_CARES = false
+else
+HAS_EMBEDDED_CARES = true
+endif
+
 PC_REQUIRES_GRPC =
 PC_LIBS_GRPC =
 
@@ -643,6 +675,37 @@ LIBS += z
 endif
 endif
 
+CARES_PKG_CONFIG = false
+
+ifeq ($(HAS_SYSTEM_CARES),false)
+ifeq ($(HAS_EMBEDDED_CARES), true)
+EMBED_CARES ?= true
+else
+DEP_MISSING += cares
+EMBED_CARES ?= broken
+endif
+else
+EMBED_CARES ?= false
+endif
+
+ifeq ($(EMBED_CARES),true)
+CARES_DEP = $(LIBDIR)/$(CONFIG)/libares.a
+CARES_MERGE_OBJS = $(LIBARES_OBJS)
+CARES_MERGE_LIBS = $(LIBDIR)/$(CONFIG)/libares.a
+CPPFLAGS := -Ithird_party/cares -Ithird_party/cares/cares $(CPPFLAGS)
+LDFLAGS := -L$(LIBDIR)/$(CONFIG)/c-ares $(LDFLAGS)
+else
+ifeq ($(HAS_PKG_CONFIG),true)
+PC_REQUIRES_GRPC += libcares
+CPPFLAGS += $(shell $(PKG_CONFIG) --cflags libcares)
+LDFLAGS += $(shell $(PKG_CONFIG) --libs-only-L libcares)
+LIBS += $(patsubst -l%,%,$(shell $(PKG_CONFIG) --libs-only-l libcares))
+else
+PC_LIBS_GRPC += -lcares
+LIBS += cares
+endif
+endif
+
 OPENSSL_PKG_CONFIG = false
 
 PC_REQUIRES_SECURE =
@@ -732,7 +795,7 @@ PROTOBUF_PKG_CONFIG = false
 PC_REQUIRES_GRPCXX =
 PC_LIBS_GRPCXX =
 
-CPPFLAGS := -Ithird_party/googletest/include $(CPPFLAGS)
+CPPFLAGS := -Ithird_party/googletest/googletest/include -Ithird_party/googletest/googlemock/include $(CPPFLAGS)
 
 PROTOC_PLUGINS_ALL = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_csharp_plugin $(BINDIR)/$(CONFIG)/grpc_node_plugin $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin $(BINDIR)/$(CONFIG)/grpc_php_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
 PROTOC_PLUGINS_DIR = $(BINDIR)/$(CONFIG)
@@ -906,6 +969,7 @@ algorithm_test: $(BINDIR)/$(CONFIG)/algorithm_test
 alloc_test: $(BINDIR)/$(CONFIG)/alloc_test
 alpn_test: $(BINDIR)/$(CONFIG)/alpn_test
 api_fuzzer: $(BINDIR)/$(CONFIG)/api_fuzzer
+arena_test: $(BINDIR)/$(CONFIG)/arena_test
 bad_server_response_test: $(BINDIR)/$(CONFIG)/bad_server_response_test
 bdp_estimator_test: $(BINDIR)/$(CONFIG)/bdp_estimator_test
 bin_decoder_test: $(BINDIR)/$(CONFIG)/bin_decoder_test
@@ -926,7 +990,9 @@ dns_resolver_connectivity_test: $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_te
 dns_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_test
 dualstack_socket_test: $(BINDIR)/$(CONFIG)/dualstack_socket_test
 endpoint_pair_test: $(BINDIR)/$(CONFIG)/endpoint_pair_test
+error_test: $(BINDIR)/$(CONFIG)/error_test
 ev_epoll_linux_test: $(BINDIR)/$(CONFIG)/ev_epoll_linux_test
+fake_resolver_test: $(BINDIR)/$(CONFIG)/fake_resolver_test
 fd_conservation_posix_test: $(BINDIR)/$(CONFIG)/fd_conservation_posix_test
 fd_posix_test: $(BINDIR)/$(CONFIG)/fd_posix_test
 fling_client: $(BINDIR)/$(CONFIG)/fling_client
@@ -996,12 +1062,14 @@ memory_profile_client: $(BINDIR)/$(CONFIG)/memory_profile_client
 memory_profile_server: $(BINDIR)/$(CONFIG)/memory_profile_server
 memory_profile_test: $(BINDIR)/$(CONFIG)/memory_profile_test
 message_compress_test: $(BINDIR)/$(CONFIG)/message_compress_test
+minimal_stack_is_minimal_test: $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_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
 nanopb_fuzzer_response_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test
 nanopb_fuzzer_serverlist_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test
 no_server_test: $(BINDIR)/$(CONFIG)/no_server_test
+parse_address_test: $(BINDIR)/$(CONFIG)/parse_address_test
 percent_decode_fuzzer: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer
 percent_encode_fuzzer: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer
 percent_encoding_test: $(BINDIR)/$(CONFIG)/percent_encoding_test
@@ -1015,8 +1083,8 @@ sequential_connectivity_test: $(BINDIR)/$(CONFIG)/sequential_connectivity_test
 server_chttp2_test: $(BINDIR)/$(CONFIG)/server_chttp2_test
 server_fuzzer: $(BINDIR)/$(CONFIG)/server_fuzzer
 server_test: $(BINDIR)/$(CONFIG)/server_test
-set_initial_connect_string_test: $(BINDIR)/$(CONFIG)/set_initial_connect_string_test
 slice_buffer_test: $(BINDIR)/$(CONFIG)/slice_buffer_test
+slice_hash_table_test: $(BINDIR)/$(CONFIG)/slice_hash_table_test
 slice_string_helpers_test: $(BINDIR)/$(CONFIG)/slice_string_helpers_test
 slice_test: $(BINDIR)/$(CONFIG)/slice_test
 sockaddr_resolver_test: $(BINDIR)/$(CONFIG)/sockaddr_resolver_test
@@ -1024,6 +1092,7 @@ sockaddr_utils_test: $(BINDIR)/$(CONFIG)/sockaddr_utils_test
 socket_utils_test: $(BINDIR)/$(CONFIG)/socket_utils_test
 ssl_server_fuzzer: $(BINDIR)/$(CONFIG)/ssl_server_fuzzer
 status_conversion_test: $(BINDIR)/$(CONFIG)/status_conversion_test
+stream_owned_slice_test: $(BINDIR)/$(CONFIG)/stream_owned_slice_test
 tcp_client_posix_test: $(BINDIR)/$(CONFIG)/tcp_client_posix_test
 tcp_client_uv_test: $(BINDIR)/$(CONFIG)/tcp_client_uv_test
 tcp_posix_test: $(BINDIR)/$(CONFIG)/tcp_posix_test
@@ -1044,13 +1113,20 @@ wakeup_fd_cv_test: $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test
 alarm_cpp_test: $(BINDIR)/$(CONFIG)/alarm_cpp_test
 async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test
 auth_property_iterator_test: $(BINDIR)/$(CONFIG)/auth_property_iterator_test
+bm_arena: $(BINDIR)/$(CONFIG)/bm_arena
 bm_call_create: $(BINDIR)/$(CONFIG)/bm_call_create
 bm_chttp2_hpack: $(BINDIR)/$(CONFIG)/bm_chttp2_hpack
+bm_chttp2_transport: $(BINDIR)/$(CONFIG)/bm_chttp2_transport
 bm_closure: $(BINDIR)/$(CONFIG)/bm_closure
 bm_cq: $(BINDIR)/$(CONFIG)/bm_cq
+bm_cq_multiple_threads: $(BINDIR)/$(CONFIG)/bm_cq_multiple_threads
 bm_error: $(BINDIR)/$(CONFIG)/bm_error
-bm_fullstack: $(BINDIR)/$(CONFIG)/bm_fullstack
+bm_fullstack_streaming_ping_pong: $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong
+bm_fullstack_streaming_pump: $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump
+bm_fullstack_trickle: $(BINDIR)/$(CONFIG)/bm_fullstack_trickle
+bm_fullstack_unary_ping_pong: $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong
 bm_metadata: $(BINDIR)/$(CONFIG)/bm_metadata
+bm_pollset: $(BINDIR)/$(CONFIG)/bm_pollset
 channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test
 channel_filter_test: $(BINDIR)/$(CONFIG)/channel_filter_test
 cli_call_test: $(BINDIR)/$(CONFIG)/cli_call_test
@@ -1064,6 +1140,7 @@ cxx_slice_test: $(BINDIR)/$(CONFIG)/cxx_slice_test
 cxx_string_ref_test: $(BINDIR)/$(CONFIG)/cxx_string_ref_test
 cxx_time_test: $(BINDIR)/$(CONFIG)/cxx_time_test
 end2end_test: $(BINDIR)/$(CONFIG)/end2end_test
+error_details_test: $(BINDIR)/$(CONFIG)/error_details_test
 filter_end2end_test: $(BINDIR)/$(CONFIG)/filter_end2end_test
 generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test
 golden_file_test: $(BINDIR)/$(CONFIG)/golden_file_test
@@ -1077,6 +1154,7 @@ grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin
 grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
 grpc_tool_test: $(BINDIR)/$(CONFIG)/grpc_tool_test
 grpclb_api_test: $(BINDIR)/$(CONFIG)/grpclb_api_test
+grpclb_end2end_test: $(BINDIR)/$(CONFIG)/grpclb_end2end_test
 grpclb_test: $(BINDIR)/$(CONFIG)/grpclb_test
 health_service_end2end_test: $(BINDIR)/$(CONFIG)/health_service_end2end_test
 http2_client: $(BINDIR)/$(CONFIG)/http2_client
@@ -1085,6 +1163,7 @@ interop_client: $(BINDIR)/$(CONFIG)/interop_client
 interop_server: $(BINDIR)/$(CONFIG)/interop_server
 interop_test: $(BINDIR)/$(CONFIG)/interop_test
 json_run_localhost: $(BINDIR)/$(CONFIG)/json_run_localhost
+memory_test: $(BINDIR)/$(CONFIG)/memory_test
 metrics_client: $(BINDIR)/$(CONFIG)/metrics_client
 mock_test: $(BINDIR)/$(CONFIG)/mock_test
 noop-benchmark: $(BINDIR)/$(CONFIG)/noop-benchmark
@@ -1100,6 +1179,7 @@ round_robin_end2end_test: $(BINDIR)/$(CONFIG)/round_robin_end2end_test
 secure_auth_context_test: $(BINDIR)/$(CONFIG)/secure_auth_context_test
 secure_sync_unary_ping_pong_test: $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test
 server_builder_plugin_test: $(BINDIR)/$(CONFIG)/server_builder_plugin_test
+server_builder_test: $(BINDIR)/$(CONFIG)/server_builder_test
 server_context_test_spouse_test: $(BINDIR)/$(CONFIG)/server_context_test_spouse_test
 server_crash_test: $(BINDIR)/$(CONFIG)/server_crash_test
 server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client
@@ -1221,6 +1301,7 @@ run_dep_checks:
 	$(PERFTOOLS_CHECK_CMD) || true
 	$(PROTOBUF_CHECK_CMD) || true
 	$(PROTOC_CHECK_VERSION_CMD) || true
+	$(CARES_CHECK_CMD) || true
 
 third_party/protobuf/configure:
 	$(E) "[AUTOGEN] Preparing protobuf"
@@ -1241,12 +1322,12 @@ static: static_c static_cxx
 
 static_c: pc_c pc_c_unsecure cache.mk  $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
 
-static_cxx: pc_cxx pc_cxx_unsecure cache.mk  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
+static_cxx: pc_cxx pc_cxx_unsecure cache.mk  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
 
 shared: shared_c shared_cxx
 
 shared_c: pc_c pc_c_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
-shared_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
+shared_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 
 shared_csharp: shared_c  $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP)
 grpc_csharp_ext: shared_csharp
@@ -1255,7 +1336,7 @@ plugins: $(PROTOC_PLUGINS)
 
 privatelibs: privatelibs_c privatelibs_cxx
 
-privatelibs_c:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a
+privatelibs_c:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a
 pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc
 
 pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc
@@ -1278,6 +1359,7 @@ buildtests_c: privatelibs_c \
   $(BINDIR)/$(CONFIG)/algorithm_test \
   $(BINDIR)/$(CONFIG)/alloc_test \
   $(BINDIR)/$(CONFIG)/alpn_test \
+  $(BINDIR)/$(CONFIG)/arena_test \
   $(BINDIR)/$(CONFIG)/bad_server_response_test \
   $(BINDIR)/$(CONFIG)/bdp_estimator_test \
   $(BINDIR)/$(CONFIG)/bin_decoder_test \
@@ -1297,7 +1379,9 @@ buildtests_c: privatelibs_c \
   $(BINDIR)/$(CONFIG)/dns_resolver_test \
   $(BINDIR)/$(CONFIG)/dualstack_socket_test \
   $(BINDIR)/$(CONFIG)/endpoint_pair_test \
+  $(BINDIR)/$(CONFIG)/error_test \
   $(BINDIR)/$(CONFIG)/ev_epoll_linux_test \
+  $(BINDIR)/$(CONFIG)/fake_resolver_test \
   $(BINDIR)/$(CONFIG)/fd_conservation_posix_test \
   $(BINDIR)/$(CONFIG)/fd_posix_test \
   $(BINDIR)/$(CONFIG)/fling_client \
@@ -1356,10 +1440,12 @@ buildtests_c: privatelibs_c \
   $(BINDIR)/$(CONFIG)/memory_profile_server \
   $(BINDIR)/$(CONFIG)/memory_profile_test \
   $(BINDIR)/$(CONFIG)/message_compress_test \
+  $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test \
   $(BINDIR)/$(CONFIG)/mlog_test \
   $(BINDIR)/$(CONFIG)/multiple_server_queues_test \
   $(BINDIR)/$(CONFIG)/murmur_hash_test \
   $(BINDIR)/$(CONFIG)/no_server_test \
+  $(BINDIR)/$(CONFIG)/parse_address_test \
   $(BINDIR)/$(CONFIG)/percent_encoding_test \
   $(BINDIR)/$(CONFIG)/pollset_set_test \
   $(BINDIR)/$(CONFIG)/resolve_address_posix_test \
@@ -1370,14 +1456,15 @@ buildtests_c: privatelibs_c \
   $(BINDIR)/$(CONFIG)/sequential_connectivity_test \
   $(BINDIR)/$(CONFIG)/server_chttp2_test \
   $(BINDIR)/$(CONFIG)/server_test \
-  $(BINDIR)/$(CONFIG)/set_initial_connect_string_test \
   $(BINDIR)/$(CONFIG)/slice_buffer_test \
+  $(BINDIR)/$(CONFIG)/slice_hash_table_test \
   $(BINDIR)/$(CONFIG)/slice_string_helpers_test \
   $(BINDIR)/$(CONFIG)/slice_test \
   $(BINDIR)/$(CONFIG)/sockaddr_resolver_test \
   $(BINDIR)/$(CONFIG)/sockaddr_utils_test \
   $(BINDIR)/$(CONFIG)/socket_utils_test \
   $(BINDIR)/$(CONFIG)/status_conversion_test \
+  $(BINDIR)/$(CONFIG)/stream_owned_slice_test \
   $(BINDIR)/$(CONFIG)/tcp_client_posix_test \
   $(BINDIR)/$(CONFIG)/tcp_client_uv_test \
   $(BINDIR)/$(CONFIG)/tcp_posix_test \
@@ -1458,13 +1545,20 @@ buildtests_cxx: privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/alarm_cpp_test \
   $(BINDIR)/$(CONFIG)/async_end2end_test \
   $(BINDIR)/$(CONFIG)/auth_property_iterator_test \
+  $(BINDIR)/$(CONFIG)/bm_arena \
   $(BINDIR)/$(CONFIG)/bm_call_create \
   $(BINDIR)/$(CONFIG)/bm_chttp2_hpack \
+  $(BINDIR)/$(CONFIG)/bm_chttp2_transport \
   $(BINDIR)/$(CONFIG)/bm_closure \
   $(BINDIR)/$(CONFIG)/bm_cq \
+  $(BINDIR)/$(CONFIG)/bm_cq_multiple_threads \
   $(BINDIR)/$(CONFIG)/bm_error \
-  $(BINDIR)/$(CONFIG)/bm_fullstack \
+  $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong \
+  $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump \
+  $(BINDIR)/$(CONFIG)/bm_fullstack_trickle \
+  $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong \
   $(BINDIR)/$(CONFIG)/bm_metadata \
+  $(BINDIR)/$(CONFIG)/bm_pollset \
   $(BINDIR)/$(CONFIG)/channel_arguments_test \
   $(BINDIR)/$(CONFIG)/channel_filter_test \
   $(BINDIR)/$(CONFIG)/cli_call_test \
@@ -1478,12 +1572,14 @@ buildtests_cxx: privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/cxx_string_ref_test \
   $(BINDIR)/$(CONFIG)/cxx_time_test \
   $(BINDIR)/$(CONFIG)/end2end_test \
+  $(BINDIR)/$(CONFIG)/error_details_test \
   $(BINDIR)/$(CONFIG)/filter_end2end_test \
   $(BINDIR)/$(CONFIG)/generic_end2end_test \
   $(BINDIR)/$(CONFIG)/golden_file_test \
   $(BINDIR)/$(CONFIG)/grpc_cli \
   $(BINDIR)/$(CONFIG)/grpc_tool_test \
   $(BINDIR)/$(CONFIG)/grpclb_api_test \
+  $(BINDIR)/$(CONFIG)/grpclb_end2end_test \
   $(BINDIR)/$(CONFIG)/grpclb_test \
   $(BINDIR)/$(CONFIG)/health_service_end2end_test \
   $(BINDIR)/$(CONFIG)/http2_client \
@@ -1492,6 +1588,7 @@ buildtests_cxx: privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/interop_server \
   $(BINDIR)/$(CONFIG)/interop_test \
   $(BINDIR)/$(CONFIG)/json_run_localhost \
+  $(BINDIR)/$(CONFIG)/memory_test \
   $(BINDIR)/$(CONFIG)/metrics_client \
   $(BINDIR)/$(CONFIG)/mock_test \
   $(BINDIR)/$(CONFIG)/noop-benchmark \
@@ -1507,6 +1604,7 @@ buildtests_cxx: privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/secure_auth_context_test \
   $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \
   $(BINDIR)/$(CONFIG)/server_builder_plugin_test \
+  $(BINDIR)/$(CONFIG)/server_builder_test \
   $(BINDIR)/$(CONFIG)/server_context_test_spouse_test \
   $(BINDIR)/$(CONFIG)/server_crash_test \
   $(BINDIR)/$(CONFIG)/server_crash_test_client \
@@ -1569,13 +1667,20 @@ buildtests_cxx: privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/alarm_cpp_test \
   $(BINDIR)/$(CONFIG)/async_end2end_test \
   $(BINDIR)/$(CONFIG)/auth_property_iterator_test \
+  $(BINDIR)/$(CONFIG)/bm_arena \
   $(BINDIR)/$(CONFIG)/bm_call_create \
   $(BINDIR)/$(CONFIG)/bm_chttp2_hpack \
+  $(BINDIR)/$(CONFIG)/bm_chttp2_transport \
   $(BINDIR)/$(CONFIG)/bm_closure \
   $(BINDIR)/$(CONFIG)/bm_cq \
+  $(BINDIR)/$(CONFIG)/bm_cq_multiple_threads \
   $(BINDIR)/$(CONFIG)/bm_error \
-  $(BINDIR)/$(CONFIG)/bm_fullstack \
+  $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong \
+  $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump \
+  $(BINDIR)/$(CONFIG)/bm_fullstack_trickle \
+  $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong \
   $(BINDIR)/$(CONFIG)/bm_metadata \
+  $(BINDIR)/$(CONFIG)/bm_pollset \
   $(BINDIR)/$(CONFIG)/channel_arguments_test \
   $(BINDIR)/$(CONFIG)/channel_filter_test \
   $(BINDIR)/$(CONFIG)/cli_call_test \
@@ -1589,12 +1694,14 @@ buildtests_cxx: privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/cxx_string_ref_test \
   $(BINDIR)/$(CONFIG)/cxx_time_test \
   $(BINDIR)/$(CONFIG)/end2end_test \
+  $(BINDIR)/$(CONFIG)/error_details_test \
   $(BINDIR)/$(CONFIG)/filter_end2end_test \
   $(BINDIR)/$(CONFIG)/generic_end2end_test \
   $(BINDIR)/$(CONFIG)/golden_file_test \
   $(BINDIR)/$(CONFIG)/grpc_cli \
   $(BINDIR)/$(CONFIG)/grpc_tool_test \
   $(BINDIR)/$(CONFIG)/grpclb_api_test \
+  $(BINDIR)/$(CONFIG)/grpclb_end2end_test \
   $(BINDIR)/$(CONFIG)/grpclb_test \
   $(BINDIR)/$(CONFIG)/health_service_end2end_test \
   $(BINDIR)/$(CONFIG)/http2_client \
@@ -1603,6 +1710,7 @@ buildtests_cxx: privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/interop_server \
   $(BINDIR)/$(CONFIG)/interop_test \
   $(BINDIR)/$(CONFIG)/json_run_localhost \
+  $(BINDIR)/$(CONFIG)/memory_test \
   $(BINDIR)/$(CONFIG)/metrics_client \
   $(BINDIR)/$(CONFIG)/mock_test \
   $(BINDIR)/$(CONFIG)/noop-benchmark \
@@ -1618,6 +1726,7 @@ buildtests_cxx: privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/secure_auth_context_test \
   $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \
   $(BINDIR)/$(CONFIG)/server_builder_plugin_test \
+  $(BINDIR)/$(CONFIG)/server_builder_test \
   $(BINDIR)/$(CONFIG)/server_context_test_spouse_test \
   $(BINDIR)/$(CONFIG)/server_crash_test \
   $(BINDIR)/$(CONFIG)/server_crash_test_client \
@@ -1645,6 +1754,8 @@ test_c: buildtests_c
 	$(Q) $(BINDIR)/$(CONFIG)/alloc_test || ( echo test alloc_test failed ; exit 1 )
 	$(E) "[RUN]     Testing alpn_test"
 	$(Q) $(BINDIR)/$(CONFIG)/alpn_test || ( echo test alpn_test failed ; exit 1 )
+	$(E) "[RUN]     Testing arena_test"
+	$(Q) $(BINDIR)/$(CONFIG)/arena_test || ( echo test arena_test failed ; exit 1 )
 	$(E) "[RUN]     Testing bad_server_response_test"
 	$(Q) $(BINDIR)/$(CONFIG)/bad_server_response_test || ( echo test bad_server_response_test failed ; exit 1 )
 	$(E) "[RUN]     Testing bdp_estimator_test"
@@ -1683,8 +1794,12 @@ test_c: buildtests_c
 	$(Q) $(BINDIR)/$(CONFIG)/dualstack_socket_test || ( echo test dualstack_socket_test failed ; exit 1 )
 	$(E) "[RUN]     Testing endpoint_pair_test"
 	$(Q) $(BINDIR)/$(CONFIG)/endpoint_pair_test || ( echo test endpoint_pair_test failed ; exit 1 )
+	$(E) "[RUN]     Testing error_test"
+	$(Q) $(BINDIR)/$(CONFIG)/error_test || ( echo test error_test failed ; exit 1 )
 	$(E) "[RUN]     Testing ev_epoll_linux_test"
 	$(Q) $(BINDIR)/$(CONFIG)/ev_epoll_linux_test || ( echo test ev_epoll_linux_test failed ; exit 1 )
+	$(E) "[RUN]     Testing fake_resolver_test"
+	$(Q) $(BINDIR)/$(CONFIG)/fake_resolver_test || ( echo test fake_resolver_test failed ; exit 1 )
 	$(E) "[RUN]     Testing fd_conservation_posix_test"
 	$(Q) $(BINDIR)/$(CONFIG)/fd_conservation_posix_test || ( echo test fd_conservation_posix_test failed ; exit 1 )
 	$(E) "[RUN]     Testing fd_posix_test"
@@ -1787,12 +1902,16 @@ test_c: buildtests_c
 	$(Q) $(BINDIR)/$(CONFIG)/memory_profile_test || ( echo test memory_profile_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 minimal_stack_is_minimal_test"
+	$(Q) $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test || ( echo test minimal_stack_is_minimal_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"
 	$(Q) $(BINDIR)/$(CONFIG)/murmur_hash_test || ( echo test murmur_hash_test failed ; exit 1 )
 	$(E) "[RUN]     Testing no_server_test"
 	$(Q) $(BINDIR)/$(CONFIG)/no_server_test || ( echo test no_server_test failed ; exit 1 )
+	$(E) "[RUN]     Testing parse_address_test"
+	$(Q) $(BINDIR)/$(CONFIG)/parse_address_test || ( echo test parse_address_test failed ; exit 1 )
 	$(E) "[RUN]     Testing percent_encoding_test"
 	$(Q) $(BINDIR)/$(CONFIG)/percent_encoding_test || ( echo test percent_encoding_test failed ; exit 1 )
 	$(E) "[RUN]     Testing pollset_set_test"
@@ -1813,10 +1932,10 @@ test_c: buildtests_c
 	$(Q) $(BINDIR)/$(CONFIG)/server_chttp2_test || ( echo test server_chttp2_test failed ; exit 1 )
 	$(E) "[RUN]     Testing server_test"
 	$(Q) $(BINDIR)/$(CONFIG)/server_test || ( echo test server_test failed ; exit 1 )
-	$(E) "[RUN]     Testing set_initial_connect_string_test"
-	$(Q) $(BINDIR)/$(CONFIG)/set_initial_connect_string_test || ( echo test set_initial_connect_string_test failed ; exit 1 )
 	$(E) "[RUN]     Testing slice_buffer_test"
 	$(Q) $(BINDIR)/$(CONFIG)/slice_buffer_test || ( echo test slice_buffer_test failed ; exit 1 )
+	$(E) "[RUN]     Testing slice_hash_table_test"
+	$(Q) $(BINDIR)/$(CONFIG)/slice_hash_table_test || ( echo test slice_hash_table_test failed ; exit 1 )
 	$(E) "[RUN]     Testing slice_string_helpers_test"
 	$(Q) $(BINDIR)/$(CONFIG)/slice_string_helpers_test || ( echo test slice_string_helpers_test failed ; exit 1 )
 	$(E) "[RUN]     Testing slice_test"
@@ -1829,6 +1948,8 @@ test_c: buildtests_c
 	$(Q) $(BINDIR)/$(CONFIG)/socket_utils_test || ( echo test socket_utils_test failed ; exit 1 )
 	$(E) "[RUN]     Testing status_conversion_test"
 	$(Q) $(BINDIR)/$(CONFIG)/status_conversion_test || ( echo test status_conversion_test failed ; exit 1 )
+	$(E) "[RUN]     Testing stream_owned_slice_test"
+	$(Q) $(BINDIR)/$(CONFIG)/stream_owned_slice_test || ( echo test stream_owned_slice_test failed ; exit 1 )
 	$(E) "[RUN]     Testing tcp_client_posix_test"
 	$(Q) $(BINDIR)/$(CONFIG)/tcp_client_posix_test || ( echo test tcp_client_posix_test failed ; exit 1 )
 	$(E) "[RUN]     Testing tcp_client_uv_test"
@@ -1899,20 +2020,34 @@ test_cxx: buildtests_cxx
 	$(Q) $(BINDIR)/$(CONFIG)/async_end2end_test || ( echo test async_end2end_test failed ; exit 1 )
 	$(E) "[RUN]     Testing auth_property_iterator_test"
 	$(Q) $(BINDIR)/$(CONFIG)/auth_property_iterator_test || ( echo test auth_property_iterator_test failed ; exit 1 )
+	$(E) "[RUN]     Testing bm_arena"
+	$(Q) $(BINDIR)/$(CONFIG)/bm_arena || ( echo test bm_arena failed ; exit 1 )
 	$(E) "[RUN]     Testing bm_call_create"
 	$(Q) $(BINDIR)/$(CONFIG)/bm_call_create || ( echo test bm_call_create failed ; exit 1 )
 	$(E) "[RUN]     Testing bm_chttp2_hpack"
 	$(Q) $(BINDIR)/$(CONFIG)/bm_chttp2_hpack || ( echo test bm_chttp2_hpack failed ; exit 1 )
+	$(E) "[RUN]     Testing bm_chttp2_transport"
+	$(Q) $(BINDIR)/$(CONFIG)/bm_chttp2_transport || ( echo test bm_chttp2_transport failed ; exit 1 )
 	$(E) "[RUN]     Testing bm_closure"
 	$(Q) $(BINDIR)/$(CONFIG)/bm_closure || ( echo test bm_closure failed ; exit 1 )
 	$(E) "[RUN]     Testing bm_cq"
 	$(Q) $(BINDIR)/$(CONFIG)/bm_cq || ( echo test bm_cq failed ; exit 1 )
+	$(E) "[RUN]     Testing bm_cq_multiple_threads"
+	$(Q) $(BINDIR)/$(CONFIG)/bm_cq_multiple_threads || ( echo test bm_cq_multiple_threads failed ; exit 1 )
 	$(E) "[RUN]     Testing bm_error"
 	$(Q) $(BINDIR)/$(CONFIG)/bm_error || ( echo test bm_error failed ; exit 1 )
-	$(E) "[RUN]     Testing bm_fullstack"
-	$(Q) $(BINDIR)/$(CONFIG)/bm_fullstack || ( echo test bm_fullstack failed ; exit 1 )
+	$(E) "[RUN]     Testing bm_fullstack_streaming_ping_pong"
+	$(Q) $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong || ( echo test bm_fullstack_streaming_ping_pong failed ; exit 1 )
+	$(E) "[RUN]     Testing bm_fullstack_streaming_pump"
+	$(Q) $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump || ( echo test bm_fullstack_streaming_pump failed ; exit 1 )
+	$(E) "[RUN]     Testing bm_fullstack_trickle"
+	$(Q) $(BINDIR)/$(CONFIG)/bm_fullstack_trickle || ( echo test bm_fullstack_trickle failed ; exit 1 )
+	$(E) "[RUN]     Testing bm_fullstack_unary_ping_pong"
+	$(Q) $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong || ( echo test bm_fullstack_unary_ping_pong failed ; exit 1 )
 	$(E) "[RUN]     Testing bm_metadata"
 	$(Q) $(BINDIR)/$(CONFIG)/bm_metadata || ( echo test bm_metadata failed ; exit 1 )
+	$(E) "[RUN]     Testing bm_pollset"
+	$(Q) $(BINDIR)/$(CONFIG)/bm_pollset || ( echo test bm_pollset failed ; exit 1 )
 	$(E) "[RUN]     Testing channel_arguments_test"
 	$(Q) $(BINDIR)/$(CONFIG)/channel_arguments_test || ( echo test channel_arguments_test failed ; exit 1 )
 	$(E) "[RUN]     Testing channel_filter_test"
@@ -1937,6 +2072,8 @@ test_cxx: buildtests_cxx
 	$(Q) $(BINDIR)/$(CONFIG)/cxx_time_test || ( echo test cxx_time_test failed ; exit 1 )
 	$(E) "[RUN]     Testing end2end_test"
 	$(Q) $(BINDIR)/$(CONFIG)/end2end_test || ( echo test end2end_test failed ; exit 1 )
+	$(E) "[RUN]     Testing error_details_test"
+	$(Q) $(BINDIR)/$(CONFIG)/error_details_test || ( echo test error_details_test failed ; exit 1 )
 	$(E) "[RUN]     Testing filter_end2end_test"
 	$(Q) $(BINDIR)/$(CONFIG)/filter_end2end_test || ( echo test filter_end2end_test failed ; exit 1 )
 	$(E) "[RUN]     Testing generic_end2end_test"
@@ -1947,12 +2084,16 @@ test_cxx: buildtests_cxx
 	$(Q) $(BINDIR)/$(CONFIG)/grpc_tool_test || ( echo test grpc_tool_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 grpclb_end2end_test"
+	$(Q) $(BINDIR)/$(CONFIG)/grpclb_end2end_test || ( echo test grpclb_end2end_test failed ; exit 1 )
 	$(E) "[RUN]     Testing grpclb_test"
 	$(Q) $(BINDIR)/$(CONFIG)/grpclb_test || ( echo test grpclb_test failed ; exit 1 )
 	$(E) "[RUN]     Testing health_service_end2end_test"
 	$(Q) $(BINDIR)/$(CONFIG)/health_service_end2end_test || ( echo test health_service_end2end_test failed ; exit 1 )
 	$(E) "[RUN]     Testing interop_test"
 	$(Q) $(BINDIR)/$(CONFIG)/interop_test || ( echo test interop_test failed ; exit 1 )
+	$(E) "[RUN]     Testing memory_test"
+	$(Q) $(BINDIR)/$(CONFIG)/memory_test || ( echo test memory_test failed ; exit 1 )
 	$(E) "[RUN]     Testing mock_test"
 	$(Q) $(BINDIR)/$(CONFIG)/mock_test || ( echo test mock_test failed ; exit 1 )
 	$(E) "[RUN]     Testing noop-benchmark"
@@ -1971,6 +2112,8 @@ test_cxx: buildtests_cxx
 	$(Q) $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test || ( echo test secure_sync_unary_ping_pong_test failed ; exit 1 )
 	$(E) "[RUN]     Testing server_builder_plugin_test"
 	$(Q) $(BINDIR)/$(CONFIG)/server_builder_plugin_test || ( echo test server_builder_plugin_test failed ; exit 1 )
+	$(E) "[RUN]     Testing server_builder_test"
+	$(Q) $(BINDIR)/$(CONFIG)/server_builder_test || ( echo test server_builder_test failed ; exit 1 )
 	$(E) "[RUN]     Testing server_context_test_spouse_test"
 	$(Q) $(BINDIR)/$(CONFIG)/server_context_test_spouse_test || ( echo test server_context_test_spouse_test failed ; exit 1 )
 	$(E) "[RUN]     Testing server_crash_test"
@@ -2039,6 +2182,8 @@ ifeq ($(CONFIG),opt)
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.a
 	$(E) "[STRIP]   Stripping libgrpc++_cronet.a"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a
+	$(E) "[STRIP]   Stripping libgrpc++_error_details.a"
+	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a
 	$(E) "[STRIP]   Stripping libgrpc++_reflection.a"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a
 	$(E) "[STRIP]   Stripping libgrpc++_unsecure.a"
@@ -2063,6 +2208,8 @@ ifeq ($(CONFIG),opt)
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
+	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
+	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@@ -2103,6 +2250,7 @@ ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc: protoc_dep_error
 else
+
 $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc: src/proto/grpc/health/v1/health.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
@@ -2118,6 +2266,7 @@ ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc: protoc_dep_error
 else
+
 $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc: src/proto/grpc/lb/v1/load_balancer.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
@@ -2133,6 +2282,7 @@ ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc: protoc_dep_error
 else
+
 $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc: src/proto/grpc/reflection/v1alpha/reflection.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
@@ -2144,10 +2294,28 @@ $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc: src/proto/grp
 	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
+ifeq ($(NO_PROTOC),true)
+$(GENDIR)/src/proto/grpc/status/status.pb.cc: protoc_dep_error
+$(GENDIR)/src/proto/grpc/status/status.grpc.pb.cc: protoc_dep_error
+else
+
+$(GENDIR)/src/proto/grpc/status/status.pb.cc: src/proto/grpc/status/status.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
+	$(E) "[PROTOC]  Generating protobuf CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/src/proto/grpc/status/status.grpc.pb.cc: src/proto/grpc/status/status.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
+endif
+
 ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.cc: protoc_dep_error
 else
+
+
 $(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc: src/proto/grpc/testing/compiler_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
@@ -2156,13 +2324,14 @@ $(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc: src/proto/grpc/testing/com
 $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.cc: src/proto/grpc/testing/compiler_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=generate_mock_code=true:$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 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
+
 $(GENDIR)/src/proto/grpc/testing/control.pb.cc: src/proto/grpc/testing/control.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
@@ -2178,6 +2347,7 @@ ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc: protoc_dep_error
 else
+
 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc: src/proto/grpc/testing/duplicate/echo_duplicate.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
@@ -2193,6 +2363,8 @@ ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/testing/echo.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: protoc_dep_error
 else
+
+
 $(GENDIR)/src/proto/grpc/testing/echo.pb.cc: src/proto/grpc/testing/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
@@ -2201,13 +2373,14 @@ $(GENDIR)/src/proto/grpc/testing/echo.pb.cc: src/proto/grpc/testing/echo.proto $
 $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: src/proto/grpc/testing/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=generate_mock_code=true:$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
 ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc: protoc_dep_error
 else
+
 $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc: src/proto/grpc/testing/echo_messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
@@ -2223,6 +2396,7 @@ ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/testing/empty.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc: protoc_dep_error
 else
+
 $(GENDIR)/src/proto/grpc/testing/empty.pb.cc: src/proto/grpc/testing/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
@@ -2238,6 +2412,7 @@ ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/testing/messages.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc: protoc_dep_error
 else
+
 $(GENDIR)/src/proto/grpc/testing/messages.pb.cc: src/proto/grpc/testing/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
@@ -2253,6 +2428,7 @@ ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc: protoc_dep_error
 else
+
 $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc: src/proto/grpc/testing/metrics.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
@@ -2268,6 +2444,7 @@ ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc: protoc_dep_error
 else
+
 $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc: src/proto/grpc/testing/payloads.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
@@ -2283,12 +2460,13 @@ ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/testing/services.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc: protoc_dep_error
 else
-$(GENDIR)/src/proto/grpc/testing/services.pb.cc: src/proto/grpc/testing/services.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc
+
+$(GENDIR)/src/proto/grpc/testing/services.pb.cc: src/proto/grpc/testing/services.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
 
-$(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc: src/proto/grpc/testing/services.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.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.grpc.pb.cc: src/proto/grpc/testing/services.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.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/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
@@ -2298,6 +2476,7 @@ ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/testing/stats.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc: protoc_dep_error
 else
+
 $(GENDIR)/src/proto/grpc/testing/stats.pb.cc: src/proto/grpc/testing/stats.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
@@ -2313,6 +2492,7 @@ ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/testing/test.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc: protoc_dep_error
 else
+
 $(GENDIR)/src/proto/grpc/testing/test.pb.cc: src/proto/grpc/testing/test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
@@ -2402,6 +2582,9 @@ install-static_cxx: static_cxx strip-static_cxx install-pkg-config_cxx
 	$(E) "[INSTALL] Installing libgrpc++_cronet.a"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a $(prefix)/lib/libgrpc++_cronet.a
+	$(E) "[INSTALL] Installing libgrpc++_error_details.a"
+	$(Q) $(INSTALL) -d $(prefix)/lib
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(prefix)/lib/libgrpc++_error_details.a
 	$(E) "[INSTALL] Installing libgrpc++_reflection.a"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(prefix)/lib/libgrpc++_reflection.a
@@ -2418,7 +2601,7 @@ install-shared_c: shared_c strip-shared_c install-pkg-config_c
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgpr.a
 else ifneq ($(SYSTEM),Darwin)
-	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgpr.so.3
+	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgpr.so.4
 	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgpr.so
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
@@ -2427,7 +2610,7 @@ endif
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgrpc.a
 else ifneq ($(SYSTEM),Darwin)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc.so.3
+	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc.so.4
 	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc.so
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
@@ -2436,7 +2619,7 @@ endif
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgrpc_cronet.a
 else ifneq ($(SYSTEM),Darwin)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_cronet.so.3
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_cronet.so.4
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_cronet.so
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
@@ -2445,7 +2628,7 @@ endif
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgrpc_unsecure.a
 else ifneq ($(SYSTEM),Darwin)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_unsecure.so.3
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_unsecure.so.4
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_unsecure.so
 endif
 ifneq ($(SYSTEM),MINGW32)
@@ -2462,7 +2645,7 @@ install-shared_cxx: shared_cxx strip-shared_cxx install-shared_c install-pkg-con
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++.a
 else ifneq ($(SYSTEM),Darwin)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so.3
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so.4
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@@ -2471,8 +2654,17 @@ endif
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_cronet.a
 else ifneq ($(SYSTEM),Darwin)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so.3
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so.4
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so
+endif
+	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
+	$(Q) $(INSTALL) -d $(prefix)/lib
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
+ifeq ($(SYSTEM),MINGW32)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_error_details.a
+else ifneq ($(SYSTEM),Darwin)
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_error_details.so.4
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_error_details.so
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
@@ -2480,7 +2672,7 @@ endif
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_reflection.a
 else ifneq ($(SYSTEM),Darwin)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so.3
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so.4
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@@ -2489,7 +2681,7 @@ endif
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_unsecure.a
 else ifneq ($(SYSTEM),Darwin)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so.3
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so.4
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so
 endif
 ifneq ($(SYSTEM),MINGW32)
@@ -2506,7 +2698,7 @@ install-shared_csharp: shared_csharp strip-shared_csharp
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP)-dll.a $(prefix)/lib/libgrpc_csharp_ext.a
 else ifneq ($(SYSTEM),Darwin)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so.3
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so.4
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so
 endif
 ifneq ($(SYSTEM),MINGW32)
@@ -2562,6 +2754,8 @@ LIBGPR_SRC = \
     src/core/lib/profiling/basic_timers.c \
     src/core/lib/profiling/stap_timers.c \
     src/core/lib/support/alloc.c \
+    src/core/lib/support/arena.c \
+    src/core/lib/support/atm.c \
     src/core/lib/support/avl.c \
     src/core/lib/support/backoff.c \
     src/core/lib/support/cmdline.c \
@@ -2638,7 +2832,6 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
-    include/grpc/impl/codegen/slice.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_generic.h \
     include/grpc/impl/codegen/sync_posix.h \
@@ -2647,7 +2840,7 @@ PUBLIC_HEADERS_C += \
 LIBGPR_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGPR_SRC))))
 
 
-$(LIBDIR)/$(CONFIG)/libgpr.a: $(ZLIB_DEP)  $(LIBGPR_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgpr.a: $(ZLIB_DEP) $(CARES_DEP)  $(LIBGPR_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgpr.a
@@ -2659,19 +2852,19 @@ endif
 
 
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OBJS)  $(ZLIB_DEP)
+$(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OBJS)  $(ZLIB_DEP) $(CARES_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(LDLIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
 else
-$(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OBJS)  $(ZLIB_DEP)
+$(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OBJS)  $(ZLIB_DEP) $(CARES_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(LDLIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
 else
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.3 -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(LDLIBS)
-	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.3
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.4 -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
+	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.4
 	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so
 endif
 endif
@@ -2689,7 +2882,7 @@ PUBLIC_HEADERS_C += \
 LIBGPR_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGPR_TEST_UTIL_SRC))))
 
 
-$(LIBDIR)/$(CONFIG)/libgpr_test_util.a: $(ZLIB_DEP)  $(LIBGPR_TEST_UTIL_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgpr_test_util.a: $(ZLIB_DEP) $(CARES_DEP)  $(LIBGPR_TEST_UTIL_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgpr_test_util.a
@@ -2711,15 +2904,10 @@ LIBGRPC_SRC = \
     src/core/lib/channel/channel_args.c \
     src/core/lib/channel/channel_stack.c \
     src/core/lib/channel/channel_stack_builder.c \
-    src/core/lib/channel/compress_filter.c \
     src/core/lib/channel/connected_channel.c \
-    src/core/lib/channel/deadline_filter.c \
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/handshaker_factory.c \
     src/core/lib/channel/handshaker_registry.c \
-    src/core/lib/channel/http_client_filter.c \
-    src/core/lib/channel/http_server_filter.c \
-    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
@@ -2744,6 +2932,7 @@ LIBGRPC_SRC = \
     src/core/lib/iomgr/iomgr_uv.c \
     src/core/lib/iomgr/iomgr_windows.c \
     src/core/lib/iomgr/load_file.c \
+    src/core/lib/iomgr/lockfree_event.c \
     src/core/lib/iomgr/network_status_tracker.c \
     src/core/lib/iomgr/polling_entity.c \
     src/core/lib/iomgr/pollset_set_uv.c \
@@ -2755,6 +2944,7 @@ LIBGRPC_SRC = \
     src/core/lib/iomgr/resolve_address_windows.c \
     src/core/lib/iomgr/resource_quota.c \
     src/core/lib/iomgr/sockaddr_utils.c \
+    src/core/lib/iomgr/socket_factory_posix.c \
     src/core/lib/iomgr/socket_mutator.c \
     src/core/lib/iomgr/socket_utils_common_posix.c \
     src/core/lib/iomgr/socket_utils_linux.c \
@@ -2767,6 +2957,9 @@ LIBGRPC_SRC = \
     src/core/lib/iomgr/tcp_client_windows.c \
     src/core/lib/iomgr/tcp_posix.c \
     src/core/lib/iomgr/tcp_server_posix.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_common.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c \
     src/core/lib/iomgr/tcp_server_uv.c \
     src/core/lib/iomgr/tcp_server_windows.c \
     src/core/lib/iomgr/tcp_uv.c \
@@ -2789,6 +2982,7 @@ LIBGRPC_SRC = \
     src/core/lib/json/json_reader.c \
     src/core/lib/json/json_string.c \
     src/core/lib/json/json_writer.c \
+    src/core/lib/slice/b64.c \
     src/core/lib/slice/percent_encoding.c \
     src/core/lib/slice/slice.c \
     src/core/lib/slice/slice_buffer.c \
@@ -2807,8 +3001,9 @@ LIBGRPC_SRC = \
     src/core/lib/surface/channel_ping.c \
     src/core/lib/surface/channel_stack_type.c \
     src/core/lib/surface/completion_queue.c \
+    src/core/lib/surface/completion_queue_factory.c \
     src/core/lib/surface/event_string.c \
-    src/core/lib/surface/lame_client.c \
+    src/core/lib/surface/lame_client.cc \
     src/core/lib/surface/metadata_array.c \
     src/core/lib/surface/server.c \
     src/core/lib/surface/validate_metadata.c \
@@ -2840,6 +3035,7 @@ LIBGRPC_SRC = \
     src/core/ext/transport/chttp2/transport/hpack_encoder.c \
     src/core/ext/transport/chttp2/transport/hpack_parser.c \
     src/core/ext/transport/chttp2/transport/hpack_table.c \
+    src/core/ext/transport/chttp2/transport/http2_settings.c \
     src/core/ext/transport/chttp2/transport/huffsyms.c \
     src/core/ext/transport/chttp2/transport/incoming_metadata.c \
     src/core/ext/transport/chttp2/transport/parsing.c \
@@ -2848,6 +3044,10 @@ LIBGRPC_SRC = \
     src/core/ext/transport/chttp2/transport/varint.c \
     src/core/ext/transport/chttp2/transport/writing.c \
     src/core/ext/transport/chttp2/alpn/alpn.c \
+    src/core/ext/filters/http/client/http_client_filter.c \
+    src/core/ext/filters/http/http_filters_plugin.c \
+    src/core/ext/filters/http/message_compress/message_compress_filter.c \
+    src/core/ext/filters/http/server/http_server_filter.c \
     src/core/lib/http/httpcli_security_connector.c \
     src/core/lib/security/context/security_context.c \
     src/core/lib/security/credentials/composite/composite_credentials.c \
@@ -2870,53 +3070,58 @@ LIBGRPC_SRC = \
     src/core/lib/security/transport/security_handshaker.c \
     src/core/lib/security/transport/server_auth_filter.c \
     src/core/lib/security/transport/tsi_error.c \
-    src/core/lib/security/util/b64.c \
     src/core/lib/security/util/json_util.c \
     src/core/lib/surface/init_secure.c \
-    src/core/lib/tsi/fake_transport_security.c \
-    src/core/lib/tsi/ssl_transport_security.c \
-    src/core/lib/tsi/transport_security.c \
+    src/core/tsi/fake_transport_security.c \
+    src/core/tsi/ssl_transport_security.c \
+    src/core/tsi/transport_security.c \
+    src/core/tsi/transport_security_adapter.c \
     src/core/ext/transport/chttp2/server/chttp2_server.c \
     src/core/ext/transport/chttp2/client/secure/secure_channel_create.c \
-    src/core/ext/client_channel/channel_connectivity.c \
-    src/core/ext/client_channel/client_channel.c \
-    src/core/ext/client_channel/client_channel_factory.c \
-    src/core/ext/client_channel/client_channel_plugin.c \
-    src/core/ext/client_channel/connector.c \
-    src/core/ext/client_channel/default_initial_connect_string.c \
-    src/core/ext/client_channel/http_connect_handshaker.c \
-    src/core/ext/client_channel/http_proxy.c \
-    src/core/ext/client_channel/initial_connect_string.c \
-    src/core/ext/client_channel/lb_policy.c \
-    src/core/ext/client_channel/lb_policy_factory.c \
-    src/core/ext/client_channel/lb_policy_registry.c \
-    src/core/ext/client_channel/parse_address.c \
-    src/core/ext/client_channel/proxy_mapper.c \
-    src/core/ext/client_channel/proxy_mapper_registry.c \
-    src/core/ext/client_channel/resolver.c \
-    src/core/ext/client_channel/resolver_factory.c \
-    src/core/ext/client_channel/resolver_registry.c \
-    src/core/ext/client_channel/subchannel.c \
-    src/core/ext/client_channel/subchannel_index.c \
-    src/core/ext/client_channel/uri_parser.c \
+    src/core/ext/filters/client_channel/channel_connectivity.c \
+    src/core/ext/filters/client_channel/client_channel.c \
+    src/core/ext/filters/client_channel/client_channel_factory.c \
+    src/core/ext/filters/client_channel/client_channel_plugin.c \
+    src/core/ext/filters/client_channel/connector.c \
+    src/core/ext/filters/client_channel/http_connect_handshaker.c \
+    src/core/ext/filters/client_channel/http_proxy.c \
+    src/core/ext/filters/client_channel/lb_policy.c \
+    src/core/ext/filters/client_channel/lb_policy_factory.c \
+    src/core/ext/filters/client_channel/lb_policy_registry.c \
+    src/core/ext/filters/client_channel/parse_address.c \
+    src/core/ext/filters/client_channel/proxy_mapper.c \
+    src/core/ext/filters/client_channel/proxy_mapper_registry.c \
+    src/core/ext/filters/client_channel/resolver.c \
+    src/core/ext/filters/client_channel/resolver_factory.c \
+    src/core/ext/filters/client_channel/resolver_registry.c \
+    src/core/ext/filters/client_channel/retry_throttle.c \
+    src/core/ext/filters/client_channel/subchannel.c \
+    src/core/ext/filters/client_channel/subchannel_index.c \
+    src/core/ext/filters/client_channel/uri_parser.c \
+    src/core/ext/filters/deadline/deadline_filter.c \
     src/core/ext/transport/chttp2/client/chttp2_connector.c \
     src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
     src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \
     src/core/ext/transport/chttp2/client/insecure/channel_create.c \
     src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
-    src/core/ext/lb_policy/grpclb/grpclb.c \
-    src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c \
-    src/core/ext/lb_policy/grpclb/load_balancer_api.c \
-    src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
     third_party/nanopb/pb_common.c \
     third_party/nanopb/pb_decode.c \
     third_party/nanopb/pb_encode.c \
-    src/core/ext/lb_policy/pick_first/pick_first.c \
-    src/core/ext/lb_policy/round_robin/round_robin.c \
-    src/core/ext/resolver/dns/native/dns_resolver.c \
-    src/core/ext/resolver/sockaddr/sockaddr_resolver.c \
-    src/core/ext/load_reporting/load_reporting.c \
-    src/core/ext/load_reporting/load_reporting_filter.c \
+    src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c \
+    src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c \
+    src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c \
+    src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c \
+    src/core/ext/filters/load_reporting/load_reporting.c \
+    src/core/ext/filters/load_reporting/load_reporting_filter.c \
     src/core/ext/census/base_resources.c \
     src/core/ext/census/context.c \
     src/core/ext/census/gen/census.pb.c \
@@ -2931,6 +3136,8 @@ LIBGRPC_SRC = \
     src/core/ext/census/resource.c \
     src/core/ext/census/trace_context.c \
     src/core/ext/census/tracing.c \
+    src/core/ext/filters/max_age/max_age_filter.c \
+    src/core/ext/filters/message_size/message_size_filter.c \
     src/core/plugin_registry/grpc_plugin_registry.c \
 
 PUBLIC_HEADERS_C += \
@@ -2950,6 +3157,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/grpc_types.h \
     include/grpc/impl/codegen/propagation_bits.h \
+    include/grpc/impl/codegen/slice.h \
     include/grpc/impl/codegen/status.h \
     include/grpc/impl/codegen/atm.h \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
@@ -2958,7 +3166,6 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
-    include/grpc/impl/codegen/slice.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_generic.h \
     include/grpc/impl/codegen/sync_posix.h \
@@ -2980,11 +3187,11 @@ $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE
 else
 
 
-$(LIBDIR)/$(CONFIG)/libgrpc.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgrpc.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(LIBGRPC_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a
-	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBGRPC_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
+	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBGRPC_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
 ifeq ($(SYSTEM),Darwin)
 	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc.a
 endif
@@ -2992,19 +3199,19 @@ endif
 
 
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
 else
-$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
 else
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBS)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.3
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.4 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
+	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.4
 	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so
 endif
 endif
@@ -3023,15 +3230,10 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/channel/channel_args.c \
     src/core/lib/channel/channel_stack.c \
     src/core/lib/channel/channel_stack_builder.c \
-    src/core/lib/channel/compress_filter.c \
     src/core/lib/channel/connected_channel.c \
-    src/core/lib/channel/deadline_filter.c \
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/handshaker_factory.c \
     src/core/lib/channel/handshaker_registry.c \
-    src/core/lib/channel/http_client_filter.c \
-    src/core/lib/channel/http_server_filter.c \
-    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
@@ -3056,6 +3258,7 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/iomgr/iomgr_uv.c \
     src/core/lib/iomgr/iomgr_windows.c \
     src/core/lib/iomgr/load_file.c \
+    src/core/lib/iomgr/lockfree_event.c \
     src/core/lib/iomgr/network_status_tracker.c \
     src/core/lib/iomgr/polling_entity.c \
     src/core/lib/iomgr/pollset_set_uv.c \
@@ -3067,6 +3270,7 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/iomgr/resolve_address_windows.c \
     src/core/lib/iomgr/resource_quota.c \
     src/core/lib/iomgr/sockaddr_utils.c \
+    src/core/lib/iomgr/socket_factory_posix.c \
     src/core/lib/iomgr/socket_mutator.c \
     src/core/lib/iomgr/socket_utils_common_posix.c \
     src/core/lib/iomgr/socket_utils_linux.c \
@@ -3079,6 +3283,9 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/iomgr/tcp_client_windows.c \
     src/core/lib/iomgr/tcp_posix.c \
     src/core/lib/iomgr/tcp_server_posix.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_common.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c \
     src/core/lib/iomgr/tcp_server_uv.c \
     src/core/lib/iomgr/tcp_server_windows.c \
     src/core/lib/iomgr/tcp_uv.c \
@@ -3101,6 +3308,7 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/json/json_reader.c \
     src/core/lib/json/json_string.c \
     src/core/lib/json/json_writer.c \
+    src/core/lib/slice/b64.c \
     src/core/lib/slice/percent_encoding.c \
     src/core/lib/slice/slice.c \
     src/core/lib/slice/slice_buffer.c \
@@ -3119,8 +3327,9 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/surface/channel_ping.c \
     src/core/lib/surface/channel_stack_type.c \
     src/core/lib/surface/completion_queue.c \
+    src/core/lib/surface/completion_queue_factory.c \
     src/core/lib/surface/event_string.c \
-    src/core/lib/surface/lame_client.c \
+    src/core/lib/surface/lame_client.cc \
     src/core/lib/surface/metadata_array.c \
     src/core/lib/surface/server.c \
     src/core/lib/surface/validate_metadata.c \
@@ -3155,6 +3364,7 @@ LIBGRPC_CRONET_SRC = \
     src/core/ext/transport/chttp2/transport/hpack_encoder.c \
     src/core/ext/transport/chttp2/transport/hpack_parser.c \
     src/core/ext/transport/chttp2/transport/hpack_table.c \
+    src/core/ext/transport/chttp2/transport/http2_settings.c \
     src/core/ext/transport/chttp2/transport/huffsyms.c \
     src/core/ext/transport/chttp2/transport/incoming_metadata.c \
     src/core/ext/transport/chttp2/transport/parsing.c \
@@ -3163,27 +3373,31 @@ LIBGRPC_CRONET_SRC = \
     src/core/ext/transport/chttp2/transport/varint.c \
     src/core/ext/transport/chttp2/transport/writing.c \
     src/core/ext/transport/chttp2/alpn/alpn.c \
-    src/core/ext/client_channel/channel_connectivity.c \
-    src/core/ext/client_channel/client_channel.c \
-    src/core/ext/client_channel/client_channel_factory.c \
-    src/core/ext/client_channel/client_channel_plugin.c \
-    src/core/ext/client_channel/connector.c \
-    src/core/ext/client_channel/default_initial_connect_string.c \
-    src/core/ext/client_channel/http_connect_handshaker.c \
-    src/core/ext/client_channel/http_proxy.c \
-    src/core/ext/client_channel/initial_connect_string.c \
-    src/core/ext/client_channel/lb_policy.c \
-    src/core/ext/client_channel/lb_policy_factory.c \
-    src/core/ext/client_channel/lb_policy_registry.c \
-    src/core/ext/client_channel/parse_address.c \
-    src/core/ext/client_channel/proxy_mapper.c \
-    src/core/ext/client_channel/proxy_mapper_registry.c \
-    src/core/ext/client_channel/resolver.c \
-    src/core/ext/client_channel/resolver_factory.c \
-    src/core/ext/client_channel/resolver_registry.c \
-    src/core/ext/client_channel/subchannel.c \
-    src/core/ext/client_channel/subchannel_index.c \
-    src/core/ext/client_channel/uri_parser.c \
+    src/core/ext/filters/http/client/http_client_filter.c \
+    src/core/ext/filters/http/http_filters_plugin.c \
+    src/core/ext/filters/http/message_compress/message_compress_filter.c \
+    src/core/ext/filters/http/server/http_server_filter.c \
+    src/core/ext/filters/client_channel/channel_connectivity.c \
+    src/core/ext/filters/client_channel/client_channel.c \
+    src/core/ext/filters/client_channel/client_channel_factory.c \
+    src/core/ext/filters/client_channel/client_channel_plugin.c \
+    src/core/ext/filters/client_channel/connector.c \
+    src/core/ext/filters/client_channel/http_connect_handshaker.c \
+    src/core/ext/filters/client_channel/http_proxy.c \
+    src/core/ext/filters/client_channel/lb_policy.c \
+    src/core/ext/filters/client_channel/lb_policy_factory.c \
+    src/core/ext/filters/client_channel/lb_policy_registry.c \
+    src/core/ext/filters/client_channel/parse_address.c \
+    src/core/ext/filters/client_channel/proxy_mapper.c \
+    src/core/ext/filters/client_channel/proxy_mapper_registry.c \
+    src/core/ext/filters/client_channel/resolver.c \
+    src/core/ext/filters/client_channel/resolver_factory.c \
+    src/core/ext/filters/client_channel/resolver_registry.c \
+    src/core/ext/filters/client_channel/retry_throttle.c \
+    src/core/ext/filters/client_channel/subchannel.c \
+    src/core/ext/filters/client_channel/subchannel_index.c \
+    src/core/ext/filters/client_channel/uri_parser.c \
+    src/core/ext/filters/deadline/deadline_filter.c \
     src/core/lib/http/httpcli_security_connector.c \
     src/core/lib/security/context/security_context.c \
     src/core/lib/security/credentials/composite/composite_credentials.c \
@@ -3206,15 +3420,15 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/security/transport/security_handshaker.c \
     src/core/lib/security/transport/server_auth_filter.c \
     src/core/lib/security/transport/tsi_error.c \
-    src/core/lib/security/util/b64.c \
     src/core/lib/security/util/json_util.c \
     src/core/lib/surface/init_secure.c \
-    src/core/lib/tsi/fake_transport_security.c \
-    src/core/lib/tsi/ssl_transport_security.c \
-    src/core/lib/tsi/transport_security.c \
+    src/core/tsi/fake_transport_security.c \
+    src/core/tsi/ssl_transport_security.c \
+    src/core/tsi/transport_security.c \
+    src/core/tsi/transport_security_adapter.c \
     src/core/ext/transport/chttp2/client/chttp2_connector.c \
-    src/core/ext/load_reporting/load_reporting.c \
-    src/core/ext/load_reporting/load_reporting_filter.c \
+    src/core/ext/filters/load_reporting/load_reporting.c \
+    src/core/ext/filters/load_reporting/load_reporting_filter.c \
     src/core/plugin_registry/grpc_cronet_plugin_registry.c \
 
 PUBLIC_HEADERS_C += \
@@ -3234,6 +3448,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/grpc_types.h \
     include/grpc/impl/codegen/propagation_bits.h \
+    include/grpc/impl/codegen/slice.h \
     include/grpc/impl/codegen/status.h \
     include/grpc/impl/codegen/atm.h \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
@@ -3242,7 +3457,6 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
-    include/grpc/impl/codegen/slice.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_generic.h \
     include/grpc/impl/codegen/sync_posix.h \
@@ -3264,11 +3478,11 @@ $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_E
 else
 
 
-$(LIBDIR)/$(CONFIG)/libgrpc_cronet.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_CRONET_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgrpc_cronet.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(LIBGRPC_CRONET_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a
-	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBGRPC_CRONET_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
+	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBGRPC_CRONET_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
 ifeq ($(SYSTEM),Darwin)
 	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a
 endif
@@ -3276,19 +3490,19 @@ endif
 
 
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CRONET_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CRONET_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
 else
-$(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CRONET_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CRONET_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
 else
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_cronet.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBS)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so.3
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_cronet.so.4 -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so.4
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so
 endif
 endif
@@ -3310,7 +3524,7 @@ LIBGRPC_TEST_UTIL_SRC = \
     test/core/security/oauth2_utils.c \
     test/core/end2end/cq_verifier.c \
     test/core/end2end/fake_resolver.c \
-    test/core/end2end/fixtures/http_proxy.c \
+    test/core/end2end/fixtures/http_proxy_fixture.c \
     test/core/end2end/fixtures/proxy.c \
     test/core/iomgr/endpoint_tests.c \
     test/core/util/debugger_macros.c \
@@ -3326,15 +3540,10 @@ LIBGRPC_TEST_UTIL_SRC = \
     src/core/lib/channel/channel_args.c \
     src/core/lib/channel/channel_stack.c \
     src/core/lib/channel/channel_stack_builder.c \
-    src/core/lib/channel/compress_filter.c \
     src/core/lib/channel/connected_channel.c \
-    src/core/lib/channel/deadline_filter.c \
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/handshaker_factory.c \
     src/core/lib/channel/handshaker_registry.c \
-    src/core/lib/channel/http_client_filter.c \
-    src/core/lib/channel/http_server_filter.c \
-    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
@@ -3359,6 +3568,7 @@ LIBGRPC_TEST_UTIL_SRC = \
     src/core/lib/iomgr/iomgr_uv.c \
     src/core/lib/iomgr/iomgr_windows.c \
     src/core/lib/iomgr/load_file.c \
+    src/core/lib/iomgr/lockfree_event.c \
     src/core/lib/iomgr/network_status_tracker.c \
     src/core/lib/iomgr/polling_entity.c \
     src/core/lib/iomgr/pollset_set_uv.c \
@@ -3370,6 +3580,7 @@ LIBGRPC_TEST_UTIL_SRC = \
     src/core/lib/iomgr/resolve_address_windows.c \
     src/core/lib/iomgr/resource_quota.c \
     src/core/lib/iomgr/sockaddr_utils.c \
+    src/core/lib/iomgr/socket_factory_posix.c \
     src/core/lib/iomgr/socket_mutator.c \
     src/core/lib/iomgr/socket_utils_common_posix.c \
     src/core/lib/iomgr/socket_utils_linux.c \
@@ -3382,6 +3593,9 @@ LIBGRPC_TEST_UTIL_SRC = \
     src/core/lib/iomgr/tcp_client_windows.c \
     src/core/lib/iomgr/tcp_posix.c \
     src/core/lib/iomgr/tcp_server_posix.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_common.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c \
     src/core/lib/iomgr/tcp_server_uv.c \
     src/core/lib/iomgr/tcp_server_windows.c \
     src/core/lib/iomgr/tcp_uv.c \
@@ -3404,6 +3618,7 @@ LIBGRPC_TEST_UTIL_SRC = \
     src/core/lib/json/json_reader.c \
     src/core/lib/json/json_string.c \
     src/core/lib/json/json_writer.c \
+    src/core/lib/slice/b64.c \
     src/core/lib/slice/percent_encoding.c \
     src/core/lib/slice/slice.c \
     src/core/lib/slice/slice_buffer.c \
@@ -3422,8 +3637,9 @@ LIBGRPC_TEST_UTIL_SRC = \
     src/core/lib/surface/channel_ping.c \
     src/core/lib/surface/channel_stack_type.c \
     src/core/lib/surface/completion_queue.c \
+    src/core/lib/surface/completion_queue_factory.c \
     src/core/lib/surface/event_string.c \
-    src/core/lib/surface/lame_client.c \
+    src/core/lib/surface/lame_client.cc \
     src/core/lib/surface/metadata_array.c \
     src/core/lib/surface/server.c \
     src/core/lib/surface/validate_metadata.c \
@@ -3459,6 +3675,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/grpc_types.h \
     include/grpc/impl/codegen/propagation_bits.h \
+    include/grpc/impl/codegen/slice.h \
     include/grpc/impl/codegen/status.h \
     include/grpc/impl/codegen/atm.h \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
@@ -3467,7 +3684,6 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
-    include/grpc/impl/codegen/slice.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_generic.h \
     include/grpc/impl/codegen/sync_posix.h \
@@ -3486,7 +3702,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a: openssl_dep_error
 else
 
 
-$(LIBDIR)/$(CONFIG)/libgrpc_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_TEST_UTIL_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgrpc_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(LIBGRPC_TEST_UTIL_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a
@@ -3510,7 +3726,7 @@ endif
 LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
     test/core/end2end/cq_verifier.c \
     test/core/end2end/fake_resolver.c \
-    test/core/end2end/fixtures/http_proxy.c \
+    test/core/end2end/fixtures/http_proxy_fixture.c \
     test/core/end2end/fixtures/proxy.c \
     test/core/iomgr/endpoint_tests.c \
     test/core/util/debugger_macros.c \
@@ -3529,7 +3745,7 @@ PUBLIC_HEADERS_C += \
 LIBGRPC_TEST_UTIL_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_TEST_UTIL_UNSECURE_SRC))))
 
 
-$(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a: $(ZLIB_DEP)  $(LIBGRPC_TEST_UTIL_UNSECURE_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a: $(ZLIB_DEP) $(CARES_DEP)  $(LIBGRPC_TEST_UTIL_UNSECURE_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a
@@ -3552,15 +3768,10 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/channel/channel_args.c \
     src/core/lib/channel/channel_stack.c \
     src/core/lib/channel/channel_stack_builder.c \
-    src/core/lib/channel/compress_filter.c \
     src/core/lib/channel/connected_channel.c \
-    src/core/lib/channel/deadline_filter.c \
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/handshaker_factory.c \
     src/core/lib/channel/handshaker_registry.c \
-    src/core/lib/channel/http_client_filter.c \
-    src/core/lib/channel/http_server_filter.c \
-    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
@@ -3585,6 +3796,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/iomgr/iomgr_uv.c \
     src/core/lib/iomgr/iomgr_windows.c \
     src/core/lib/iomgr/load_file.c \
+    src/core/lib/iomgr/lockfree_event.c \
     src/core/lib/iomgr/network_status_tracker.c \
     src/core/lib/iomgr/polling_entity.c \
     src/core/lib/iomgr/pollset_set_uv.c \
@@ -3596,6 +3808,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/iomgr/resolve_address_windows.c \
     src/core/lib/iomgr/resource_quota.c \
     src/core/lib/iomgr/sockaddr_utils.c \
+    src/core/lib/iomgr/socket_factory_posix.c \
     src/core/lib/iomgr/socket_mutator.c \
     src/core/lib/iomgr/socket_utils_common_posix.c \
     src/core/lib/iomgr/socket_utils_linux.c \
@@ -3608,6 +3821,9 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/iomgr/tcp_client_windows.c \
     src/core/lib/iomgr/tcp_posix.c \
     src/core/lib/iomgr/tcp_server_posix.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_common.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c \
     src/core/lib/iomgr/tcp_server_uv.c \
     src/core/lib/iomgr/tcp_server_windows.c \
     src/core/lib/iomgr/tcp_uv.c \
@@ -3630,6 +3846,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/json/json_reader.c \
     src/core/lib/json/json_string.c \
     src/core/lib/json/json_writer.c \
+    src/core/lib/slice/b64.c \
     src/core/lib/slice/percent_encoding.c \
     src/core/lib/slice/slice.c \
     src/core/lib/slice/slice_buffer.c \
@@ -3648,8 +3865,9 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/surface/channel_ping.c \
     src/core/lib/surface/channel_stack_type.c \
     src/core/lib/surface/completion_queue.c \
+    src/core/lib/surface/completion_queue_factory.c \
     src/core/lib/surface/event_string.c \
-    src/core/lib/surface/lame_client.c \
+    src/core/lib/surface/lame_client.cc \
     src/core/lib/surface/metadata_array.c \
     src/core/lib/surface/server.c \
     src/core/lib/surface/validate_metadata.c \
@@ -3682,6 +3900,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/transport/chttp2/transport/hpack_encoder.c \
     src/core/ext/transport/chttp2/transport/hpack_parser.c \
     src/core/ext/transport/chttp2/transport/hpack_table.c \
+    src/core/ext/transport/chttp2/transport/http2_settings.c \
     src/core/ext/transport/chttp2/transport/huffsyms.c \
     src/core/ext/transport/chttp2/transport/incoming_metadata.c \
     src/core/ext/transport/chttp2/transport/parsing.c \
@@ -3690,44 +3909,53 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/transport/chttp2/transport/varint.c \
     src/core/ext/transport/chttp2/transport/writing.c \
     src/core/ext/transport/chttp2/alpn/alpn.c \
+    src/core/ext/filters/http/client/http_client_filter.c \
+    src/core/ext/filters/http/http_filters_plugin.c \
+    src/core/ext/filters/http/message_compress/message_compress_filter.c \
+    src/core/ext/filters/http/server/http_server_filter.c \
     src/core/ext/transport/chttp2/server/chttp2_server.c \
     src/core/ext/transport/chttp2/client/insecure/channel_create.c \
     src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
     src/core/ext/transport/chttp2/client/chttp2_connector.c \
-    src/core/ext/client_channel/channel_connectivity.c \
-    src/core/ext/client_channel/client_channel.c \
-    src/core/ext/client_channel/client_channel_factory.c \
-    src/core/ext/client_channel/client_channel_plugin.c \
-    src/core/ext/client_channel/connector.c \
-    src/core/ext/client_channel/default_initial_connect_string.c \
-    src/core/ext/client_channel/http_connect_handshaker.c \
-    src/core/ext/client_channel/http_proxy.c \
-    src/core/ext/client_channel/initial_connect_string.c \
-    src/core/ext/client_channel/lb_policy.c \
-    src/core/ext/client_channel/lb_policy_factory.c \
-    src/core/ext/client_channel/lb_policy_registry.c \
-    src/core/ext/client_channel/parse_address.c \
-    src/core/ext/client_channel/proxy_mapper.c \
-    src/core/ext/client_channel/proxy_mapper_registry.c \
-    src/core/ext/client_channel/resolver.c \
-    src/core/ext/client_channel/resolver_factory.c \
-    src/core/ext/client_channel/resolver_registry.c \
-    src/core/ext/client_channel/subchannel.c \
-    src/core/ext/client_channel/subchannel_index.c \
-    src/core/ext/client_channel/uri_parser.c \
-    src/core/ext/resolver/dns/native/dns_resolver.c \
-    src/core/ext/resolver/sockaddr/sockaddr_resolver.c \
-    src/core/ext/load_reporting/load_reporting.c \
-    src/core/ext/load_reporting/load_reporting_filter.c \
-    src/core/ext/lb_policy/grpclb/grpclb.c \
-    src/core/ext/lb_policy/grpclb/grpclb_channel.c \
-    src/core/ext/lb_policy/grpclb/load_balancer_api.c \
-    src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
+    src/core/ext/filters/client_channel/channel_connectivity.c \
+    src/core/ext/filters/client_channel/client_channel.c \
+    src/core/ext/filters/client_channel/client_channel_factory.c \
+    src/core/ext/filters/client_channel/client_channel_plugin.c \
+    src/core/ext/filters/client_channel/connector.c \
+    src/core/ext/filters/client_channel/http_connect_handshaker.c \
+    src/core/ext/filters/client_channel/http_proxy.c \
+    src/core/ext/filters/client_channel/lb_policy.c \
+    src/core/ext/filters/client_channel/lb_policy_factory.c \
+    src/core/ext/filters/client_channel/lb_policy_registry.c \
+    src/core/ext/filters/client_channel/parse_address.c \
+    src/core/ext/filters/client_channel/proxy_mapper.c \
+    src/core/ext/filters/client_channel/proxy_mapper_registry.c \
+    src/core/ext/filters/client_channel/resolver.c \
+    src/core/ext/filters/client_channel/resolver_factory.c \
+    src/core/ext/filters/client_channel/resolver_registry.c \
+    src/core/ext/filters/client_channel/retry_throttle.c \
+    src/core/ext/filters/client_channel/subchannel.c \
+    src/core/ext/filters/client_channel/subchannel_index.c \
+    src/core/ext/filters/client_channel/uri_parser.c \
+    src/core/ext/filters/deadline/deadline_filter.c \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c \
+    src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c \
+    src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c \
+    src/core/ext/filters/load_reporting/load_reporting.c \
+    src/core/ext/filters/load_reporting/load_reporting_filter.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
     third_party/nanopb/pb_common.c \
     third_party/nanopb/pb_decode.c \
     third_party/nanopb/pb_encode.c \
-    src/core/ext/lb_policy/pick_first/pick_first.c \
-    src/core/ext/lb_policy/round_robin/round_robin.c \
+    src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c \
+    src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c \
     src/core/ext/census/base_resources.c \
     src/core/ext/census/context.c \
     src/core/ext/census/gen/census.pb.c \
@@ -3742,6 +3970,8 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/census/resource.c \
     src/core/ext/census/trace_context.c \
     src/core/ext/census/tracing.c \
+    src/core/ext/filters/max_age/max_age_filter.c \
+    src/core/ext/filters/message_size/message_size_filter.c \
     src/core/plugin_registry/grpc_unsecure_plugin_registry.c \
 
 PUBLIC_HEADERS_C += \
@@ -3761,6 +3991,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/grpc_types.h \
     include/grpc/impl/codegen/propagation_bits.h \
+    include/grpc/impl/codegen/slice.h \
     include/grpc/impl/codegen/status.h \
     include/grpc/impl/codegen/atm.h \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
@@ -3769,7 +4000,6 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
-    include/grpc/impl/codegen/slice.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_generic.h \
     include/grpc/impl/codegen/sync_posix.h \
@@ -3779,11 +4009,11 @@ PUBLIC_HEADERS_C += \
 LIBGRPC_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_UNSECURE_SRC))))
 
 
-$(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a: $(ZLIB_DEP)  $(LIBGRPC_UNSECURE_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a: $(ZLIB_DEP) $(CARES_DEP)  $(LIBGRPC_UNSECURE_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
-	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBGRPC_UNSECURE_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS) 
+	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBGRPC_UNSECURE_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS) 
 ifeq ($(SYSTEM),Darwin)
 	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
 endif
@@ -3791,19 +4021,19 @@ endif
 
 
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a
+$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(LDLIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
 else
-$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a
+$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(LDLIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
 else
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(LDLIBS)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.3
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.4 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.4
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so
 endif
 endif
@@ -3831,7 +4061,7 @@ $(LIBDIR)/$(CONFIG)/libreconnect_server.a: openssl_dep_error
 else
 
 
-$(LIBDIR)/$(CONFIG)/libreconnect_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBRECONNECT_SERVER_OBJS) 
+$(LIBDIR)/$(CONFIG)/libreconnect_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(LIBRECONNECT_SERVER_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libreconnect_server.a
@@ -3870,7 +4100,7 @@ $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a: openssl_dep_error
 else
 
 
-$(LIBDIR)/$(CONFIG)/libtest_tcp_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBTEST_TCP_SERVER_OBJS) 
+$(LIBDIR)/$(CONFIG)/libtest_tcp_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(LIBTEST_TCP_SERVER_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a
@@ -3915,6 +4145,7 @@ LIBGRPC++_SRC = \
     src/cpp/common/rpc_method.cc \
     src/cpp/common/version_cc.cc \
     src/cpp/server/async_generic_service.cc \
+    src/cpp/server/channel_argument_option.cc \
     src/cpp/server/create_default_thread_pool.cc \
     src/cpp/server/dynamic_thread_pool.cc \
     src/cpp/server/health/default_health_check_service.cc \
@@ -3932,241 +4163,13 @@ LIBGRPC++_SRC = \
     src/cpp/util/status.cc \
     src/cpp/util/string_ref.cc \
     src/cpp/util/time_cc.cc \
-    src/cpp/codegen/codegen_init.cc \
-
-PUBLIC_HEADERS_CXX += \
-    include/grpc++/alarm.h \
-    include/grpc++/channel.h \
-    include/grpc++/client_context.h \
-    include/grpc++/completion_queue.h \
-    include/grpc++/create_channel.h \
-    include/grpc++/create_channel_posix.h \
-    include/grpc++/ext/health_check_service_server_builder_option.h \
-    include/grpc++/generic/async_generic_service.h \
-    include/grpc++/generic/generic_stub.h \
-    include/grpc++/grpc++.h \
-    include/grpc++/health_check_service_interface.h \
-    include/grpc++/impl/call.h \
-    include/grpc++/impl/client_unary_call.h \
-    include/grpc++/impl/codegen/core_codegen.h \
-    include/grpc++/impl/grpc_library.h \
-    include/grpc++/impl/method_handler_impl.h \
-    include/grpc++/impl/rpc_method.h \
-    include/grpc++/impl/rpc_service_method.h \
-    include/grpc++/impl/serialization_traits.h \
-    include/grpc++/impl/server_builder_option.h \
-    include/grpc++/impl/server_builder_plugin.h \
-    include/grpc++/impl/server_initializer.h \
-    include/grpc++/impl/service_type.h \
-    include/grpc++/resource_quota.h \
-    include/grpc++/security/auth_context.h \
-    include/grpc++/security/auth_metadata_processor.h \
-    include/grpc++/security/credentials.h \
-    include/grpc++/security/server_credentials.h \
-    include/grpc++/server.h \
-    include/grpc++/server_builder.h \
-    include/grpc++/server_context.h \
-    include/grpc++/server_posix.h \
-    include/grpc++/support/async_stream.h \
-    include/grpc++/support/async_unary_call.h \
-    include/grpc++/support/byte_buffer.h \
-    include/grpc++/support/channel_arguments.h \
-    include/grpc++/support/config.h \
-    include/grpc++/support/slice.h \
-    include/grpc++/support/status.h \
-    include/grpc++/support/status_code_enum.h \
-    include/grpc++/support/string_ref.h \
-    include/grpc++/support/stub_options.h \
-    include/grpc++/support/sync_stream.h \
-    include/grpc++/support/time.h \
-    include/grpc++/impl/codegen/async_stream.h \
-    include/grpc++/impl/codegen/async_unary_call.h \
-    include/grpc++/impl/codegen/call.h \
-    include/grpc++/impl/codegen/call_hook.h \
-    include/grpc++/impl/codegen/channel_interface.h \
-    include/grpc++/impl/codegen/client_context.h \
-    include/grpc++/impl/codegen/client_unary_call.h \
-    include/grpc++/impl/codegen/completion_queue.h \
-    include/grpc++/impl/codegen/completion_queue_tag.h \
-    include/grpc++/impl/codegen/config.h \
-    include/grpc++/impl/codegen/core_codegen_interface.h \
-    include/grpc++/impl/codegen/create_auth_context.h \
-    include/grpc++/impl/codegen/grpc_library.h \
-    include/grpc++/impl/codegen/metadata_map.h \
-    include/grpc++/impl/codegen/method_handler_impl.h \
-    include/grpc++/impl/codegen/rpc_method.h \
-    include/grpc++/impl/codegen/rpc_service_method.h \
-    include/grpc++/impl/codegen/security/auth_context.h \
-    include/grpc++/impl/codegen/serialization_traits.h \
-    include/grpc++/impl/codegen/server_context.h \
-    include/grpc++/impl/codegen/server_interface.h \
-    include/grpc++/impl/codegen/service_type.h \
-    include/grpc++/impl/codegen/slice.h \
-    include/grpc++/impl/codegen/status.h \
-    include/grpc++/impl/codegen/status_code_enum.h \
-    include/grpc++/impl/codegen/status_helper.h \
-    include/grpc++/impl/codegen/string_ref.h \
-    include/grpc++/impl/codegen/stub_options.h \
-    include/grpc++/impl/codegen/sync_stream.h \
-    include/grpc++/impl/codegen/time.h \
-    include/grpc/impl/codegen/byte_buffer_reader.h \
-    include/grpc/impl/codegen/compression_types.h \
-    include/grpc/impl/codegen/connectivity_state.h \
-    include/grpc/impl/codegen/exec_ctx_fwd.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/atm.h \
-    include/grpc/impl/codegen/atm_gcc_atomic.h \
-    include/grpc/impl/codegen/atm_gcc_sync.h \
-    include/grpc/impl/codegen/atm_windows.h \
-    include/grpc/impl/codegen/gpr_slice.h \
-    include/grpc/impl/codegen/gpr_types.h \
-    include/grpc/impl/codegen/port_platform.h \
-    include/grpc/impl/codegen/slice.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_windows.h \
-    include/grpc++/impl/codegen/proto_utils.h \
-    include/grpc++/impl/codegen/config_protobuf.h \
-
-LIBGRPC++_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_SRC))))
-
-
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure libraries if you don't have OpenSSL.
-
-$(LIBDIR)/$(CONFIG)/libgrpc++.a: openssl_dep_error
-
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): openssl_dep_error
-
-else
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
-
-$(LIBDIR)/$(CONFIG)/libgrpc++.a: protobuf_dep_error
-
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error
-
-else
-
-$(LIBDIR)/$(CONFIG)/libgrpc++.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS) 
-	$(E) "[AR]      Creating $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++.a
-	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBGRPC++_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS) 
-ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++.a
-endif
-
-
-
-ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP)
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc$(SHARED_VERSION_CORE)-dll
-else
-$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc
-else
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so.1
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so
-endif
-endif
-
-endif
-
-endif
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(LIBGRPC++_OBJS:.o=.dep)
-endif
-endif
-
-
-LIBGRPC++_CRONET_SRC = \
-    src/cpp/client/cronet_credentials.cc \
-    src/cpp/client/insecure_credentials.cc \
-    src/cpp/common/insecure_create_auth_context.cc \
-    src/cpp/server/insecure_server_credentials.cc \
-    src/cpp/client/channel_cc.cc \
-    src/cpp/client/client_context.cc \
-    src/cpp/client/create_channel.cc \
-    src/cpp/client/create_channel_internal.cc \
-    src/cpp/client/create_channel_posix.cc \
-    src/cpp/client/credentials_cc.cc \
-    src/cpp/client/generic_stub.cc \
-    src/cpp/common/channel_arguments.cc \
-    src/cpp/common/channel_filter.cc \
-    src/cpp/common/completion_queue_cc.cc \
-    src/cpp/common/core_codegen.cc \
-    src/cpp/common/resource_quota_cc.cc \
-    src/cpp/common/rpc_method.cc \
-    src/cpp/common/version_cc.cc \
-    src/cpp/server/async_generic_service.cc \
-    src/cpp/server/create_default_thread_pool.cc \
-    src/cpp/server/dynamic_thread_pool.cc \
-    src/cpp/server/health/default_health_check_service.cc \
-    src/cpp/server/health/health.pb.c \
-    src/cpp/server/health/health_check_service.cc \
-    src/cpp/server/health/health_check_service_server_builder_option.cc \
-    src/cpp/server/server_builder.cc \
-    src/cpp/server/server_cc.cc \
-    src/cpp/server/server_context.cc \
-    src/cpp/server/server_credentials.cc \
-    src/cpp/server/server_posix.cc \
-    src/cpp/thread_manager/thread_manager.cc \
-    src/cpp/util/byte_buffer_cc.cc \
-    src/cpp/util/slice_cc.cc \
-    src/cpp/util/status.cc \
-    src/cpp/util/string_ref.cc \
-    src/cpp/util/time_cc.cc \
-    src/cpp/codegen/codegen_init.cc \
-    src/core/ext/transport/chttp2/client/insecure/channel_create.c \
-    src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
-    src/core/ext/transport/chttp2/client/chttp2_connector.c \
-    src/core/ext/transport/chttp2/transport/bin_decoder.c \
-    src/core/ext/transport/chttp2/transport/bin_encoder.c \
-    src/core/ext/transport/chttp2/transport/chttp2_plugin.c \
-    src/core/ext/transport/chttp2/transport/chttp2_transport.c \
-    src/core/ext/transport/chttp2/transport/frame_data.c \
-    src/core/ext/transport/chttp2/transport/frame_goaway.c \
-    src/core/ext/transport/chttp2/transport/frame_ping.c \
-    src/core/ext/transport/chttp2/transport/frame_rst_stream.c \
-    src/core/ext/transport/chttp2/transport/frame_settings.c \
-    src/core/ext/transport/chttp2/transport/frame_window_update.c \
-    src/core/ext/transport/chttp2/transport/hpack_encoder.c \
-    src/core/ext/transport/chttp2/transport/hpack_parser.c \
-    src/core/ext/transport/chttp2/transport/hpack_table.c \
-    src/core/ext/transport/chttp2/transport/huffsyms.c \
-    src/core/ext/transport/chttp2/transport/incoming_metadata.c \
-    src/core/ext/transport/chttp2/transport/parsing.c \
-    src/core/ext/transport/chttp2/transport/stream_lists.c \
-    src/core/ext/transport/chttp2/transport/stream_map.c \
-    src/core/ext/transport/chttp2/transport/varint.c \
-    src/core/ext/transport/chttp2/transport/writing.c \
     src/core/lib/channel/channel_args.c \
     src/core/lib/channel/channel_stack.c \
     src/core/lib/channel/channel_stack_builder.c \
-    src/core/lib/channel/compress_filter.c \
     src/core/lib/channel/connected_channel.c \
-    src/core/lib/channel/deadline_filter.c \
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/handshaker_factory.c \
     src/core/lib/channel/handshaker_registry.c \
-    src/core/lib/channel/http_client_filter.c \
-    src/core/lib/channel/http_server_filter.c \
-    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
@@ -4191,6 +4194,7 @@ LIBGRPC++_CRONET_SRC = \
     src/core/lib/iomgr/iomgr_uv.c \
     src/core/lib/iomgr/iomgr_windows.c \
     src/core/lib/iomgr/load_file.c \
+    src/core/lib/iomgr/lockfree_event.c \
     src/core/lib/iomgr/network_status_tracker.c \
     src/core/lib/iomgr/polling_entity.c \
     src/core/lib/iomgr/pollset_set_uv.c \
@@ -4202,6 +4206,7 @@ LIBGRPC++_CRONET_SRC = \
     src/core/lib/iomgr/resolve_address_windows.c \
     src/core/lib/iomgr/resource_quota.c \
     src/core/lib/iomgr/sockaddr_utils.c \
+    src/core/lib/iomgr/socket_factory_posix.c \
     src/core/lib/iomgr/socket_mutator.c \
     src/core/lib/iomgr/socket_utils_common_posix.c \
     src/core/lib/iomgr/socket_utils_linux.c \
@@ -4214,6 +4219,9 @@ LIBGRPC++_CRONET_SRC = \
     src/core/lib/iomgr/tcp_client_windows.c \
     src/core/lib/iomgr/tcp_posix.c \
     src/core/lib/iomgr/tcp_server_posix.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_common.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c \
     src/core/lib/iomgr/tcp_server_uv.c \
     src/core/lib/iomgr/tcp_server_windows.c \
     src/core/lib/iomgr/tcp_uv.c \
@@ -4236,6 +4244,7 @@ LIBGRPC++_CRONET_SRC = \
     src/core/lib/json/json_reader.c \
     src/core/lib/json/json_string.c \
     src/core/lib/json/json_writer.c \
+    src/core/lib/slice/b64.c \
     src/core/lib/slice/percent_encoding.c \
     src/core/lib/slice/slice.c \
     src/core/lib/slice/slice_buffer.c \
@@ -4254,8 +4263,9 @@ LIBGRPC++_CRONET_SRC = \
     src/core/lib/surface/channel_ping.c \
     src/core/lib/surface/channel_stack_type.c \
     src/core/lib/surface/completion_queue.c \
+    src/core/lib/surface/completion_queue_factory.c \
     src/core/lib/surface/event_string.c \
-    src/core/lib/surface/lame_client.c \
+    src/core/lib/surface/lame_client.cc \
     src/core/lib/surface/metadata_array.c \
     src/core/lib/surface/server.c \
     src/core/lib/surface/validate_metadata.c \
@@ -4273,48 +4283,10 @@ LIBGRPC++_CRONET_SRC = \
     src/core/lib/transport/timeout_encoding.c \
     src/core/lib/transport/transport.c \
     src/core/lib/transport/transport_op_string.c \
-    src/core/ext/transport/chttp2/alpn/alpn.c \
-    src/core/ext/client_channel/channel_connectivity.c \
-    src/core/ext/client_channel/client_channel.c \
-    src/core/ext/client_channel/client_channel_factory.c \
-    src/core/ext/client_channel/client_channel_plugin.c \
-    src/core/ext/client_channel/connector.c \
-    src/core/ext/client_channel/default_initial_connect_string.c \
-    src/core/ext/client_channel/http_connect_handshaker.c \
-    src/core/ext/client_channel/http_proxy.c \
-    src/core/ext/client_channel/initial_connect_string.c \
-    src/core/ext/client_channel/lb_policy.c \
-    src/core/ext/client_channel/lb_policy_factory.c \
-    src/core/ext/client_channel/lb_policy_registry.c \
-    src/core/ext/client_channel/parse_address.c \
-    src/core/ext/client_channel/proxy_mapper.c \
-    src/core/ext/client_channel/proxy_mapper_registry.c \
-    src/core/ext/client_channel/resolver.c \
-    src/core/ext/client_channel/resolver_factory.c \
-    src/core/ext/client_channel/resolver_registry.c \
-    src/core/ext/client_channel/subchannel.c \
-    src/core/ext/client_channel/subchannel_index.c \
-    src/core/ext/client_channel/uri_parser.c \
-    src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
-    src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \
-    src/core/ext/transport/chttp2/server/chttp2_server.c \
-    src/core/ext/census/base_resources.c \
-    src/core/ext/census/context.c \
-    src/core/ext/census/gen/census.pb.c \
-    src/core/ext/census/gen/trace_context.pb.c \
-    src/core/ext/census/grpc_context.c \
-    src/core/ext/census/grpc_filter.c \
-    src/core/ext/census/grpc_plugin.c \
-    src/core/ext/census/initialize.c \
-    src/core/ext/census/mlog.c \
-    src/core/ext/census/operation.c \
-    src/core/ext/census/placeholders.c \
-    src/core/ext/census/resource.c \
-    src/core/ext/census/trace_context.c \
-    src/core/ext/census/tracing.c \
     third_party/nanopb/pb_common.c \
     third_party/nanopb/pb_decode.c \
     third_party/nanopb/pb_encode.c \
+    src/cpp/codegen/codegen_init.cc \
 
 PUBLIC_HEADERS_CXX += \
     include/grpc++/alarm.h \
@@ -4329,6 +4301,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/grpc++.h \
     include/grpc++/health_check_service_interface.h \
     include/grpc++/impl/call.h \
+    include/grpc++/impl/channel_argument_option.h \
     include/grpc++/impl/client_unary_call.h \
     include/grpc++/impl/codegen/core_codegen.h \
     include/grpc++/impl/grpc_library.h \
@@ -4386,7 +4359,6 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/impl/codegen/slice.h \
     include/grpc++/impl/codegen/status.h \
     include/grpc++/impl/codegen/status_code_enum.h \
-    include/grpc++/impl/codegen/status_helper.h \
     include/grpc++/impl/codegen/string_ref.h \
     include/grpc++/impl/codegen/stub_options.h \
     include/grpc++/impl/codegen/sync_stream.h \
@@ -4397,6 +4369,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/grpc_types.h \
     include/grpc/impl/codegen/propagation_bits.h \
+    include/grpc/impl/codegen/slice.h \
     include/grpc/impl/codegen/status.h \
     include/grpc/impl/codegen/atm.h \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
@@ -4405,7 +4378,6 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
-    include/grpc/impl/codegen/slice.h \
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_generic.h \
     include/grpc/impl/codegen/sync_posix.h \
@@ -4420,18 +4392,19 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/slice.h \
     include/grpc/slice_buffer.h \
     include/grpc/status.h \
-    include/grpc/census.h \
+    include/grpc++/impl/codegen/proto_utils.h \
+    include/grpc++/impl/codegen/config_protobuf.h \
 
-LIBGRPC++_CRONET_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_CRONET_SRC))))
+LIBGRPC++_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_SRC))))
 
 
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure libraries if you don't have OpenSSL.
 
-$(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a: openssl_dep_error
+$(LIBDIR)/$(CONFIG)/libgrpc++.a: openssl_dep_error
 
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): openssl_dep_error
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): openssl_dep_error
 
 else
 
@@ -4439,159 +4412,629 @@ ifeq ($(NO_PROTOBUF),true)
 
 # You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
 
-$(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a: protobuf_dep_error
+$(LIBDIR)/$(CONFIG)/libgrpc++.a: protobuf_dep_error
 
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_CRONET_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgrpc++.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a
-	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a $(LIBGRPC++_CRONET_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++.a
+	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBGRPC++_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++.a
 endif
 
 
 
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_CRONET_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr$(SHARED_VERSION_CORE)-dll -lgrpc_cronet$(SHARED_VERSION_CORE)-dll
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc$(SHARED_VERSION_CORE)-dll -lgpr$(SHARED_VERSION_CORE)-dll
 else
-$(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_CRONET_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_cronet
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc -lgpr
 else
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_cronet.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_cronet
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).so.1
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).so
-endif
-endif
-
-endif
-
-endif
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(LIBGRPC++_CRONET_OBJS:.o=.dep)
-endif
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc -lgpr
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so.1
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so
 endif
-
-
-LIBGRPC++_PROTO_REFLECTION_DESC_DB_SRC = \
-    test/cpp/util/proto_reflection_descriptor_database.cc \
-    $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc \
-
-PUBLIC_HEADERS_CXX += \
-    include/grpc++/impl/codegen/config_protobuf.h \
-
-LIBGRPC++_PROTO_REFLECTION_DESC_DB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_PROTO_REFLECTION_DESC_DB_SRC))))
-
-
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure libraries if you don't have OpenSSL.
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a: openssl_dep_error
-
-
-else
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a: protobuf_dep_error
-
-
-else
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_PROTO_REFLECTION_DESC_DB_OBJS) 
-	$(E) "[AR]      Creating $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a
-	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBGRPC++_PROTO_REFLECTION_DESC_DB_OBJS) 
-ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a
 endif
 
-
-
-
 endif
 
 endif
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(LIBGRPC++_PROTO_REFLECTION_DESC_DB_OBJS:.o=.dep)
-endif
+-include $(LIBGRPC++_OBJS:.o=.dep)
 endif
-$(OBJDIR)/$(CONFIG)/test/cpp/util/proto_reflection_descriptor_database.o: $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc
-
-
-LIBGRPC++_REFLECTION_SRC = \
-    src/cpp/ext/proto_server_reflection.cc \
-    src/cpp/ext/proto_server_reflection_plugin.cc \
-    $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc \
-
-PUBLIC_HEADERS_CXX += \
-    include/grpc++/ext/proto_server_reflection_plugin.h \
-
-LIBGRPC++_REFLECTION_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_REFLECTION_SRC))))
-
-
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure libraries if you don't have OpenSSL.
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: openssl_dep_error
-
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): openssl_dep_error
-
-else
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: protobuf_dep_error
-
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error
-
-else
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_REFLECTION_OBJS) 
-	$(E) "[AR]      Creating $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a
-	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBGRPC++_REFLECTION_OBJS) 
-ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a
 endif
 
 
-
-ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(OPENSSL_DEP)
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll
-else
-$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(OPENSSL_DEP)
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
+LIBGRPC++_CRONET_SRC = \
+    src/cpp/client/cronet_credentials.cc \
+    src/cpp/client/insecure_credentials.cc \
+    src/cpp/common/insecure_create_auth_context.cc \
+    src/cpp/server/insecure_server_credentials.cc \
+    src/cpp/client/channel_cc.cc \
+    src/cpp/client/client_context.cc \
+    src/cpp/client/create_channel.cc \
+    src/cpp/client/create_channel_internal.cc \
+    src/cpp/client/create_channel_posix.cc \
+    src/cpp/client/credentials_cc.cc \
+    src/cpp/client/generic_stub.cc \
+    src/cpp/common/channel_arguments.cc \
+    src/cpp/common/channel_filter.cc \
+    src/cpp/common/completion_queue_cc.cc \
+    src/cpp/common/core_codegen.cc \
+    src/cpp/common/resource_quota_cc.cc \
+    src/cpp/common/rpc_method.cc \
+    src/cpp/common/version_cc.cc \
+    src/cpp/server/async_generic_service.cc \
+    src/cpp/server/channel_argument_option.cc \
+    src/cpp/server/create_default_thread_pool.cc \
+    src/cpp/server/dynamic_thread_pool.cc \
+    src/cpp/server/health/default_health_check_service.cc \
+    src/cpp/server/health/health.pb.c \
+    src/cpp/server/health/health_check_service.cc \
+    src/cpp/server/health/health_check_service_server_builder_option.cc \
+    src/cpp/server/server_builder.cc \
+    src/cpp/server/server_cc.cc \
+    src/cpp/server/server_context.cc \
+    src/cpp/server/server_credentials.cc \
+    src/cpp/server/server_posix.cc \
+    src/cpp/thread_manager/thread_manager.cc \
+    src/cpp/util/byte_buffer_cc.cc \
+    src/cpp/util/slice_cc.cc \
+    src/cpp/util/status.cc \
+    src/cpp/util/string_ref.cc \
+    src/cpp/util/time_cc.cc \
+    src/core/lib/channel/channel_args.c \
+    src/core/lib/channel/channel_stack.c \
+    src/core/lib/channel/channel_stack_builder.c \
+    src/core/lib/channel/connected_channel.c \
+    src/core/lib/channel/handshaker.c \
+    src/core/lib/channel/handshaker_factory.c \
+    src/core/lib/channel/handshaker_registry.c \
+    src/core/lib/compression/compression.c \
+    src/core/lib/compression/message_compress.c \
+    src/core/lib/debug/trace.c \
+    src/core/lib/http/format_request.c \
+    src/core/lib/http/httpcli.c \
+    src/core/lib/http/parser.c \
+    src/core/lib/iomgr/closure.c \
+    src/core/lib/iomgr/combiner.c \
+    src/core/lib/iomgr/endpoint.c \
+    src/core/lib/iomgr/endpoint_pair_posix.c \
+    src/core/lib/iomgr/endpoint_pair_uv.c \
+    src/core/lib/iomgr/endpoint_pair_windows.c \
+    src/core/lib/iomgr/error.c \
+    src/core/lib/iomgr/ev_epoll_linux.c \
+    src/core/lib/iomgr/ev_poll_posix.c \
+    src/core/lib/iomgr/ev_posix.c \
+    src/core/lib/iomgr/exec_ctx.c \
+    src/core/lib/iomgr/executor.c \
+    src/core/lib/iomgr/iocp_windows.c \
+    src/core/lib/iomgr/iomgr.c \
+    src/core/lib/iomgr/iomgr_posix.c \
+    src/core/lib/iomgr/iomgr_uv.c \
+    src/core/lib/iomgr/iomgr_windows.c \
+    src/core/lib/iomgr/load_file.c \
+    src/core/lib/iomgr/lockfree_event.c \
+    src/core/lib/iomgr/network_status_tracker.c \
+    src/core/lib/iomgr/polling_entity.c \
+    src/core/lib/iomgr/pollset_set_uv.c \
+    src/core/lib/iomgr/pollset_set_windows.c \
+    src/core/lib/iomgr/pollset_uv.c \
+    src/core/lib/iomgr/pollset_windows.c \
+    src/core/lib/iomgr/resolve_address_posix.c \
+    src/core/lib/iomgr/resolve_address_uv.c \
+    src/core/lib/iomgr/resolve_address_windows.c \
+    src/core/lib/iomgr/resource_quota.c \
+    src/core/lib/iomgr/sockaddr_utils.c \
+    src/core/lib/iomgr/socket_factory_posix.c \
+    src/core/lib/iomgr/socket_mutator.c \
+    src/core/lib/iomgr/socket_utils_common_posix.c \
+    src/core/lib/iomgr/socket_utils_linux.c \
+    src/core/lib/iomgr/socket_utils_posix.c \
+    src/core/lib/iomgr/socket_utils_uv.c \
+    src/core/lib/iomgr/socket_utils_windows.c \
+    src/core/lib/iomgr/socket_windows.c \
+    src/core/lib/iomgr/tcp_client_posix.c \
+    src/core/lib/iomgr/tcp_client_uv.c \
+    src/core/lib/iomgr/tcp_client_windows.c \
+    src/core/lib/iomgr/tcp_posix.c \
+    src/core/lib/iomgr/tcp_server_posix.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_common.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c \
+    src/core/lib/iomgr/tcp_server_uv.c \
+    src/core/lib/iomgr/tcp_server_windows.c \
+    src/core/lib/iomgr/tcp_uv.c \
+    src/core/lib/iomgr/tcp_windows.c \
+    src/core/lib/iomgr/time_averaged_stats.c \
+    src/core/lib/iomgr/timer_generic.c \
+    src/core/lib/iomgr/timer_heap.c \
+    src/core/lib/iomgr/timer_uv.c \
+    src/core/lib/iomgr/udp_server.c \
+    src/core/lib/iomgr/unix_sockets_posix.c \
+    src/core/lib/iomgr/unix_sockets_posix_noop.c \
+    src/core/lib/iomgr/wakeup_fd_cv.c \
+    src/core/lib/iomgr/wakeup_fd_eventfd.c \
+    src/core/lib/iomgr/wakeup_fd_nospecial.c \
+    src/core/lib/iomgr/wakeup_fd_pipe.c \
+    src/core/lib/iomgr/wakeup_fd_posix.c \
+    src/core/lib/iomgr/workqueue_uv.c \
+    src/core/lib/iomgr/workqueue_windows.c \
+    src/core/lib/json/json.c \
+    src/core/lib/json/json_reader.c \
+    src/core/lib/json/json_string.c \
+    src/core/lib/json/json_writer.c \
+    src/core/lib/slice/b64.c \
+    src/core/lib/slice/percent_encoding.c \
+    src/core/lib/slice/slice.c \
+    src/core/lib/slice/slice_buffer.c \
+    src/core/lib/slice/slice_hash_table.c \
+    src/core/lib/slice/slice_intern.c \
+    src/core/lib/slice/slice_string_helpers.c \
+    src/core/lib/surface/alarm.c \
+    src/core/lib/surface/api_trace.c \
+    src/core/lib/surface/byte_buffer.c \
+    src/core/lib/surface/byte_buffer_reader.c \
+    src/core/lib/surface/call.c \
+    src/core/lib/surface/call_details.c \
+    src/core/lib/surface/call_log_batch.c \
+    src/core/lib/surface/channel.c \
+    src/core/lib/surface/channel_init.c \
+    src/core/lib/surface/channel_ping.c \
+    src/core/lib/surface/channel_stack_type.c \
+    src/core/lib/surface/completion_queue.c \
+    src/core/lib/surface/completion_queue_factory.c \
+    src/core/lib/surface/event_string.c \
+    src/core/lib/surface/lame_client.cc \
+    src/core/lib/surface/metadata_array.c \
+    src/core/lib/surface/server.c \
+    src/core/lib/surface/validate_metadata.c \
+    src/core/lib/surface/version.c \
+    src/core/lib/transport/bdp_estimator.c \
+    src/core/lib/transport/byte_stream.c \
+    src/core/lib/transport/connectivity_state.c \
+    src/core/lib/transport/error_utils.c \
+    src/core/lib/transport/metadata.c \
+    src/core/lib/transport/metadata_batch.c \
+    src/core/lib/transport/pid_controller.c \
+    src/core/lib/transport/service_config.c \
+    src/core/lib/transport/static_metadata.c \
+    src/core/lib/transport/status_conversion.c \
+    src/core/lib/transport/timeout_encoding.c \
+    src/core/lib/transport/transport.c \
+    src/core/lib/transport/transport_op_string.c \
+    third_party/nanopb/pb_common.c \
+    third_party/nanopb/pb_decode.c \
+    third_party/nanopb/pb_encode.c \
+    src/cpp/codegen/codegen_init.cc \
+    src/core/ext/transport/chttp2/client/insecure/channel_create.c \
+    src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
+    src/core/ext/transport/chttp2/client/chttp2_connector.c \
+    src/core/ext/transport/chttp2/transport/bin_decoder.c \
+    src/core/ext/transport/chttp2/transport/bin_encoder.c \
+    src/core/ext/transport/chttp2/transport/chttp2_plugin.c \
+    src/core/ext/transport/chttp2/transport/chttp2_transport.c \
+    src/core/ext/transport/chttp2/transport/frame_data.c \
+    src/core/ext/transport/chttp2/transport/frame_goaway.c \
+    src/core/ext/transport/chttp2/transport/frame_ping.c \
+    src/core/ext/transport/chttp2/transport/frame_rst_stream.c \
+    src/core/ext/transport/chttp2/transport/frame_settings.c \
+    src/core/ext/transport/chttp2/transport/frame_window_update.c \
+    src/core/ext/transport/chttp2/transport/hpack_encoder.c \
+    src/core/ext/transport/chttp2/transport/hpack_parser.c \
+    src/core/ext/transport/chttp2/transport/hpack_table.c \
+    src/core/ext/transport/chttp2/transport/http2_settings.c \
+    src/core/ext/transport/chttp2/transport/huffsyms.c \
+    src/core/ext/transport/chttp2/transport/incoming_metadata.c \
+    src/core/ext/transport/chttp2/transport/parsing.c \
+    src/core/ext/transport/chttp2/transport/stream_lists.c \
+    src/core/ext/transport/chttp2/transport/stream_map.c \
+    src/core/ext/transport/chttp2/transport/varint.c \
+    src/core/ext/transport/chttp2/transport/writing.c \
+    src/core/ext/transport/chttp2/alpn/alpn.c \
+    src/core/ext/filters/http/client/http_client_filter.c \
+    src/core/ext/filters/http/http_filters_plugin.c \
+    src/core/ext/filters/http/message_compress/message_compress_filter.c \
+    src/core/ext/filters/http/server/http_server_filter.c \
+    src/core/ext/filters/client_channel/channel_connectivity.c \
+    src/core/ext/filters/client_channel/client_channel.c \
+    src/core/ext/filters/client_channel/client_channel_factory.c \
+    src/core/ext/filters/client_channel/client_channel_plugin.c \
+    src/core/ext/filters/client_channel/connector.c \
+    src/core/ext/filters/client_channel/http_connect_handshaker.c \
+    src/core/ext/filters/client_channel/http_proxy.c \
+    src/core/ext/filters/client_channel/lb_policy.c \
+    src/core/ext/filters/client_channel/lb_policy_factory.c \
+    src/core/ext/filters/client_channel/lb_policy_registry.c \
+    src/core/ext/filters/client_channel/parse_address.c \
+    src/core/ext/filters/client_channel/proxy_mapper.c \
+    src/core/ext/filters/client_channel/proxy_mapper_registry.c \
+    src/core/ext/filters/client_channel/resolver.c \
+    src/core/ext/filters/client_channel/resolver_factory.c \
+    src/core/ext/filters/client_channel/resolver_registry.c \
+    src/core/ext/filters/client_channel/retry_throttle.c \
+    src/core/ext/filters/client_channel/subchannel.c \
+    src/core/ext/filters/client_channel/subchannel_index.c \
+    src/core/ext/filters/client_channel/uri_parser.c \
+    src/core/ext/filters/deadline/deadline_filter.c \
+    src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
+    src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \
+    src/core/ext/transport/chttp2/server/chttp2_server.c \
+    src/core/ext/census/base_resources.c \
+    src/core/ext/census/context.c \
+    src/core/ext/census/gen/census.pb.c \
+    src/core/ext/census/gen/trace_context.pb.c \
+    src/core/ext/census/grpc_context.c \
+    src/core/ext/census/grpc_filter.c \
+    src/core/ext/census/grpc_plugin.c \
+    src/core/ext/census/initialize.c \
+    src/core/ext/census/mlog.c \
+    src/core/ext/census/operation.c \
+    src/core/ext/census/placeholders.c \
+    src/core/ext/census/resource.c \
+    src/core/ext/census/trace_context.c \
+    src/core/ext/census/tracing.c \
+
+PUBLIC_HEADERS_CXX += \
+    include/grpc++/alarm.h \
+    include/grpc++/channel.h \
+    include/grpc++/client_context.h \
+    include/grpc++/completion_queue.h \
+    include/grpc++/create_channel.h \
+    include/grpc++/create_channel_posix.h \
+    include/grpc++/ext/health_check_service_server_builder_option.h \
+    include/grpc++/generic/async_generic_service.h \
+    include/grpc++/generic/generic_stub.h \
+    include/grpc++/grpc++.h \
+    include/grpc++/health_check_service_interface.h \
+    include/grpc++/impl/call.h \
+    include/grpc++/impl/channel_argument_option.h \
+    include/grpc++/impl/client_unary_call.h \
+    include/grpc++/impl/codegen/core_codegen.h \
+    include/grpc++/impl/grpc_library.h \
+    include/grpc++/impl/method_handler_impl.h \
+    include/grpc++/impl/rpc_method.h \
+    include/grpc++/impl/rpc_service_method.h \
+    include/grpc++/impl/serialization_traits.h \
+    include/grpc++/impl/server_builder_option.h \
+    include/grpc++/impl/server_builder_plugin.h \
+    include/grpc++/impl/server_initializer.h \
+    include/grpc++/impl/service_type.h \
+    include/grpc++/resource_quota.h \
+    include/grpc++/security/auth_context.h \
+    include/grpc++/security/auth_metadata_processor.h \
+    include/grpc++/security/credentials.h \
+    include/grpc++/security/server_credentials.h \
+    include/grpc++/server.h \
+    include/grpc++/server_builder.h \
+    include/grpc++/server_context.h \
+    include/grpc++/server_posix.h \
+    include/grpc++/support/async_stream.h \
+    include/grpc++/support/async_unary_call.h \
+    include/grpc++/support/byte_buffer.h \
+    include/grpc++/support/channel_arguments.h \
+    include/grpc++/support/config.h \
+    include/grpc++/support/slice.h \
+    include/grpc++/support/status.h \
+    include/grpc++/support/status_code_enum.h \
+    include/grpc++/support/string_ref.h \
+    include/grpc++/support/stub_options.h \
+    include/grpc++/support/sync_stream.h \
+    include/grpc++/support/time.h \
+    include/grpc++/impl/codegen/async_stream.h \
+    include/grpc++/impl/codegen/async_unary_call.h \
+    include/grpc++/impl/codegen/call.h \
+    include/grpc++/impl/codegen/call_hook.h \
+    include/grpc++/impl/codegen/channel_interface.h \
+    include/grpc++/impl/codegen/client_context.h \
+    include/grpc++/impl/codegen/client_unary_call.h \
+    include/grpc++/impl/codegen/completion_queue.h \
+    include/grpc++/impl/codegen/completion_queue_tag.h \
+    include/grpc++/impl/codegen/config.h \
+    include/grpc++/impl/codegen/core_codegen_interface.h \
+    include/grpc++/impl/codegen/create_auth_context.h \
+    include/grpc++/impl/codegen/grpc_library.h \
+    include/grpc++/impl/codegen/metadata_map.h \
+    include/grpc++/impl/codegen/method_handler_impl.h \
+    include/grpc++/impl/codegen/rpc_method.h \
+    include/grpc++/impl/codegen/rpc_service_method.h \
+    include/grpc++/impl/codegen/security/auth_context.h \
+    include/grpc++/impl/codegen/serialization_traits.h \
+    include/grpc++/impl/codegen/server_context.h \
+    include/grpc++/impl/codegen/server_interface.h \
+    include/grpc++/impl/codegen/service_type.h \
+    include/grpc++/impl/codegen/slice.h \
+    include/grpc++/impl/codegen/status.h \
+    include/grpc++/impl/codegen/status_code_enum.h \
+    include/grpc++/impl/codegen/string_ref.h \
+    include/grpc++/impl/codegen/stub_options.h \
+    include/grpc++/impl/codegen/sync_stream.h \
+    include/grpc++/impl/codegen/time.h \
+    include/grpc/impl/codegen/byte_buffer_reader.h \
+    include/grpc/impl/codegen/compression_types.h \
+    include/grpc/impl/codegen/connectivity_state.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
+    include/grpc/impl/codegen/grpc_types.h \
+    include/grpc/impl/codegen/propagation_bits.h \
+    include/grpc/impl/codegen/slice.h \
+    include/grpc/impl/codegen/status.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_windows.h \
+    include/grpc/impl/codegen/gpr_slice.h \
+    include/grpc/impl/codegen/gpr_types.h \
+    include/grpc/impl/codegen/port_platform.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_windows.h \
+    include/grpc/byte_buffer.h \
+    include/grpc/byte_buffer_reader.h \
+    include/grpc/compression.h \
+    include/grpc/grpc.h \
+    include/grpc/grpc_posix.h \
+    include/grpc/grpc_security_constants.h \
+    include/grpc/load_reporting.h \
+    include/grpc/slice.h \
+    include/grpc/slice_buffer.h \
+    include/grpc/status.h \
+    include/grpc/census.h \
+
+LIBGRPC++_CRONET_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_CRONET_SRC))))
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL.
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a: openssl_dep_error
+
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): openssl_dep_error
+
+else
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a: protobuf_dep_error
+
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error
+
+else
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_CRONET_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a
+	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a $(LIBGRPC++_CRONET_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a
+endif
+
+
+
+ifeq ($(SYSTEM),MINGW32)
+$(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_CRONET_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr$(SHARED_VERSION_CORE)-dll -lgrpc_cronet$(SHARED_VERSION_CORE)-dll
+else
+$(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_CRONET_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+ifeq ($(SYSTEM),Darwin)
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_cronet
+else
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_cronet.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_cronet
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).so.1
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).so
+endif
+endif
+
+endif
+
+endif
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPC++_CRONET_OBJS:.o=.dep)
+endif
+endif
+
+
+LIBGRPC++_ERROR_DETAILS_SRC = \
+    $(GENDIR)/src/proto/grpc/status/status.pb.cc $(GENDIR)/src/proto/grpc/status/status.grpc.pb.cc \
+    src/cpp/util/error_details.cc \
+
+PUBLIC_HEADERS_CXX += \
+    include/grpc++/support/error_details.h \
+
+LIBGRPC++_ERROR_DETAILS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_ERROR_DETAILS_SRC))))
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL.
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a: openssl_dep_error
+
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): openssl_dep_error
+
+else
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a: protobuf_dep_error
+
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error
+
+else
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_ERROR_DETAILS_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS) 
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a
+	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBGRPC++_ERROR_DETAILS_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a
+endif
+
+
+
+ifeq ($(SYSTEM),MINGW32)
+$(LIBDIR)/$(CONFIG)/grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ERROR_DETAILS_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(OPENSSL_DEP)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_error_details$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll
+else
+$(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ERROR_DETAILS_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(OPENSSL_DEP)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+ifeq ($(SYSTEM),Darwin)
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++
+else
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_error_details.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).so.1
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).so
+endif
+endif
+
+endif
+
+endif
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPC++_ERROR_DETAILS_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/src/cpp/util/error_details.o: $(GENDIR)/src/proto/grpc/status/status.pb.cc $(GENDIR)/src/proto/grpc/status/status.grpc.pb.cc
+
+
+LIBGRPC++_PROTO_REFLECTION_DESC_DB_SRC = \
+    test/cpp/util/proto_reflection_descriptor_database.cc \
+    $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc \
+
+PUBLIC_HEADERS_CXX += \
+    include/grpc++/impl/codegen/config_protobuf.h \
+
+LIBGRPC++_PROTO_REFLECTION_DESC_DB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_PROTO_REFLECTION_DESC_DB_SRC))))
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL.
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a: openssl_dep_error
+
+
+else
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a: protobuf_dep_error
+
+
+else
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_PROTO_REFLECTION_DESC_DB_OBJS) 
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a
+	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBGRPC++_PROTO_REFLECTION_DESC_DB_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a
+endif
+
+
+
+
+endif
+
+endif
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPC++_PROTO_REFLECTION_DESC_DB_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/test/cpp/util/proto_reflection_descriptor_database.o: $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc
+
+
+LIBGRPC++_REFLECTION_SRC = \
+    src/cpp/ext/proto_server_reflection.cc \
+    src/cpp/ext/proto_server_reflection_plugin.cc \
+    $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc \
+
+PUBLIC_HEADERS_CXX += \
+    include/grpc++/ext/proto_server_reflection_plugin.h \
+
+LIBGRPC++_REFLECTION_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_REFLECTION_SRC))))
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL.
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: openssl_dep_error
+
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): openssl_dep_error
+
+else
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: protobuf_dep_error
+
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error
+
+else
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_REFLECTION_OBJS) 
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a
+	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBGRPC++_REFLECTION_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a
+endif
+
+
+
+ifeq ($(SYSTEM),MINGW32)
+$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(OPENSSL_DEP)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll
+else
+$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(OPENSSL_DEP)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++
 else
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_reflection.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_reflection.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so.1
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so
 endif
@@ -4636,7 +5079,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_TEST_CONFIG_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_TEST_CONFIG_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
@@ -4698,7 +5141,6 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/impl/codegen/slice.h \
     include/grpc++/impl/codegen/status.h \
     include/grpc++/impl/codegen/status_code_enum.h \
-    include/grpc++/impl/codegen/status_helper.h \
     include/grpc++/impl/codegen/string_ref.h \
     include/grpc++/impl/codegen/stub_options.h \
     include/grpc++/impl/codegen/sync_stream.h \
@@ -4709,6 +5151,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/grpc_types.h \
     include/grpc/impl/codegen/propagation_bits.h \
+    include/grpc/impl/codegen/slice.h \
     include/grpc/impl/codegen/status.h \
     include/grpc/impl/codegen/atm.h \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
@@ -4717,15 +5160,12 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
-    include/grpc/impl/codegen/slice.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_windows.h \
     include/grpc++/impl/codegen/proto_utils.h \
     include/grpc++/impl/codegen/config_protobuf.h \
-    include/grpc++/impl/codegen/thrift_serializer.h \
-    include/grpc++/impl/codegen/thrift_utils.h \
 
 LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC))))
 
@@ -4748,7 +5188,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_TEST_UTIL_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_TEST_UTIL_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a
@@ -4797,6 +5237,7 @@ LIBGRPC++_UNSECURE_SRC = \
     src/cpp/common/rpc_method.cc \
     src/cpp/common/version_cc.cc \
     src/cpp/server/async_generic_service.cc \
+    src/cpp/server/channel_argument_option.cc \
     src/cpp/server/create_default_thread_pool.cc \
     src/cpp/server/dynamic_thread_pool.cc \
     src/cpp/server/health/default_health_check_service.cc \
@@ -4814,6 +5255,129 @@ LIBGRPC++_UNSECURE_SRC = \
     src/cpp/util/status.cc \
     src/cpp/util/string_ref.cc \
     src/cpp/util/time_cc.cc \
+    src/core/lib/channel/channel_args.c \
+    src/core/lib/channel/channel_stack.c \
+    src/core/lib/channel/channel_stack_builder.c \
+    src/core/lib/channel/connected_channel.c \
+    src/core/lib/channel/handshaker.c \
+    src/core/lib/channel/handshaker_factory.c \
+    src/core/lib/channel/handshaker_registry.c \
+    src/core/lib/compression/compression.c \
+    src/core/lib/compression/message_compress.c \
+    src/core/lib/debug/trace.c \
+    src/core/lib/http/format_request.c \
+    src/core/lib/http/httpcli.c \
+    src/core/lib/http/parser.c \
+    src/core/lib/iomgr/closure.c \
+    src/core/lib/iomgr/combiner.c \
+    src/core/lib/iomgr/endpoint.c \
+    src/core/lib/iomgr/endpoint_pair_posix.c \
+    src/core/lib/iomgr/endpoint_pair_uv.c \
+    src/core/lib/iomgr/endpoint_pair_windows.c \
+    src/core/lib/iomgr/error.c \
+    src/core/lib/iomgr/ev_epoll_linux.c \
+    src/core/lib/iomgr/ev_poll_posix.c \
+    src/core/lib/iomgr/ev_posix.c \
+    src/core/lib/iomgr/exec_ctx.c \
+    src/core/lib/iomgr/executor.c \
+    src/core/lib/iomgr/iocp_windows.c \
+    src/core/lib/iomgr/iomgr.c \
+    src/core/lib/iomgr/iomgr_posix.c \
+    src/core/lib/iomgr/iomgr_uv.c \
+    src/core/lib/iomgr/iomgr_windows.c \
+    src/core/lib/iomgr/load_file.c \
+    src/core/lib/iomgr/lockfree_event.c \
+    src/core/lib/iomgr/network_status_tracker.c \
+    src/core/lib/iomgr/polling_entity.c \
+    src/core/lib/iomgr/pollset_set_uv.c \
+    src/core/lib/iomgr/pollset_set_windows.c \
+    src/core/lib/iomgr/pollset_uv.c \
+    src/core/lib/iomgr/pollset_windows.c \
+    src/core/lib/iomgr/resolve_address_posix.c \
+    src/core/lib/iomgr/resolve_address_uv.c \
+    src/core/lib/iomgr/resolve_address_windows.c \
+    src/core/lib/iomgr/resource_quota.c \
+    src/core/lib/iomgr/sockaddr_utils.c \
+    src/core/lib/iomgr/socket_factory_posix.c \
+    src/core/lib/iomgr/socket_mutator.c \
+    src/core/lib/iomgr/socket_utils_common_posix.c \
+    src/core/lib/iomgr/socket_utils_linux.c \
+    src/core/lib/iomgr/socket_utils_posix.c \
+    src/core/lib/iomgr/socket_utils_uv.c \
+    src/core/lib/iomgr/socket_utils_windows.c \
+    src/core/lib/iomgr/socket_windows.c \
+    src/core/lib/iomgr/tcp_client_posix.c \
+    src/core/lib/iomgr/tcp_client_uv.c \
+    src/core/lib/iomgr/tcp_client_windows.c \
+    src/core/lib/iomgr/tcp_posix.c \
+    src/core/lib/iomgr/tcp_server_posix.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_common.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c \
+    src/core/lib/iomgr/tcp_server_uv.c \
+    src/core/lib/iomgr/tcp_server_windows.c \
+    src/core/lib/iomgr/tcp_uv.c \
+    src/core/lib/iomgr/tcp_windows.c \
+    src/core/lib/iomgr/time_averaged_stats.c \
+    src/core/lib/iomgr/timer_generic.c \
+    src/core/lib/iomgr/timer_heap.c \
+    src/core/lib/iomgr/timer_uv.c \
+    src/core/lib/iomgr/udp_server.c \
+    src/core/lib/iomgr/unix_sockets_posix.c \
+    src/core/lib/iomgr/unix_sockets_posix_noop.c \
+    src/core/lib/iomgr/wakeup_fd_cv.c \
+    src/core/lib/iomgr/wakeup_fd_eventfd.c \
+    src/core/lib/iomgr/wakeup_fd_nospecial.c \
+    src/core/lib/iomgr/wakeup_fd_pipe.c \
+    src/core/lib/iomgr/wakeup_fd_posix.c \
+    src/core/lib/iomgr/workqueue_uv.c \
+    src/core/lib/iomgr/workqueue_windows.c \
+    src/core/lib/json/json.c \
+    src/core/lib/json/json_reader.c \
+    src/core/lib/json/json_string.c \
+    src/core/lib/json/json_writer.c \
+    src/core/lib/slice/b64.c \
+    src/core/lib/slice/percent_encoding.c \
+    src/core/lib/slice/slice.c \
+    src/core/lib/slice/slice_buffer.c \
+    src/core/lib/slice/slice_hash_table.c \
+    src/core/lib/slice/slice_intern.c \
+    src/core/lib/slice/slice_string_helpers.c \
+    src/core/lib/surface/alarm.c \
+    src/core/lib/surface/api_trace.c \
+    src/core/lib/surface/byte_buffer.c \
+    src/core/lib/surface/byte_buffer_reader.c \
+    src/core/lib/surface/call.c \
+    src/core/lib/surface/call_details.c \
+    src/core/lib/surface/call_log_batch.c \
+    src/core/lib/surface/channel.c \
+    src/core/lib/surface/channel_init.c \
+    src/core/lib/surface/channel_ping.c \
+    src/core/lib/surface/channel_stack_type.c \
+    src/core/lib/surface/completion_queue.c \
+    src/core/lib/surface/completion_queue_factory.c \
+    src/core/lib/surface/event_string.c \
+    src/core/lib/surface/lame_client.cc \
+    src/core/lib/surface/metadata_array.c \
+    src/core/lib/surface/server.c \
+    src/core/lib/surface/validate_metadata.c \
+    src/core/lib/surface/version.c \
+    src/core/lib/transport/bdp_estimator.c \
+    src/core/lib/transport/byte_stream.c \
+    src/core/lib/transport/connectivity_state.c \
+    src/core/lib/transport/error_utils.c \
+    src/core/lib/transport/metadata.c \
+    src/core/lib/transport/metadata_batch.c \
+    src/core/lib/transport/pid_controller.c \
+    src/core/lib/transport/service_config.c \
+    src/core/lib/transport/static_metadata.c \
+    src/core/lib/transport/status_conversion.c \
+    src/core/lib/transport/timeout_encoding.c \
+    src/core/lib/transport/transport.c \
+    src/core/lib/transport/transport_op_string.c \
+    third_party/nanopb/pb_common.c \
+    third_party/nanopb/pb_decode.c \
+    third_party/nanopb/pb_encode.c \
     src/cpp/codegen/codegen_init.cc \
 
 PUBLIC_HEADERS_CXX += \
@@ -4829,6 +5393,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/grpc++.h \
     include/grpc++/health_check_service_interface.h \
     include/grpc++/impl/call.h \
+    include/grpc++/impl/channel_argument_option.h \
     include/grpc++/impl/client_unary_call.h \
     include/grpc++/impl/codegen/core_codegen.h \
     include/grpc++/impl/grpc_library.h \
@@ -4886,7 +5451,6 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/impl/codegen/slice.h \
     include/grpc++/impl/codegen/status.h \
     include/grpc++/impl/codegen/status_code_enum.h \
-    include/grpc++/impl/codegen/status_helper.h \
     include/grpc++/impl/codegen/string_ref.h \
     include/grpc++/impl/codegen/stub_options.h \
     include/grpc++/impl/codegen/sync_stream.h \
@@ -4897,6 +5461,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/grpc_types.h \
     include/grpc/impl/codegen/propagation_bits.h \
+    include/grpc/impl/codegen/slice.h \
     include/grpc/impl/codegen/status.h \
     include/grpc/impl/codegen/atm.h \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
@@ -4905,11 +5470,20 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
-    include/grpc/impl/codegen/slice.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_windows.h \
+    include/grpc/byte_buffer.h \
+    include/grpc/byte_buffer_reader.h \
+    include/grpc/compression.h \
+    include/grpc/grpc.h \
+    include/grpc/grpc_posix.h \
+    include/grpc/grpc_security_constants.h \
+    include/grpc/load_reporting.h \
+    include/grpc/slice.h \
+    include/grpc/slice_buffer.h \
+    include/grpc/status.h \
 
 LIBGRPC++_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_UNSECURE_SRC))))
 
@@ -4924,11 +5498,11 @@ $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARE
 
 else
 
-$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBGRPC++_UNSECURE_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBGRPC++_UNSECURE_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
-	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBGRPC++_UNSECURE_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS) 
+	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBGRPC++_UNSECURE_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS) 
 ifeq ($(SYSTEM),Darwin)
 	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
 endif
@@ -4936,18 +5510,18 @@ endif
 
 
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
+$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr$(SHARED_VERSION_CORE)-dll -lgrpc_unsecure$(SHARED_VERSION_CORE)-dll
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr$(SHARED_VERSION_CORE)-dll -lgrpc_unsecure$(SHARED_VERSION_CORE)-dll
 else
-$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT_CORE)
+$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT_CORE)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_unsecure
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_unsecure
 else
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_unsecure
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_unsecure
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so.1
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so
 endif
@@ -4960,6 +5534,56 @@ ifneq ($(NO_DEPS),true)
 endif
 
 
+LIBGRPC_BENCHMARK_SRC = \
+    test/cpp/microbenchmarks/helpers.cc \
+
+PUBLIC_HEADERS_CXX += \
+
+LIBGRPC_BENCHMARK_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_BENCHMARK_SRC))))
+
+$(LIBGRPC_BENCHMARK_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL.
+
+$(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a: openssl_dep_error
+
+
+else
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+
+$(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a: protobuf_dep_error
+
+
+else
+
+$(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBGRPC_BENCHMARK_OBJS) 
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a
+	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBGRPC_BENCHMARK_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a
+endif
+
+
+
+
+endif
+
+endif
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPC_BENCHMARK_OBJS:.o=.dep)
+endif
+endif
+
+
 LIBGRPC_CLI_LIBS_SRC = \
     test/cpp/util/cli_call.cc \
     test/cpp/util/cli_credentials.cc \
@@ -4992,7 +5616,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC_CLI_LIBS_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBGRPC_CLI_LIBS_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a
@@ -5044,7 +5668,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBGRPC_PLUGIN_SUPPORT_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBGRPC_PLUGIN_SUPPORT_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
@@ -5092,7 +5716,7 @@ $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libhttp2_client_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBHTTP2_CLIENT_MAIN_OBJS) 
+$(LIBDIR)/$(CONFIG)/libhttp2_client_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBHTTP2_CLIENT_MAIN_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a
@@ -5143,7 +5767,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libinterop_client_helper.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_CLIENT_HELPER_OBJS) 
+$(LIBDIR)/$(CONFIG)/libinterop_client_helper.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_CLIENT_HELPER_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a
@@ -5197,7 +5821,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_client_main.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libinterop_client_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_CLIENT_MAIN_OBJS) 
+$(LIBDIR)/$(CONFIG)/libinterop_client_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_CLIENT_MAIN_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_client_main.a
@@ -5248,7 +5872,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libinterop_server_helper.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_SERVER_HELPER_OBJS) 
+$(LIBDIR)/$(CONFIG)/libinterop_server_helper.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_SERVER_HELPER_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a
@@ -5300,7 +5924,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_SERVER_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_SERVER_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a
@@ -5350,7 +5974,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_server_main.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libinterop_server_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_SERVER_MAIN_OBJS) 
+$(LIBDIR)/$(CONFIG)/libinterop_server_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_SERVER_MAIN_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_server_main.a
@@ -5379,6 +6003,7 @@ LIBQPS_SRC = \
     $(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 \
+    test/cpp/qps/benchmark_config.cc \
     test/cpp/qps/client_async.cc \
     test/cpp/qps/client_sync.cc \
     test/cpp/qps/driver.cc \
@@ -5388,7 +6013,6 @@ LIBQPS_SRC = \
     test/cpp/qps/server_async.cc \
     test/cpp/qps/server_sync.cc \
     test/cpp/qps/usage_timer.cc \
-    test/cpp/util/benchmark_config.cc \
 
 PUBLIC_HEADERS_CXX += \
 
@@ -5413,7 +6037,7 @@ $(LIBDIR)/$(CONFIG)/libqps.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libqps.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBQPS_OBJS) 
+$(LIBDIR)/$(CONFIG)/libqps.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBQPS_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libqps.a
@@ -5434,6 +6058,7 @@ ifneq ($(NO_DEPS),true)
 -include $(LIBQPS_OBJS:.o=.dep)
 endif
 endif
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/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
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/client_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
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/client_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
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.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
@@ -5443,7 +6068,6 @@ $(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/src/proto/grpc/testing/mess
 $(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
 $(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
 $(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
-$(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
 
 
 LIBGRPC_CSHARP_EXT_SRC = \
@@ -5465,7 +6089,7 @@ $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SH
 else
 
 
-$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_CSHARP_EXT_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(LIBGRPC_CSHARP_EXT_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a
@@ -5477,18 +6101,18 @@ endif
 
 
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP): $(LIBGRPC_CSHARP_EXT_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP): $(LIBGRPC_CSHARP_EXT_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(LDLIBS)
+	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
 else
-$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP): $(LIBGRPC_CSHARP_EXT_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP): $(LIBGRPC_CSHARP_EXT_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(LDLIBS)
+	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
 else
-	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(LDLIBS)
+	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).so.1
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).so
 endif
@@ -5816,7 +6440,7 @@ LIBBORINGSSL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename
 $(LIBBORINGSSL_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
 $(LIBBORINGSSL_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
-$(LIBDIR)/$(CONFIG)/libboringssl.a: $(ZLIB_DEP)  $(LIBBORINGSSL_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl.a: $(ZLIB_DEP) $(CARES_DEP)  $(LIBBORINGSSL_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl.a
@@ -5854,7 +6478,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_test_util.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_TEST_UTIL_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_test_util.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_TEST_UTIL_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a
@@ -5892,7 +6516,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_AES_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_AES_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a
@@ -5930,7 +6554,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ASN1_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ASN1_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a
@@ -5968,7 +6592,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_BASE64_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_BASE64_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a
@@ -6006,7 +6630,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_BIO_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_BIO_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a
@@ -6044,7 +6668,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_BN_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_BN_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a
@@ -6082,7 +6706,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a
@@ -6120,7 +6744,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_CHACHA_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_CHACHA_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a
@@ -6158,7 +6782,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_AEAD_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_AEAD_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a
@@ -6196,7 +6820,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a
@@ -6234,7 +6858,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_CMAC_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_CMAC_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a
@@ -6263,7 +6887,7 @@ LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(a
 $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
 $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
-$(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a
@@ -6299,7 +6923,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ED25519_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ED25519_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a
@@ -6337,7 +6961,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_SPAKE25519_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_SPAKE25519_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a
@@ -6375,7 +6999,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_X25519_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_X25519_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a
@@ -6413,7 +7037,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_DH_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_DH_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a
@@ -6451,7 +7075,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a
@@ -6480,7 +7104,7 @@ LIBBORINGSSL_DSA_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .
 $(LIBBORINGSSL_DSA_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
 $(LIBBORINGSSL_DSA_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
-$(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_DSA_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(LIBBORINGSSL_DSA_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a
@@ -6516,7 +7140,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_EC_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_EC_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a
@@ -6545,7 +7169,7 @@ LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffi
 $(LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
 $(LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
-$(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a
@@ -6581,7 +7205,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ECDH_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ECDH_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a
@@ -6619,7 +7243,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_sign_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_sign_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ECDSA_SIGN_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_sign_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ECDSA_SIGN_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_sign_test_lib.a
@@ -6657,7 +7281,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a
@@ -6695,7 +7319,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_verify_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_verify_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ECDSA_VERIFY_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_verify_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ECDSA_VERIFY_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_verify_test_lib.a
@@ -6733,7 +7357,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ERR_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ERR_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a
@@ -6771,7 +7395,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a
@@ -6809,7 +7433,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_EVP_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_EVP_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a
@@ -6847,7 +7471,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a
@@ -6876,7 +7500,7 @@ LIBBORINGSSL_HKDF_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix
 $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
 $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
-$(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a
@@ -6912,7 +7536,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_HMAC_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_HMAC_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a
@@ -6941,7 +7565,7 @@ LIBBORINGSSL_LHASH_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix
 $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
 $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
-$(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a
@@ -6977,7 +7601,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_GCM_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_GCM_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a
@@ -7015,7 +7639,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_newhope_statistical_test_lib.a: protobuf_dep_er
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_newhope_statistical_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_NEWHOPE_STATISTICAL_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_newhope_statistical_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_NEWHOPE_STATISTICAL_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_newhope_statistical_test_lib.a
@@ -7053,7 +7677,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_newhope_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_newhope_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_NEWHOPE_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_newhope_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_NEWHOPE_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_newhope_test_lib.a
@@ -7091,7 +7715,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_newhope_vectors_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_newhope_vectors_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_NEWHOPE_VECTORS_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_newhope_vectors_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_NEWHOPE_VECTORS_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_newhope_vectors_test_lib.a
@@ -7129,7 +7753,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_OBJ_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_OBJ_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a
@@ -7167,7 +7791,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a
@@ -7205,7 +7829,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a
@@ -7243,7 +7867,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a
@@ -7272,7 +7896,7 @@ LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuf
 $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
 $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
-$(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a
@@ -7308,7 +7932,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_RSA_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_RSA_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a
@@ -7337,7 +7961,7 @@ LIBBORINGSSL_THREAD_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffi
 $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
 $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
-$(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a
@@ -7364,7 +7988,7 @@ LIBBORINGSSL_PKCS7_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix
 $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
 $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
-$(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a
@@ -7400,7 +8024,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_X509_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_X509_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a
@@ -7429,7 +8053,7 @@ LIBBORINGSSL_TAB_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .
 $(LIBBORINGSSL_TAB_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
 $(LIBBORINGSSL_TAB_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
-$(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_TAB_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(LIBBORINGSSL_TAB_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a
@@ -7456,7 +8080,7 @@ LIBBORINGSSL_V3NAME_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffi
 $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
 $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
-$(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a
@@ -7492,7 +8116,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_SSL_TEST_LIB_OBJS) 
+$(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_SSL_TEST_LIB_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a
@@ -7541,7 +8165,7 @@ $(LIBDIR)/$(CONFIG)/libbenchmark.a: protobuf_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libbenchmark.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBENCHMARK_OBJS) 
+$(LIBDIR)/$(CONFIG)/libbenchmark.a: $(ZLIB_DEP) $(CARES_DEP)  $(PROTOBUF_DEP) $(LIBBENCHMARK_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libbenchmark.a
@@ -7583,7 +8207,7 @@ LIBZ_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBZ_
 
 $(LIBZ_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-implicit-function-declaration $(W_NO_SHIFT_NEGATIVE_VALUE) -fvisibility=hidden
 
-$(LIBDIR)/$(CONFIG)/libz.a:  $(LIBZ_OBJS) 
+$(LIBDIR)/$(CONFIG)/libz.a: $(CARES_DEP)  $(LIBZ_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libz.a
@@ -7600,6 +8224,81 @@ ifneq ($(NO_DEPS),true)
 endif
 
 
+LIBARES_SRC = \
+    third_party/cares/cares/ares__close_sockets.c \
+    third_party/cares/cares/ares__get_hostent.c \
+    third_party/cares/cares/ares__read_line.c \
+    third_party/cares/cares/ares__timeval.c \
+    third_party/cares/cares/ares_cancel.c \
+    third_party/cares/cares/ares_create_query.c \
+    third_party/cares/cares/ares_data.c \
+    third_party/cares/cares/ares_destroy.c \
+    third_party/cares/cares/ares_expand_name.c \
+    third_party/cares/cares/ares_expand_string.c \
+    third_party/cares/cares/ares_fds.c \
+    third_party/cares/cares/ares_free_hostent.c \
+    third_party/cares/cares/ares_free_string.c \
+    third_party/cares/cares/ares_getenv.c \
+    third_party/cares/cares/ares_gethostbyaddr.c \
+    third_party/cares/cares/ares_gethostbyname.c \
+    third_party/cares/cares/ares_getnameinfo.c \
+    third_party/cares/cares/ares_getopt.c \
+    third_party/cares/cares/ares_getsock.c \
+    third_party/cares/cares/ares_init.c \
+    third_party/cares/cares/ares_library_init.c \
+    third_party/cares/cares/ares_llist.c \
+    third_party/cares/cares/ares_mkquery.c \
+    third_party/cares/cares/ares_nowarn.c \
+    third_party/cares/cares/ares_options.c \
+    third_party/cares/cares/ares_parse_a_reply.c \
+    third_party/cares/cares/ares_parse_aaaa_reply.c \
+    third_party/cares/cares/ares_parse_mx_reply.c \
+    third_party/cares/cares/ares_parse_naptr_reply.c \
+    third_party/cares/cares/ares_parse_ns_reply.c \
+    third_party/cares/cares/ares_parse_ptr_reply.c \
+    third_party/cares/cares/ares_parse_soa_reply.c \
+    third_party/cares/cares/ares_parse_srv_reply.c \
+    third_party/cares/cares/ares_parse_txt_reply.c \
+    third_party/cares/cares/ares_platform.c \
+    third_party/cares/cares/ares_process.c \
+    third_party/cares/cares/ares_query.c \
+    third_party/cares/cares/ares_search.c \
+    third_party/cares/cares/ares_send.c \
+    third_party/cares/cares/ares_strcasecmp.c \
+    third_party/cares/cares/ares_strdup.c \
+    third_party/cares/cares/ares_strerror.c \
+    third_party/cares/cares/ares_timeout.c \
+    third_party/cares/cares/ares_version.c \
+    third_party/cares/cares/ares_writev.c \
+    third_party/cares/cares/bitncmp.c \
+    third_party/cares/cares/inet_net_pton.c \
+    third_party/cares/cares/inet_ntop.c \
+    third_party/cares/cares/windows_port.c \
+
+PUBLIC_HEADERS_C += \
+
+LIBARES_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBARES_SRC))))
+
+$(LIBARES_OBJS): CPPFLAGS += -Ithird_party/cares -Ithird_party/cares/cares $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux) $(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) -fvisibility=hidden -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(if $(subst MINGW32,,$(SYSTEM)),-DHAVE_CONFIG_H,)
+$(LIBARES_OBJS): CFLAGS += -Wno-sign-conversion $(if $(subst MINGW32,,$(SYSTEM)),-Wno-invalid-source-encoding,)
+
+$(LIBDIR)/$(CONFIG)/libares.a: $(ZLIB_DEP)  $(LIBARES_OBJS) 
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libares.a
+	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libares.a $(LIBARES_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libares.a
+endif
+
+
+
+
+ifneq ($(NO_DEPS),true)
+-include $(LIBARES_OBJS:.o=.dep)
+endif
+
+
 LIBBAD_CLIENT_TEST_SRC = \
     test/core/bad_client/bad_client.c \
 
@@ -7618,7 +8317,7 @@ $(LIBDIR)/$(CONFIG)/libbad_client_test.a: openssl_dep_error
 else
 
 
-$(LIBDIR)/$(CONFIG)/libbad_client_test.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBBAD_CLIENT_TEST_OBJS) 
+$(LIBDIR)/$(CONFIG)/libbad_client_test.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(LIBBAD_CLIENT_TEST_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libbad_client_test.a
@@ -7657,7 +8356,7 @@ $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a: openssl_dep_error
 else
 
 
-$(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBBAD_SSL_TEST_SERVER_OBJS) 
+$(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(LIBBAD_SSL_TEST_SERVER_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a
@@ -7683,6 +8382,7 @@ LIBEND2END_TESTS_SRC = \
     test/core/end2end/end2end_test_utils.c \
     test/core/end2end/tests/authority_not_supported.c \
     test/core/end2end/tests/bad_hostname.c \
+    test/core/end2end/tests/bad_ping.c \
     test/core/end2end/tests/binary_metadata.c \
     test/core/end2end/tests/call_creds.c \
     test/core/end2end/tests/cancel_after_accept.c \
@@ -7708,6 +8408,8 @@ LIBEND2END_TESTS_SRC = \
     test/core/end2end/tests/large_metadata.c \
     test/core/end2end/tests/load_reporting_hook.c \
     test/core/end2end/tests/max_concurrent_streams.c \
+    test/core/end2end/tests/max_connection_age.c \
+    test/core/end2end/tests/max_connection_idle.c \
     test/core/end2end/tests/max_message_length.c \
     test/core/end2end/tests/negative_deadline.c \
     test/core/end2end/tests/network_status_change.c \
@@ -7747,7 +8449,7 @@ $(LIBDIR)/$(CONFIG)/libend2end_tests.a: openssl_dep_error
 else
 
 
-$(LIBDIR)/$(CONFIG)/libend2end_tests.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBEND2END_TESTS_OBJS) 
+$(LIBDIR)/$(CONFIG)/libend2end_tests.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(LIBEND2END_TESTS_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libend2end_tests.a
@@ -7773,6 +8475,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \
     test/core/end2end/end2end_test_utils.c \
     test/core/end2end/tests/authority_not_supported.c \
     test/core/end2end/tests/bad_hostname.c \
+    test/core/end2end/tests/bad_ping.c \
     test/core/end2end/tests/binary_metadata.c \
     test/core/end2end/tests/cancel_after_accept.c \
     test/core/end2end/tests/cancel_after_client_done.c \
@@ -7797,6 +8500,8 @@ LIBEND2END_NOSEC_TESTS_SRC = \
     test/core/end2end/tests/large_metadata.c \
     test/core/end2end/tests/load_reporting_hook.c \
     test/core/end2end/tests/max_concurrent_streams.c \
+    test/core/end2end/tests/max_connection_age.c \
+    test/core/end2end/tests/max_connection_idle.c \
     test/core/end2end/tests/max_message_length.c \
     test/core/end2end/tests/negative_deadline.c \
     test/core/end2end/tests/network_status_change.c \
@@ -7826,7 +8531,7 @@ PUBLIC_HEADERS_C += \
 LIBEND2END_NOSEC_TESTS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBEND2END_NOSEC_TESTS_SRC))))
 
 
-$(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a: $(ZLIB_DEP)  $(LIBEND2END_NOSEC_TESTS_OBJS) 
+$(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a: $(ZLIB_DEP) $(CARES_DEP)  $(LIBEND2END_NOSEC_TESTS_OBJS) 
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a
@@ -8007,6 +8712,38 @@ endif
 endif
 
 
+ARENA_TEST_SRC = \
+    test/core/support/arena_test.c \
+
+ARENA_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ARENA_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/arena_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/arena_test: $(ARENA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(ARENA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/arena_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/support/arena_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_arena_test: $(ARENA_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(ARENA_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 BAD_SERVER_RESPONSE_TEST_SRC = \
     test/core/end2end/bad_server_response_test.c \
 
@@ -8647,6 +9384,38 @@ endif
 endif
 
 
+ERROR_TEST_SRC = \
+    test/core/iomgr/error_test.c \
+
+ERROR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ERROR_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/error_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/error_test: $(ERROR_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) $(ERROR_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)/error_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/iomgr/error_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_error_test: $(ERROR_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(ERROR_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 EV_EPOLL_LINUX_TEST_SRC = \
     test/core/iomgr/ev_epoll_linux_test.c \
 
@@ -8679,6 +9448,38 @@ endif
 endif
 
 
+FAKE_RESOLVER_TEST_SRC = \
+    test/core/client_channel/resolvers/fake_resolver_test.c \
+
+FAKE_RESOLVER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(FAKE_RESOLVER_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/fake_resolver_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/fake_resolver_test: $(FAKE_RESOLVER_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) $(FAKE_RESOLVER_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)/fake_resolver_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/fake_resolver_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_fake_resolver_test: $(FAKE_RESOLVER_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(FAKE_RESOLVER_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 FD_CONSERVATION_POSIX_TEST_SRC = \
     test/core/iomgr/fd_conservation_posix_test.c \
 
@@ -9576,7 +10377,7 @@ endif
 
 
 GRPC_B64_TEST_SRC = \
-    test/core/security/b64_test.c \
+    test/core/slice/b64_test.c \
 
 GRPC_B64_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_B64_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -9596,7 +10397,7 @@ $(BINDIR)/$(CONFIG)/grpc_b64_test: $(GRPC_B64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/lib
 
 endif
 
-$(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
+$(OBJDIR)/$(CONFIG)/test/core/slice/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_b64_test: $(GRPC_B64_TEST_OBJS:.o=.dep)
 
@@ -10887,6 +11688,38 @@ endif
 endif
 
 
+MINIMAL_STACK_IS_MINIMAL_TEST_SRC = \
+    test/core/channel/minimal_stack_is_minimal_test.c \
+
+MINIMAL_STACK_IS_MINIMAL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MINIMAL_STACK_IS_MINIMAL_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test: $(MINIMAL_STACK_IS_MINIMAL_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) $(MINIMAL_STACK_IS_MINIMAL_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)/minimal_stack_is_minimal_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/channel/minimal_stack_is_minimal_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_minimal_stack_is_minimal_test: $(MINIMAL_STACK_IS_MINIMAL_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(MINIMAL_STACK_IS_MINIMAL_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 MLOG_TEST_SRC = \
     test/core/census/mlog_test.c \
 
@@ -11079,6 +11912,38 @@ endif
 endif
 
 
+PARSE_ADDRESS_TEST_SRC = \
+    test/core/client_channel/parse_address_test.c \
+
+PARSE_ADDRESS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PARSE_ADDRESS_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/parse_address_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/parse_address_test: $(PARSE_ADDRESS_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) $(PARSE_ADDRESS_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)/parse_address_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/client_channel/parse_address_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_parse_address_test: $(PARSE_ADDRESS_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(PARSE_ADDRESS_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 PERCENT_DECODE_FUZZER_SRC = \
     test/core/slice/percent_decode_fuzzer.c \
 
@@ -11495,66 +12360,66 @@ endif
 endif
 
 
-SET_INITIAL_CONNECT_STRING_TEST_SRC = \
-    test/core/client_channel/set_initial_connect_string_test.c \
+SLICE_BUFFER_TEST_SRC = \
+    test/core/slice/slice_buffer_test.c \
 
-SET_INITIAL_CONNECT_STRING_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SET_INITIAL_CONNECT_STRING_TEST_SRC))))
+SLICE_BUFFER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SLICE_BUFFER_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/set_initial_connect_string_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/slice_buffer_test: openssl_dep_error
 
 else
 
 
 
-$(BINDIR)/$(CONFIG)/set_initial_connect_string_test: $(SET_INITIAL_CONNECT_STRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/slice_buffer_test: $(SLICE_BUFFER_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) $(SET_INITIAL_CONNECT_STRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(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)/set_initial_connect_string_test
+	$(Q) $(LD) $(LDFLAGS) $(SLICE_BUFFER_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)/slice_buffer_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/client_channel/set_initial_connect_string_test.o:  $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/slice/slice_buffer_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_set_initial_connect_string_test: $(SET_INITIAL_CONNECT_STRING_TEST_OBJS:.o=.dep)
+deps_slice_buffer_test: $(SLICE_BUFFER_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(SET_INITIAL_CONNECT_STRING_TEST_OBJS:.o=.dep)
+-include $(SLICE_BUFFER_TEST_OBJS:.o=.dep)
 endif
 endif
 
 
-SLICE_BUFFER_TEST_SRC = \
-    test/core/slice/slice_buffer_test.c \
+SLICE_HASH_TABLE_TEST_SRC = \
+    test/core/slice/slice_hash_table_test.c \
 
-SLICE_BUFFER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SLICE_BUFFER_TEST_SRC))))
+SLICE_HASH_TABLE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SLICE_HASH_TABLE_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/slice_buffer_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/slice_hash_table_test: openssl_dep_error
 
 else
 
 
 
-$(BINDIR)/$(CONFIG)/slice_buffer_test: $(SLICE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/slice_hash_table_test: $(SLICE_HASH_TABLE_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) $(SLICE_BUFFER_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)/slice_buffer_test
+	$(Q) $(LD) $(LDFLAGS) $(SLICE_HASH_TABLE_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)/slice_hash_table_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/slice/slice_buffer_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/slice/slice_hash_table_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_slice_buffer_test: $(SLICE_BUFFER_TEST_OBJS:.o=.dep)
+deps_slice_hash_table_test: $(SLICE_HASH_TABLE_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(SLICE_BUFFER_TEST_OBJS:.o=.dep)
+-include $(SLICE_HASH_TABLE_TEST_OBJS:.o=.dep)
 endif
 endif
 
@@ -11783,6 +12648,38 @@ endif
 endif
 
 
+STREAM_OWNED_SLICE_TEST_SRC = \
+    test/core/transport/stream_owned_slice_test.c \
+
+STREAM_OWNED_SLICE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(STREAM_OWNED_SLICE_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/stream_owned_slice_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/stream_owned_slice_test: $(STREAM_OWNED_SLICE_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) $(STREAM_OWNED_SLICE_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)/stream_owned_slice_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/transport/stream_owned_slice_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_stream_owned_slice_test: $(STREAM_OWNED_SLICE_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(STREAM_OWNED_SLICE_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 TCP_CLIENT_POSIX_TEST_SRC = \
     test/core/iomgr/tcp_client_posix_test.c \
 
@@ -11946,396 +12843,701 @@ endif
 TIME_AVERAGED_STATS_TEST_SRC = \
     test/core/iomgr/time_averaged_stats_test.c \
 
-TIME_AVERAGED_STATS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TIME_AVERAGED_STATS_TEST_SRC))))
+TIME_AVERAGED_STATS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TIME_AVERAGED_STATS_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/time_averaged_stats_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/time_averaged_stats_test: $(TIME_AVERAGED_STATS_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) $(TIME_AVERAGED_STATS_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)/time_averaged_stats_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/iomgr/time_averaged_stats_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_time_averaged_stats_test: $(TIME_AVERAGED_STATS_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(TIME_AVERAGED_STATS_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
+TIMEOUT_ENCODING_TEST_SRC = \
+    test/core/transport/timeout_encoding_test.c \
+
+TIMEOUT_ENCODING_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TIMEOUT_ENCODING_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/timeout_encoding_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/timeout_encoding_test: $(TIMEOUT_ENCODING_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) $(TIMEOUT_ENCODING_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)/timeout_encoding_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/transport/timeout_encoding_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_timeout_encoding_test: $(TIMEOUT_ENCODING_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(TIMEOUT_ENCODING_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
+TIMER_HEAP_TEST_SRC = \
+    test/core/iomgr/timer_heap_test.c \
+
+TIMER_HEAP_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TIMER_HEAP_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/timer_heap_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/timer_heap_test: $(TIMER_HEAP_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) $(TIMER_HEAP_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)/timer_heap_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/iomgr/timer_heap_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_timer_heap_test: $(TIMER_HEAP_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(TIMER_HEAP_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
+TIMER_LIST_TEST_SRC = \
+    test/core/iomgr/timer_list_test.c \
+
+TIMER_LIST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TIMER_LIST_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/timer_list_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/timer_list_test: $(TIMER_LIST_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) $(TIMER_LIST_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)/timer_list_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/iomgr/timer_list_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_timer_list_test: $(TIMER_LIST_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(TIMER_LIST_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
+TRANSPORT_CONNECTIVITY_STATE_TEST_SRC = \
+    test/core/transport/connectivity_state_test.c \
+
+TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TRANSPORT_CONNECTIVITY_STATE_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/transport_connectivity_state_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/transport_connectivity_state_test: $(TRANSPORT_CONNECTIVITY_STATE_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) $(TRANSPORT_CONNECTIVITY_STATE_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)/transport_connectivity_state_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/transport/connectivity_state_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_transport_connectivity_state_test: $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
+TRANSPORT_METADATA_TEST_SRC = \
+    test/core/transport/metadata_test.c \
+
+TRANSPORT_METADATA_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TRANSPORT_METADATA_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/transport_metadata_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/transport_metadata_test: $(TRANSPORT_METADATA_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) $(TRANSPORT_METADATA_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)/transport_metadata_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/transport/metadata_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_transport_metadata_test: $(TRANSPORT_METADATA_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(TRANSPORT_METADATA_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
+TRANSPORT_PID_CONTROLLER_TEST_SRC = \
+    test/core/transport/pid_controller_test.c \
+
+TRANSPORT_PID_CONTROLLER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TRANSPORT_PID_CONTROLLER_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/transport_pid_controller_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/transport_pid_controller_test: $(TRANSPORT_PID_CONTROLLER_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) $(TRANSPORT_PID_CONTROLLER_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)/transport_pid_controller_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/transport/pid_controller_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_transport_pid_controller_test: $(TRANSPORT_PID_CONTROLLER_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(TRANSPORT_PID_CONTROLLER_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
+TRANSPORT_SECURITY_TEST_SRC = \
+    test/core/tsi/transport_security_test.c \
+
+TRANSPORT_SECURITY_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TRANSPORT_SECURITY_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/time_averaged_stats_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/transport_security_test: openssl_dep_error
 
 else
 
 
 
-$(BINDIR)/$(CONFIG)/time_averaged_stats_test: $(TIME_AVERAGED_STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/transport_security_test: $(TRANSPORT_SECURITY_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) $(TIME_AVERAGED_STATS_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)/time_averaged_stats_test
+	$(Q) $(LD) $(LDFLAGS) $(TRANSPORT_SECURITY_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)/transport_security_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/iomgr/time_averaged_stats_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/tsi/transport_security_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_time_averaged_stats_test: $(TIME_AVERAGED_STATS_TEST_OBJS:.o=.dep)
+deps_transport_security_test: $(TRANSPORT_SECURITY_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(TIME_AVERAGED_STATS_TEST_OBJS:.o=.dep)
+-include $(TRANSPORT_SECURITY_TEST_OBJS:.o=.dep)
 endif
 endif
 
 
-TIMEOUT_ENCODING_TEST_SRC = \
-    test/core/transport/timeout_encoding_test.c \
+UDP_SERVER_TEST_SRC = \
+    test/core/iomgr/udp_server_test.c \
 
-TIMEOUT_ENCODING_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TIMEOUT_ENCODING_TEST_SRC))))
+UDP_SERVER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(UDP_SERVER_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/timeout_encoding_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/udp_server_test: openssl_dep_error
 
 else
 
 
 
-$(BINDIR)/$(CONFIG)/timeout_encoding_test: $(TIMEOUT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/udp_server_test: $(UDP_SERVER_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) $(TIMEOUT_ENCODING_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)/timeout_encoding_test
+	$(Q) $(LD) $(LDFLAGS) $(UDP_SERVER_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)/udp_server_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/transport/timeout_encoding_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/iomgr/udp_server_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_timeout_encoding_test: $(TIMEOUT_ENCODING_TEST_OBJS:.o=.dep)
+deps_udp_server_test: $(UDP_SERVER_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(TIMEOUT_ENCODING_TEST_OBJS:.o=.dep)
+-include $(UDP_SERVER_TEST_OBJS:.o=.dep)
 endif
 endif
 
 
-TIMER_HEAP_TEST_SRC = \
-    test/core/iomgr/timer_heap_test.c \
+URI_FUZZER_TEST_SRC = \
+    test/core/client_channel/uri_fuzzer_test.c \
 
-TIMER_HEAP_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TIMER_HEAP_TEST_SRC))))
+URI_FUZZER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(URI_FUZZER_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/timer_heap_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/uri_fuzzer_test: openssl_dep_error
 
 else
 
 
 
-$(BINDIR)/$(CONFIG)/timer_heap_test: $(TIMER_HEAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/uri_fuzzer_test: $(URI_FUZZER_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) $(TIMER_HEAP_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)/timer_heap_test
+	$(Q) $(LDXX) $(LDFLAGS) $(URI_FUZZER_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) -lFuzzer -o $(BINDIR)/$(CONFIG)/uri_fuzzer_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/iomgr/timer_heap_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/client_channel/uri_fuzzer_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_timer_heap_test: $(TIMER_HEAP_TEST_OBJS:.o=.dep)
+deps_uri_fuzzer_test: $(URI_FUZZER_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(TIMER_HEAP_TEST_OBJS:.o=.dep)
+-include $(URI_FUZZER_TEST_OBJS:.o=.dep)
 endif
 endif
 
 
-TIMER_LIST_TEST_SRC = \
-    test/core/iomgr/timer_list_test.c \
+URI_PARSER_TEST_SRC = \
+    test/core/client_channel/uri_parser_test.c \
 
-TIMER_LIST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TIMER_LIST_TEST_SRC))))
+URI_PARSER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(URI_PARSER_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/timer_list_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/uri_parser_test: openssl_dep_error
 
 else
 
 
 
-$(BINDIR)/$(CONFIG)/timer_list_test: $(TIMER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/uri_parser_test: $(URI_PARSER_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) $(TIMER_LIST_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)/timer_list_test
+	$(Q) $(LD) $(LDFLAGS) $(URI_PARSER_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)/uri_parser_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/iomgr/timer_list_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/client_channel/uri_parser_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_timer_list_test: $(TIMER_LIST_TEST_OBJS:.o=.dep)
+deps_uri_parser_test: $(URI_PARSER_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(TIMER_LIST_TEST_OBJS:.o=.dep)
+-include $(URI_PARSER_TEST_OBJS:.o=.dep)
 endif
 endif
 
 
-TRANSPORT_CONNECTIVITY_STATE_TEST_SRC = \
-    test/core/transport/connectivity_state_test.c \
+WAKEUP_FD_CV_TEST_SRC = \
+    test/core/iomgr/wakeup_fd_cv_test.c \
 
-TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TRANSPORT_CONNECTIVITY_STATE_TEST_SRC))))
+WAKEUP_FD_CV_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(WAKEUP_FD_CV_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/transport_connectivity_state_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/wakeup_fd_cv_test: openssl_dep_error
 
 else
 
 
 
-$(BINDIR)/$(CONFIG)/transport_connectivity_state_test: $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/wakeup_fd_cv_test: $(WAKEUP_FD_CV_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) $(TRANSPORT_CONNECTIVITY_STATE_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)/transport_connectivity_state_test
+	$(Q) $(LD) $(LDFLAGS) $(WAKEUP_FD_CV_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)/wakeup_fd_cv_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/transport/connectivity_state_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/iomgr/wakeup_fd_cv_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_transport_connectivity_state_test: $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS:.o=.dep)
+deps_wakeup_fd_cv_test: $(WAKEUP_FD_CV_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS:.o=.dep)
+-include $(WAKEUP_FD_CV_TEST_OBJS:.o=.dep)
 endif
 endif
 
 
-TRANSPORT_METADATA_TEST_SRC = \
-    test/core/transport/metadata_test.c \
+ALARM_CPP_TEST_SRC = \
+    test/cpp/common/alarm_cpp_test.cc \
 
-TRANSPORT_METADATA_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TRANSPORT_METADATA_TEST_SRC))))
+ALARM_CPP_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ALARM_CPP_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/transport_metadata_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/alarm_cpp_test: openssl_dep_error
 
 else
 
 
 
-$(BINDIR)/$(CONFIG)/transport_metadata_test: $(TRANSPORT_METADATA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+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)/alarm_cpp_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/alarm_cpp_test: $(PROTOBUF_DEP) $(ALARM_CPP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.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) $(TRANSPORT_METADATA_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)/transport_metadata_test
+	$(Q) $(LDXX) $(LDFLAGS) $(ALARM_CPP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/alarm_cpp_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/transport/metadata_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+endif
 
-deps_transport_metadata_test: $(TRANSPORT_METADATA_TEST_OBJS:.o=.dep)
+$(OBJDIR)/$(CONFIG)/test/cpp/common/alarm_cpp_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_alarm_cpp_test: $(ALARM_CPP_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(TRANSPORT_METADATA_TEST_OBJS:.o=.dep)
+-include $(ALARM_CPP_TEST_OBJS:.o=.dep)
 endif
 endif
 
 
-TRANSPORT_PID_CONTROLLER_TEST_SRC = \
-    test/core/transport/pid_controller_test.c \
+ASYNC_END2END_TEST_SRC = \
+    test/cpp/end2end/async_end2end_test.cc \
 
-TRANSPORT_PID_CONTROLLER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TRANSPORT_PID_CONTROLLER_TEST_SRC))))
+ASYNC_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ASYNC_END2END_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/transport_pid_controller_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/async_end2end_test: openssl_dep_error
 
 else
 
 
 
-$(BINDIR)/$(CONFIG)/transport_pid_controller_test: $(TRANSPORT_PID_CONTROLLER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+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)/async_end2end_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/async_end2end_test: $(PROTOBUF_DEP) $(ASYNC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.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) $(TRANSPORT_PID_CONTROLLER_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)/transport_pid_controller_test
+	$(Q) $(LDXX) $(LDFLAGS) $(ASYNC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/async_end2end_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/transport/pid_controller_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+endif
 
-deps_transport_pid_controller_test: $(TRANSPORT_PID_CONTROLLER_TEST_OBJS:.o=.dep)
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/async_end2end_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_async_end2end_test: $(ASYNC_END2END_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(TRANSPORT_PID_CONTROLLER_TEST_OBJS:.o=.dep)
+-include $(ASYNC_END2END_TEST_OBJS:.o=.dep)
 endif
 endif
 
 
-TRANSPORT_SECURITY_TEST_SRC = \
-    test/core/tsi/transport_security_test.c \
+AUTH_PROPERTY_ITERATOR_TEST_SRC = \
+    test/cpp/common/auth_property_iterator_test.cc \
 
-TRANSPORT_SECURITY_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TRANSPORT_SECURITY_TEST_SRC))))
+AUTH_PROPERTY_ITERATOR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(AUTH_PROPERTY_ITERATOR_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/transport_security_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/auth_property_iterator_test: openssl_dep_error
 
 else
 
 
 
-$(BINDIR)/$(CONFIG)/transport_security_test: $(TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+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)/auth_property_iterator_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/auth_property_iterator_test: $(PROTOBUF_DEP) $(AUTH_PROPERTY_ITERATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.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) $(TRANSPORT_SECURITY_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)/transport_security_test
+	$(Q) $(LDXX) $(LDFLAGS) $(AUTH_PROPERTY_ITERATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/auth_property_iterator_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+endif
 
-deps_transport_security_test: $(TRANSPORT_SECURITY_TEST_OBJS:.o=.dep)
+$(OBJDIR)/$(CONFIG)/test/cpp/common/auth_property_iterator_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_auth_property_iterator_test: $(AUTH_PROPERTY_ITERATOR_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(TRANSPORT_SECURITY_TEST_OBJS:.o=.dep)
+-include $(AUTH_PROPERTY_ITERATOR_TEST_OBJS:.o=.dep)
 endif
 endif
 
 
-UDP_SERVER_TEST_SRC = \
-    test/core/iomgr/udp_server_test.c \
+BM_ARENA_SRC = \
+    test/cpp/microbenchmarks/bm_arena.cc \
 
-UDP_SERVER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(UDP_SERVER_TEST_SRC))))
+BM_ARENA_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_ARENA_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/udp_server_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/bm_arena: openssl_dep_error
 
 else
 
 
 
-$(BINDIR)/$(CONFIG)/udp_server_test: $(UDP_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+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)/bm_arena: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/bm_arena: $(PROTOBUF_DEP) $(BM_ARENA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.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) $(UDP_SERVER_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)/udp_server_test
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_ARENA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_arena
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/iomgr/udp_server_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+endif
 
-deps_udp_server_test: $(UDP_SERVER_TEST_OBJS:.o=.dep)
+$(BM_ARENA_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_arena.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_bm_arena: $(BM_ARENA_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(UDP_SERVER_TEST_OBJS:.o=.dep)
+-include $(BM_ARENA_OBJS:.o=.dep)
 endif
 endif
 
 
-URI_FUZZER_TEST_SRC = \
-    test/core/client_channel/uri_fuzzer_test.c \
+BM_CALL_CREATE_SRC = \
+    test/cpp/microbenchmarks/bm_call_create.cc \
 
-URI_FUZZER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(URI_FUZZER_TEST_SRC))))
+BM_CALL_CREATE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CALL_CREATE_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/uri_fuzzer_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/bm_call_create: openssl_dep_error
 
 else
 
 
 
-$(BINDIR)/$(CONFIG)/uri_fuzzer_test: $(URI_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+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)/bm_call_create: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/bm_call_create: $(PROTOBUF_DEP) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(URI_FUZZER_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) -lFuzzer -o $(BINDIR)/$(CONFIG)/uri_fuzzer_test
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_call_create
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_fuzzer_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+endif
 
-deps_uri_fuzzer_test: $(URI_FUZZER_TEST_OBJS:.o=.dep)
+$(BM_CALL_CREATE_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_call_create.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_bm_call_create: $(BM_CALL_CREATE_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(URI_FUZZER_TEST_OBJS:.o=.dep)
+-include $(BM_CALL_CREATE_OBJS:.o=.dep)
 endif
 endif
 
 
-URI_PARSER_TEST_SRC = \
-    test/core/client_channel/uri_parser_test.c \
+BM_CHTTP2_HPACK_SRC = \
+    test/cpp/microbenchmarks/bm_chttp2_hpack.cc \
 
-URI_PARSER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(URI_PARSER_TEST_SRC))))
+BM_CHTTP2_HPACK_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CHTTP2_HPACK_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/uri_parser_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/bm_chttp2_hpack: openssl_dep_error
 
 else
 
 
 
-$(BINDIR)/$(CONFIG)/uri_parser_test: $(URI_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+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)/bm_chttp2_hpack: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/bm_chttp2_hpack: $(PROTOBUF_DEP) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.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) $(URI_PARSER_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)/uri_parser_test
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_chttp2_hpack
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_parser_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+endif
 
-deps_uri_parser_test: $(URI_PARSER_TEST_OBJS:.o=.dep)
+$(BM_CHTTP2_HPACK_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_hpack.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_bm_chttp2_hpack: $(BM_CHTTP2_HPACK_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(URI_PARSER_TEST_OBJS:.o=.dep)
+-include $(BM_CHTTP2_HPACK_OBJS:.o=.dep)
 endif
 endif
 
 
-WAKEUP_FD_CV_TEST_SRC = \
-    test/core/iomgr/wakeup_fd_cv_test.c \
+BM_CHTTP2_TRANSPORT_SRC = \
+    test/cpp/microbenchmarks/bm_chttp2_transport.cc \
 
-WAKEUP_FD_CV_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(WAKEUP_FD_CV_TEST_SRC))))
+BM_CHTTP2_TRANSPORT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CHTTP2_TRANSPORT_SRC))))
 ifeq ($(NO_SECURE),true)
 
-# You can't build secure targets if you don't have OpenSSL.
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/bm_chttp2_transport: openssl_dep_error
+
+else
+
+
+
 
-$(BINDIR)/$(CONFIG)/wakeup_fd_cv_test: openssl_dep_error
+ifeq ($(NO_PROTOBUF),true)
 
-else
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
 
+$(BINDIR)/$(CONFIG)/bm_chttp2_transport: protobuf_dep_error
 
+else
 
-$(BINDIR)/$(CONFIG)/wakeup_fd_cv_test: $(WAKEUP_FD_CV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_chttp2_transport: $(PROTOBUF_DEP) $(BM_CHTTP2_TRANSPORT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.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) $(WAKEUP_FD_CV_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)/wakeup_fd_cv_test
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_TRANSPORT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_chttp2_transport
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/iomgr/wakeup_fd_cv_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+endif
 
-deps_wakeup_fd_cv_test: $(WAKEUP_FD_CV_TEST_OBJS:.o=.dep)
+$(BM_CHTTP2_TRANSPORT_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_transport.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_bm_chttp2_transport: $(BM_CHTTP2_TRANSPORT_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(WAKEUP_FD_CV_TEST_OBJS:.o=.dep)
+-include $(BM_CHTTP2_TRANSPORT_OBJS:.o=.dep)
 endif
 endif
 
 
-ALARM_CPP_TEST_SRC = \
-    test/cpp/common/alarm_cpp_test.cc \
+BM_CLOSURE_SRC = \
+    test/cpp/microbenchmarks/bm_closure.cc \
 
-ALARM_CPP_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ALARM_CPP_TEST_SRC))))
+BM_CLOSURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CLOSURE_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/alarm_cpp_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/bm_closure: openssl_dep_error
 
 else
 
@@ -12346,39 +13548,40 @@ 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)/alarm_cpp_test: protobuf_dep_error
+$(BINDIR)/$(CONFIG)/bm_closure: protobuf_dep_error
 
 else
 
-$(BINDIR)/$(CONFIG)/alarm_cpp_test: $(PROTOBUF_DEP) $(ALARM_CPP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_closure: $(PROTOBUF_DEP) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(ALARM_CPP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/alarm_cpp_test
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_closure
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/common/alarm_cpp_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BM_CLOSURE_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_closure.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_alarm_cpp_test: $(ALARM_CPP_TEST_OBJS:.o=.dep)
+deps_bm_closure: $(BM_CLOSURE_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(ALARM_CPP_TEST_OBJS:.o=.dep)
+-include $(BM_CLOSURE_OBJS:.o=.dep)
 endif
 endif
 
 
-ASYNC_END2END_TEST_SRC = \
-    test/cpp/end2end/async_end2end_test.cc \
+BM_CQ_SRC = \
+    test/cpp/microbenchmarks/bm_cq.cc \
 
-ASYNC_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ASYNC_END2END_TEST_SRC))))
+BM_CQ_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CQ_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/async_end2end_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/bm_cq: openssl_dep_error
 
 else
 
@@ -12389,39 +13592,40 @@ 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)/async_end2end_test: protobuf_dep_error
+$(BINDIR)/$(CONFIG)/bm_cq: protobuf_dep_error
 
 else
 
-$(BINDIR)/$(CONFIG)/async_end2end_test: $(PROTOBUF_DEP) $(ASYNC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_cq: $(PROTOBUF_DEP) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(ASYNC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/async_end2end_test
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_cq
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/end2end/async_end2end_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BM_CQ_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_async_end2end_test: $(ASYNC_END2END_TEST_OBJS:.o=.dep)
+deps_bm_cq: $(BM_CQ_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(ASYNC_END2END_TEST_OBJS:.o=.dep)
+-include $(BM_CQ_OBJS:.o=.dep)
 endif
 endif
 
 
-AUTH_PROPERTY_ITERATOR_TEST_SRC = \
-    test/cpp/common/auth_property_iterator_test.cc \
+BM_CQ_MULTIPLE_THREADS_SRC = \
+    test/cpp/microbenchmarks/bm_cq_multiple_threads.cc \
 
-AUTH_PROPERTY_ITERATOR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(AUTH_PROPERTY_ITERATOR_TEST_SRC))))
+BM_CQ_MULTIPLE_THREADS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CQ_MULTIPLE_THREADS_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/auth_property_iterator_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/bm_cq_multiple_threads: openssl_dep_error
 
 else
 
@@ -12432,39 +13636,40 @@ 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)/auth_property_iterator_test: protobuf_dep_error
+$(BINDIR)/$(CONFIG)/bm_cq_multiple_threads: protobuf_dep_error
 
 else
 
-$(BINDIR)/$(CONFIG)/auth_property_iterator_test: $(PROTOBUF_DEP) $(AUTH_PROPERTY_ITERATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_cq_multiple_threads: $(PROTOBUF_DEP) $(BM_CQ_MULTIPLE_THREADS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(AUTH_PROPERTY_ITERATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/auth_property_iterator_test
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_MULTIPLE_THREADS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_cq_multiple_threads
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/common/auth_property_iterator_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BM_CQ_MULTIPLE_THREADS_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq_multiple_threads.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_auth_property_iterator_test: $(AUTH_PROPERTY_ITERATOR_TEST_OBJS:.o=.dep)
+deps_bm_cq_multiple_threads: $(BM_CQ_MULTIPLE_THREADS_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(AUTH_PROPERTY_ITERATOR_TEST_OBJS:.o=.dep)
+-include $(BM_CQ_MULTIPLE_THREADS_OBJS:.o=.dep)
 endif
 endif
 
 
-BM_CALL_CREATE_SRC = \
-    test/cpp/microbenchmarks/bm_call_create.cc \
+BM_ERROR_SRC = \
+    test/cpp/microbenchmarks/bm_error.cc \
 
-BM_CALL_CREATE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CALL_CREATE_SRC))))
+BM_ERROR_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_ERROR_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/bm_call_create: openssl_dep_error
+$(BINDIR)/$(CONFIG)/bm_error: openssl_dep_error
 
 else
 
@@ -12475,39 +13680,40 @@ 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)/bm_call_create: protobuf_dep_error
+$(BINDIR)/$(CONFIG)/bm_error: protobuf_dep_error
 
 else
 
-$(BINDIR)/$(CONFIG)/bm_call_create: $(PROTOBUF_DEP) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_error: $(PROTOBUF_DEP) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_call_create
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_error
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_call_create.o:  $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BM_ERROR_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_error.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_bm_call_create: $(BM_CALL_CREATE_OBJS:.o=.dep)
+deps_bm_error: $(BM_ERROR_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(BM_CALL_CREATE_OBJS:.o=.dep)
+-include $(BM_ERROR_OBJS:.o=.dep)
 endif
 endif
 
 
-BM_CHTTP2_HPACK_SRC = \
-    test/cpp/microbenchmarks/bm_chttp2_hpack.cc \
+BM_FULLSTACK_STREAMING_PING_PONG_SRC = \
+    test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc \
 
-BM_CHTTP2_HPACK_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CHTTP2_HPACK_SRC))))
+BM_FULLSTACK_STREAMING_PING_PONG_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_FULLSTACK_STREAMING_PING_PONG_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/bm_chttp2_hpack: openssl_dep_error
+$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: openssl_dep_error
 
 else
 
@@ -12518,39 +13724,40 @@ 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)/bm_chttp2_hpack: protobuf_dep_error
+$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: protobuf_dep_error
 
 else
 
-$(BINDIR)/$(CONFIG)/bm_chttp2_hpack: $(PROTOBUF_DEP) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_chttp2_hpack
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_hpack.o:  $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BM_FULLSTACK_STREAMING_PING_PONG_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_bm_chttp2_hpack: $(BM_CHTTP2_HPACK_OBJS:.o=.dep)
+deps_bm_fullstack_streaming_ping_pong: $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(BM_CHTTP2_HPACK_OBJS:.o=.dep)
+-include $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS:.o=.dep)
 endif
 endif
 
 
-BM_CLOSURE_SRC = \
-    test/cpp/microbenchmarks/bm_closure.cc \
+BM_FULLSTACK_STREAMING_PUMP_SRC = \
+    test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc \
 
-BM_CLOSURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CLOSURE_SRC))))
+BM_FULLSTACK_STREAMING_PUMP_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_FULLSTACK_STREAMING_PUMP_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/bm_closure: openssl_dep_error
+$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: openssl_dep_error
 
 else
 
@@ -12561,39 +13768,40 @@ 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)/bm_closure: protobuf_dep_error
+$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: protobuf_dep_error
 
 else
 
-$(BINDIR)/$(CONFIG)/bm_closure: $(PROTOBUF_DEP) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PUMP_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_closure
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_STREAMING_PUMP_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_closure.o:  $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BM_FULLSTACK_STREAMING_PUMP_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_bm_closure: $(BM_CLOSURE_OBJS:.o=.dep)
+deps_bm_fullstack_streaming_pump: $(BM_FULLSTACK_STREAMING_PUMP_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(BM_CLOSURE_OBJS:.o=.dep)
+-include $(BM_FULLSTACK_STREAMING_PUMP_OBJS:.o=.dep)
 endif
 endif
 
 
-BM_CQ_SRC = \
-    test/cpp/microbenchmarks/bm_cq.cc \
+BM_FULLSTACK_TRICKLE_SRC = \
+    test/cpp/microbenchmarks/bm_fullstack_trickle.cc \
 
-BM_CQ_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CQ_SRC))))
+BM_FULLSTACK_TRICKLE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_FULLSTACK_TRICKLE_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/bm_cq: openssl_dep_error
+$(BINDIR)/$(CONFIG)/bm_fullstack_trickle: openssl_dep_error
 
 else
 
@@ -12604,39 +13812,40 @@ 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)/bm_cq: protobuf_dep_error
+$(BINDIR)/$(CONFIG)/bm_fullstack_trickle: protobuf_dep_error
 
 else
 
-$(BINDIR)/$(CONFIG)/bm_cq: $(PROTOBUF_DEP) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_fullstack_trickle: $(PROTOBUF_DEP) $(BM_FULLSTACK_TRICKLE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_cq
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_TRICKLE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_trickle
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq.o:  $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BM_FULLSTACK_TRICKLE_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_trickle.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_bm_cq: $(BM_CQ_OBJS:.o=.dep)
+deps_bm_fullstack_trickle: $(BM_FULLSTACK_TRICKLE_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(BM_CQ_OBJS:.o=.dep)
+-include $(BM_FULLSTACK_TRICKLE_OBJS:.o=.dep)
 endif
 endif
 
 
-BM_ERROR_SRC = \
-    test/cpp/microbenchmarks/bm_error.cc \
+BM_FULLSTACK_UNARY_PING_PONG_SRC = \
+    test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc \
 
-BM_ERROR_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_ERROR_SRC))))
+BM_FULLSTACK_UNARY_PING_PONG_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_FULLSTACK_UNARY_PING_PONG_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/bm_error: openssl_dep_error
+$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: openssl_dep_error
 
 else
 
@@ -12647,39 +13856,40 @@ 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)/bm_error: protobuf_dep_error
+$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: protobuf_dep_error
 
 else
 
-$(BINDIR)/$(CONFIG)/bm_error: $(PROTOBUF_DEP) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_UNARY_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_error
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_UNARY_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_error.o:  $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BM_FULLSTACK_UNARY_PING_PONG_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_bm_error: $(BM_ERROR_OBJS:.o=.dep)
+deps_bm_fullstack_unary_ping_pong: $(BM_FULLSTACK_UNARY_PING_PONG_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(BM_ERROR_OBJS:.o=.dep)
+-include $(BM_FULLSTACK_UNARY_PING_PONG_OBJS:.o=.dep)
 endif
 endif
 
 
-BM_FULLSTACK_SRC = \
-    test/cpp/microbenchmarks/bm_fullstack.cc \
+BM_METADATA_SRC = \
+    test/cpp/microbenchmarks/bm_metadata.cc \
 
-BM_FULLSTACK_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_FULLSTACK_SRC))))
+BM_METADATA_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_METADATA_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/bm_fullstack: openssl_dep_error
+$(BINDIR)/$(CONFIG)/bm_metadata: openssl_dep_error
 
 else
 
@@ -12690,39 +13900,40 @@ 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)/bm_fullstack: protobuf_dep_error
+$(BINDIR)/$(CONFIG)/bm_metadata: protobuf_dep_error
 
 else
 
-$(BINDIR)/$(CONFIG)/bm_fullstack: $(PROTOBUF_DEP) $(BM_FULLSTACK_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_metadata: $(PROTOBUF_DEP) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_metadata
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack.o:  $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BM_METADATA_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_metadata.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_bm_fullstack: $(BM_FULLSTACK_OBJS:.o=.dep)
+deps_bm_metadata: $(BM_METADATA_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(BM_FULLSTACK_OBJS:.o=.dep)
+-include $(BM_METADATA_OBJS:.o=.dep)
 endif
 endif
 
 
-BM_METADATA_SRC = \
-    test/cpp/microbenchmarks/bm_metadata.cc \
+BM_POLLSET_SRC = \
+    test/cpp/microbenchmarks/bm_pollset.cc \
 
-BM_METADATA_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_METADATA_SRC))))
+BM_POLLSET_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_POLLSET_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/bm_metadata: openssl_dep_error
+$(BINDIR)/$(CONFIG)/bm_pollset: openssl_dep_error
 
 else
 
@@ -12733,26 +13944,27 @@ 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)/bm_metadata: protobuf_dep_error
+$(BINDIR)/$(CONFIG)/bm_pollset: protobuf_dep_error
 
 else
 
-$(BINDIR)/$(CONFIG)/bm_metadata: $(PROTOBUF_DEP) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_pollset: $(PROTOBUF_DEP) $(BM_POLLSET_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_metadata
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_POLLSET_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_pollset
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_metadata.o:  $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BM_POLLSET_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_pollset.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_bm_metadata: $(BM_METADATA_OBJS:.o=.dep)
+deps_bm_pollset: $(BM_POLLSET_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(BM_METADATA_OBJS:.o=.dep)
+-include $(BM_POLLSET_OBJS:.o=.dep)
 endif
 endif
 
@@ -13060,28 +14272,28 @@ $(BINDIR)/$(CONFIG)/codegen_test_minimal: protobuf_dep_error
 
 else
 
-$(BINDIR)/$(CONFIG)/codegen_test_minimal: $(PROTOBUF_DEP) $(CODEGEN_TEST_MINIMAL_OBJS)
+$(BINDIR)/$(CONFIG)/codegen_test_minimal: $(PROTOBUF_DEP) $(CODEGEN_TEST_MINIMAL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(CODEGEN_TEST_MINIMAL_OBJS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/codegen_test_minimal
+	$(Q) $(LDXX) $(LDFLAGS) $(CODEGEN_TEST_MINIMAL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/codegen_test_minimal
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/control.o: 
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/control.o:  $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: 
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o:  $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/payloads.o: 
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/payloads.o:  $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/services.o: 
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/services.o:  $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/stats.o: 
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/stats.o:  $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-$(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_minimal.o: 
+$(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_minimal.o:  $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o:  $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_codegen_test_minimal: $(CODEGEN_TEST_MINIMAL_OBJS:.o=.dep)
 
@@ -13352,6 +14564,53 @@ endif
 endif
 
 
+ERROR_DETAILS_TEST_SRC = \
+    $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \
+    test/cpp/util/error_details_test.cc \
+
+ERROR_DETAILS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ERROR_DETAILS_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/error_details_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)/error_details_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/error_details_test: $(PROTOBUF_DEP) $(ERROR_DETAILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(ERROR_DETAILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/error_details_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++.a
+
+$(OBJDIR)/$(CONFIG)/test/cpp/util/error_details_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++.a
+
+deps_error_details_test: $(ERROR_DETAILS_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(ERROR_DETAILS_TEST_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/test/cpp/util/error_details_test.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc
+
+
 FILTER_END2END_TEST_SRC = \
     test/cpp/end2end/filter_end2end_test.cc \
 
@@ -13842,6 +15101,53 @@ endif
 $(OBJDIR)/$(CONFIG)/test/cpp/grpclb/grpclb_api_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc
 
 
+GRPCLB_END2END_TEST_SRC = \
+    $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc \
+    test/cpp/end2end/grpclb_end2end_test.cc \
+
+GRPCLB_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPCLB_END2END_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/grpclb_end2end_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_end2end_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/grpclb_end2end_test: $(PROTOBUF_DEP) $(GRPCLB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(GRPCLB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpclb_end2end_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v1/load_balancer.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/grpclb_end2end_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_grpclb_end2end_test: $(GRPCLB_END2END_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(GRPCLB_END2END_TEST_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/grpclb_end2end_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc
+
+
 GRPCLB_TEST_SRC = \
     $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc \
     test/cpp/grpclb/grpclb_test.cc \
@@ -14154,6 +15460,49 @@ endif
 endif
 
 
+MEMORY_TEST_SRC = \
+    test/core/support/memory_test.cc \
+
+MEMORY_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MEMORY_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/memory_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)/memory_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/memory_test: $(PROTOBUF_DEP) $(MEMORY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(MEMORY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/memory_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/support/memory_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_memory_test: $(MEMORY_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(MEMORY_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 METRICS_CLIENT_SRC = \
     $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc \
     test/cpp/interop/metrics_client.cc \
@@ -14276,6 +15625,7 @@ endif
 
 endif
 
+$(NOOP-BENCHMARK_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
 $(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/noop-benchmark.o:  $(LIBDIR)/$(CONFIG)/libbenchmark.a
 
 deps_noop-benchmark: $(NOOP-BENCHMARK_OBJS:.o=.dep)
@@ -14823,6 +16173,56 @@ endif
 endif
 
 
+SERVER_BUILDER_TEST_SRC = \
+    $(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 \
+    test/cpp/server/server_builder_test.cc \
+
+SERVER_BUILDER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_BUILDER_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/server_builder_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)/server_builder_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/server_builder_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_server_builder_test: $(SERVER_BUILDER_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(SERVER_BUILDER_TEST_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_test.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
+
+
 SERVER_CONTEXT_TEST_SPOUSE_TEST_SRC = \
     test/cpp/test/server_context_test_spouse_test.cc \
 
@@ -15089,7 +16489,6 @@ STRESS_TEST_SRC = \
     test/cpp/interop/interop_client.cc \
     test/cpp/interop/stress_interop_client.cc \
     test/cpp/interop/stress_test.cc \
-    test/cpp/util/create_test_channel.cc \
     test/cpp/util/metrics_server.cc \
 
 STRESS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(STRESS_TEST_SRC))))
@@ -15135,8 +16534,6 @@ $(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_interop_client.o:  $(LIBDIR)/$(CONFI
 
 $(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
 
-$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
-
 $(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_server.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
 
 deps_stress_test: $(STRESS_TEST_OBJS:.o=.dep)
@@ -15149,7 +16546,6 @@ endif
 $(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_client.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/metrics.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.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/stress_interop_client.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/metrics.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.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/stress_test.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/metrics.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.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/metrics.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_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/metrics.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc
 
 
@@ -15342,6 +16738,8 @@ $(BINDIR)/$(CONFIG)/boringssl_aes_test:  $(LIBDIR)/$(CONFIG)/libboringssl_aes_te
 
 endif
 
+$(BORINGSSL_AES_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_AES_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15369,6 +16767,8 @@ $(BINDIR)/$(CONFIG)/boringssl_asn1_test:  $(LIBDIR)/$(CONFIG)/libboringssl_asn1_
 
 endif
 
+$(BORINGSSL_ASN1_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_ASN1_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15396,6 +16796,8 @@ $(BINDIR)/$(CONFIG)/boringssl_base64_test:  $(LIBDIR)/$(CONFIG)/libboringssl_bas
 
 endif
 
+$(BORINGSSL_BASE64_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_BASE64_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15423,6 +16825,8 @@ $(BINDIR)/$(CONFIG)/boringssl_bio_test:  $(LIBDIR)/$(CONFIG)/libboringssl_bio_te
 
 endif
 
+$(BORINGSSL_BIO_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_BIO_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15450,6 +16854,8 @@ $(BINDIR)/$(CONFIG)/boringssl_bn_test:  $(LIBDIR)/$(CONFIG)/libboringssl_bn_test
 
 endif
 
+$(BORINGSSL_BN_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_BN_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15477,6 +16883,8 @@ $(BINDIR)/$(CONFIG)/boringssl_bytestring_test:  $(LIBDIR)/$(CONFIG)/libboringssl
 
 endif
 
+$(BORINGSSL_BYTESTRING_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_BYTESTRING_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15504,6 +16912,8 @@ $(BINDIR)/$(CONFIG)/boringssl_chacha_test:  $(LIBDIR)/$(CONFIG)/libboringssl_cha
 
 endif
 
+$(BORINGSSL_CHACHA_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_CHACHA_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15531,6 +16941,8 @@ $(BINDIR)/$(CONFIG)/boringssl_aead_test:  $(LIBDIR)/$(CONFIG)/libboringssl_aead_
 
 endif
 
+$(BORINGSSL_AEAD_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_AEAD_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15558,6 +16970,8 @@ $(BINDIR)/$(CONFIG)/boringssl_cipher_test:  $(LIBDIR)/$(CONFIG)/libboringssl_cip
 
 endif
 
+$(BORINGSSL_CIPHER_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_CIPHER_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15585,6 +16999,8 @@ $(BINDIR)/$(CONFIG)/boringssl_cmac_test:  $(LIBDIR)/$(CONFIG)/libboringssl_cmac_
 
 endif
 
+$(BORINGSSL_CMAC_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_CMAC_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15612,6 +17028,8 @@ $(BINDIR)/$(CONFIG)/boringssl_constant_time_test:  $(LIBDIR)/$(CONFIG)/libboring
 
 endif
 
+$(BORINGSSL_CONSTANT_TIME_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_CONSTANT_TIME_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15639,6 +17057,8 @@ $(BINDIR)/$(CONFIG)/boringssl_ed25519_test:  $(LIBDIR)/$(CONFIG)/libboringssl_ed
 
 endif
 
+$(BORINGSSL_ED25519_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_ED25519_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15666,6 +17086,8 @@ $(BINDIR)/$(CONFIG)/boringssl_spake25519_test:  $(LIBDIR)/$(CONFIG)/libboringssl
 
 endif
 
+$(BORINGSSL_SPAKE25519_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_SPAKE25519_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15693,6 +17115,8 @@ $(BINDIR)/$(CONFIG)/boringssl_x25519_test:  $(LIBDIR)/$(CONFIG)/libboringssl_x25
 
 endif
 
+$(BORINGSSL_X25519_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_X25519_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15720,6 +17144,8 @@ $(BINDIR)/$(CONFIG)/boringssl_dh_test:  $(LIBDIR)/$(CONFIG)/libboringssl_dh_test
 
 endif
 
+$(BORINGSSL_DH_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_DH_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15747,6 +17173,8 @@ $(BINDIR)/$(CONFIG)/boringssl_digest_test:  $(LIBDIR)/$(CONFIG)/libboringssl_dig
 
 endif
 
+$(BORINGSSL_DIGEST_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_DIGEST_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15774,6 +17202,8 @@ $(BINDIR)/$(CONFIG)/boringssl_dsa_test:  $(LIBDIR)/$(CONFIG)/libboringssl_dsa_te
 
 endif
 
+$(BORINGSSL_DSA_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_DSA_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15801,6 +17231,8 @@ $(BINDIR)/$(CONFIG)/boringssl_ec_test:  $(LIBDIR)/$(CONFIG)/libboringssl_ec_test
 
 endif
 
+$(BORINGSSL_EC_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_EC_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15828,6 +17260,8 @@ $(BINDIR)/$(CONFIG)/boringssl_example_mul:  $(LIBDIR)/$(CONFIG)/libboringssl_exa
 
 endif
 
+$(BORINGSSL_EXAMPLE_MUL_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_EXAMPLE_MUL_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15855,6 +17289,8 @@ $(BINDIR)/$(CONFIG)/boringssl_ecdh_test:  $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_
 
 endif
 
+$(BORINGSSL_ECDH_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_ECDH_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15882,6 +17318,8 @@ $(BINDIR)/$(CONFIG)/boringssl_ecdsa_sign_test:  $(LIBDIR)/$(CONFIG)/libboringssl
 
 endif
 
+$(BORINGSSL_ECDSA_SIGN_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_ECDSA_SIGN_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15909,6 +17347,8 @@ $(BINDIR)/$(CONFIG)/boringssl_ecdsa_test:  $(LIBDIR)/$(CONFIG)/libboringssl_ecds
 
 endif
 
+$(BORINGSSL_ECDSA_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_ECDSA_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15936,6 +17376,8 @@ $(BINDIR)/$(CONFIG)/boringssl_ecdsa_verify_test:  $(LIBDIR)/$(CONFIG)/libborings
 
 endif
 
+$(BORINGSSL_ECDSA_VERIFY_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_ECDSA_VERIFY_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15963,6 +17405,8 @@ $(BINDIR)/$(CONFIG)/boringssl_err_test:  $(LIBDIR)/$(CONFIG)/libboringssl_err_te
 
 endif
 
+$(BORINGSSL_ERR_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_ERR_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -15990,6 +17434,8 @@ $(BINDIR)/$(CONFIG)/boringssl_evp_extra_test:  $(LIBDIR)/$(CONFIG)/libboringssl_
 
 endif
 
+$(BORINGSSL_EVP_EXTRA_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_EVP_EXTRA_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16017,6 +17463,8 @@ $(BINDIR)/$(CONFIG)/boringssl_evp_test:  $(LIBDIR)/$(CONFIG)/libboringssl_evp_te
 
 endif
 
+$(BORINGSSL_EVP_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_EVP_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16044,6 +17492,8 @@ $(BINDIR)/$(CONFIG)/boringssl_pbkdf_test:  $(LIBDIR)/$(CONFIG)/libboringssl_pbkd
 
 endif
 
+$(BORINGSSL_PBKDF_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_PBKDF_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16071,6 +17521,8 @@ $(BINDIR)/$(CONFIG)/boringssl_hkdf_test:  $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_
 
 endif
 
+$(BORINGSSL_HKDF_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_HKDF_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16098,6 +17550,8 @@ $(BINDIR)/$(CONFIG)/boringssl_hmac_test:  $(LIBDIR)/$(CONFIG)/libboringssl_hmac_
 
 endif
 
+$(BORINGSSL_HMAC_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_HMAC_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16125,6 +17579,8 @@ $(BINDIR)/$(CONFIG)/boringssl_lhash_test:  $(LIBDIR)/$(CONFIG)/libboringssl_lhas
 
 endif
 
+$(BORINGSSL_LHASH_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_LHASH_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16152,6 +17608,8 @@ $(BINDIR)/$(CONFIG)/boringssl_gcm_test:  $(LIBDIR)/$(CONFIG)/libboringssl_gcm_te
 
 endif
 
+$(BORINGSSL_GCM_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_GCM_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16179,6 +17637,8 @@ $(BINDIR)/$(CONFIG)/boringssl_newhope_statistical_test:  $(LIBDIR)/$(CONFIG)/lib
 
 endif
 
+$(BORINGSSL_NEWHOPE_STATISTICAL_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_NEWHOPE_STATISTICAL_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16206,6 +17666,8 @@ $(BINDIR)/$(CONFIG)/boringssl_newhope_test:  $(LIBDIR)/$(CONFIG)/libboringssl_ne
 
 endif
 
+$(BORINGSSL_NEWHOPE_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_NEWHOPE_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16233,6 +17695,8 @@ $(BINDIR)/$(CONFIG)/boringssl_newhope_vectors_test:  $(LIBDIR)/$(CONFIG)/libbori
 
 endif
 
+$(BORINGSSL_NEWHOPE_VECTORS_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_NEWHOPE_VECTORS_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16260,6 +17724,8 @@ $(BINDIR)/$(CONFIG)/boringssl_obj_test:  $(LIBDIR)/$(CONFIG)/libboringssl_obj_te
 
 endif
 
+$(BORINGSSL_OBJ_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_OBJ_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16287,6 +17753,8 @@ $(BINDIR)/$(CONFIG)/boringssl_pkcs12_test:  $(LIBDIR)/$(CONFIG)/libboringssl_pkc
 
 endif
 
+$(BORINGSSL_PKCS12_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_PKCS12_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16314,6 +17782,8 @@ $(BINDIR)/$(CONFIG)/boringssl_pkcs8_test:  $(LIBDIR)/$(CONFIG)/libboringssl_pkcs
 
 endif
 
+$(BORINGSSL_PKCS8_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_PKCS8_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16341,6 +17811,8 @@ $(BINDIR)/$(CONFIG)/boringssl_poly1305_test:  $(LIBDIR)/$(CONFIG)/libboringssl_p
 
 endif
 
+$(BORINGSSL_POLY1305_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_POLY1305_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16368,6 +17840,8 @@ $(BINDIR)/$(CONFIG)/boringssl_refcount_test:  $(LIBDIR)/$(CONFIG)/libboringssl_r
 
 endif
 
+$(BORINGSSL_REFCOUNT_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_REFCOUNT_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16395,6 +17869,8 @@ $(BINDIR)/$(CONFIG)/boringssl_rsa_test:  $(LIBDIR)/$(CONFIG)/libboringssl_rsa_te
 
 endif
 
+$(BORINGSSL_RSA_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_RSA_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16422,6 +17898,8 @@ $(BINDIR)/$(CONFIG)/boringssl_thread_test:  $(LIBDIR)/$(CONFIG)/libboringssl_thr
 
 endif
 
+$(BORINGSSL_THREAD_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_THREAD_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16449,6 +17927,8 @@ $(BINDIR)/$(CONFIG)/boringssl_pkcs7_test:  $(LIBDIR)/$(CONFIG)/libboringssl_pkcs
 
 endif
 
+$(BORINGSSL_PKCS7_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_PKCS7_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16476,6 +17956,8 @@ $(BINDIR)/$(CONFIG)/boringssl_x509_test:  $(LIBDIR)/$(CONFIG)/libboringssl_x509_
 
 endif
 
+$(BORINGSSL_X509_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_X509_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16503,6 +17985,8 @@ $(BINDIR)/$(CONFIG)/boringssl_tab_test:  $(LIBDIR)/$(CONFIG)/libboringssl_tab_te
 
 endif
 
+$(BORINGSSL_TAB_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_TAB_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16530,6 +18014,8 @@ $(BINDIR)/$(CONFIG)/boringssl_v3name_test:  $(LIBDIR)/$(CONFIG)/libboringssl_v3n
 
 endif
 
+$(BORINGSSL_V3NAME_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_V3NAME_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -16557,6 +18043,8 @@ $(BINDIR)/$(CONFIG)/boringssl_ssl_test:  $(LIBDIR)/$(CONFIG)/libboringssl_ssl_te
 
 endif
 
+$(BORINGSSL_SSL_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(BORINGSSL_SSL_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare $(NO_W_EXTRA_SEMI)
 
 
 
@@ -18123,7 +19611,7 @@ ifneq ($(OPENSSL_DEP),)
 # This is to ensure the embedded OpenSSL is built beforehand, properly
 # 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/ext/lb_policy/grpclb/grpclb_channel_secure.c: $(OPENSSL_DEP)
+src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c: $(OPENSSL_DEP)
 src/core/ext/transport/chttp2/client/secure/secure_channel_create.c: $(OPENSSL_DEP)
 src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c: $(OPENSSL_DEP)
 src/core/ext/transport/cronet/client/secure/cronet_channel_create.c: $(OPENSSL_DEP)
@@ -18151,14 +19639,14 @@ src/core/lib/security/transport/security_connector.c: $(OPENSSL_DEP)
 src/core/lib/security/transport/security_handshaker.c: $(OPENSSL_DEP)
 src/core/lib/security/transport/server_auth_filter.c: $(OPENSSL_DEP)
 src/core/lib/security/transport/tsi_error.c: $(OPENSSL_DEP)
-src/core/lib/security/util/b64.c: $(OPENSSL_DEP)
 src/core/lib/security/util/json_util.c: $(OPENSSL_DEP)
 src/core/lib/surface/init_secure.c: $(OPENSSL_DEP)
-src/core/lib/tsi/fake_transport_security.c: $(OPENSSL_DEP)
-src/core/lib/tsi/ssl_transport_security.c: $(OPENSSL_DEP)
-src/core/lib/tsi/transport_security.c: $(OPENSSL_DEP)
 src/core/plugin_registry/grpc_cronet_plugin_registry.c: $(OPENSSL_DEP)
 src/core/plugin_registry/grpc_plugin_registry.c: $(OPENSSL_DEP)
+src/core/tsi/fake_transport_security.c: $(OPENSSL_DEP)
+src/core/tsi/ssl_transport_security.c: $(OPENSSL_DEP)
+src/core/tsi/transport_security.c: $(OPENSSL_DEP)
+src/core/tsi/transport_security_adapter.c: $(OPENSSL_DEP)
 src/cpp/client/cronet_credentials.cc: $(OPENSSL_DEP)
 src/cpp/client/secure_credentials.cc: $(OPENSSL_DEP)
 src/cpp/common/auth_property_iterator.cc: $(OPENSSL_DEP)
@@ -18168,6 +19656,7 @@ src/cpp/common/secure_create_auth_context.cc: $(OPENSSL_DEP)
 src/cpp/ext/proto_server_reflection.cc: $(OPENSSL_DEP)
 src/cpp/ext/proto_server_reflection_plugin.cc: $(OPENSSL_DEP)
 src/cpp/server/secure_server_credentials.cc: $(OPENSSL_DEP)
+src/cpp/util/error_details.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_common.c: $(OPENSSL_DEP)
@@ -18188,6 +19677,8 @@ test/cpp/interop/interop_client.cc: $(OPENSSL_DEP)
 test/cpp/interop/interop_server.cc: $(OPENSSL_DEP)
 test/cpp/interop/interop_server_bootstrap.cc: $(OPENSSL_DEP)
 test/cpp/interop/server_helper.cc: $(OPENSSL_DEP)
+test/cpp/microbenchmarks/helpers.cc: $(OPENSSL_DEP)
+test/cpp/qps/benchmark_config.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)
@@ -18197,7 +19688,6 @@ 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/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)
 test/cpp/util/cli_credentials.cc: $(OPENSSL_DEP)
diff --git a/PYTHON-MANIFEST.in b/PYTHON-MANIFEST.in
index adeb39064958e0c56b2f82165ba438618b2aef4b..8be0af964f0e4fea20d3468656683f5f04306505 100644
--- a/PYTHON-MANIFEST.in
+++ b/PYTHON-MANIFEST.in
@@ -7,6 +7,7 @@ graft include/grpc
 graft third_party/boringssl
 graft third_party/nanopb
 graft third_party/zlib
+graft third_party/cares
 include src/python/grpcio/_spawn_patch.py
 include src/python/grpcio/commands.py
 include src/python/grpcio/grpc_version.py
@@ -16,3 +17,4 @@ include src/python/grpcio/support.py
 include src/python/grpcio/README.rst
 include requirements.txt
 include etc/roots.pem
+include Makefile
diff --git a/README.md b/README.md
index 174e861f5945fd9a4bd81e14c5ca4252b59bad41..0edea88518569a336408ee4fa50e4f93bf1761c6 100644
--- a/README.md
+++ b/README.md
@@ -7,11 +7,11 @@
 
 Copyright 2015 Google Inc.
 
-#Documentation
+# Documentation
 
 You can find more detailed documentation and examples in the [doc](doc) and [examples](examples) directories respectively.
 
-#Installation & Testing
+# Installation & Testing
 
 See [INSTALL](INSTALL.md) for installation instructions for various platforms.
 
@@ -19,32 +19,31 @@ See [tools/run_tests](tools/run_tests) for more guidance on how to run various t
 
 See [Performance dashboard](http://performance-dot-grpc-testing.appspot.com/explore?dashboard=5712453606309888) for the performance numbers for v1.0.x.
 
-#Repository Structure & Status
+# Repository Structure & Status
 
-This repository contains source code for gRPC libraries for multiple languages written on top of shared C core library [src/core] (src/core).
+This repository contains source code for gRPC libraries for multiple languages written on top of shared C core library [src/core](src/core).
 
 Libraries in different languages may be in different states of development. We are seeking contributions for all of these libraries.
 
 | Language                | Source                              | Status  |
 |-------------------------|-------------------------------------|---------|
-| Shared C [core library] | [src/core] (src/core)               | 1.0     |
-| C++                     | [src/cpp] (src/cpp)                 | 1.0     |
-| Ruby                    | [src/ruby] (src/ruby)               | 1.0     |
-| NodeJS                  | [src/node] (src/node)               | 1.0     |
-| Python                  | [src/python] (src/python)           | 1.0     |
-| PHP                     | [src/php] (src/php)                 | 1.0     |
-| C#                      | [src/csharp] (src/csharp)           | 1.0     |
-| Objective-C             | [src/objective-c] (src/objective-c) | 1.0     |
-
-<small>
-Java source code is in the [grpc-java] (http://github.com/grpc/grpc-java) repository.
-Go source code is in the [grpc-go] (http://github.com/grpc/grpc-go) repository.
-</small>
+| Shared C [core library] | [src/core](src/core)                | 1.0     |
+| C++                     | [src/cpp](src/cpp)                  | 1.0     |
+| Ruby                    | [src/ruby](src/ruby)                | 1.0     |
+| NodeJS                  | [src/node](src/node)                | 1.0     |
+| Python                  | [src/python](src/python)            | 1.0     |
+| PHP                     | [src/php](src/php)                  | 1.0     |
+| C#                      | [src/csharp](src/csharp)            | 1.0     |
+| Objective-C             | [src/objective-c](src/objective-c)  | 1.0     |
+
+Java source code is in the [grpc-java](http://github.com/grpc/grpc-java)
+repository. Go source code is in the
+[grpc-go](http://github.com/grpc/grpc-go) repository.
 
 See [MANIFEST.md](MANIFEST.md) for a listing of top-level items in the
 repository.
 
-#Overview
+# Overview
 
 
 Remote Procedure Calls (RPCs) provide a useful abstraction for building
@@ -54,7 +53,7 @@ These libraries enable communication between clients and servers using any
 combination of the supported languages.
 
 
-##Interface
+## Interface
 
 
 Developers using gRPC typically start with the description of an RPC service
@@ -66,7 +65,7 @@ Interface Definition Language (IDL) for describing both the service interface
 and the structure of the payload messages. It is possible to use other
 alternatives if desired.
 
-###Surface API
+### Surface API
 Starting from an interface definition in a .proto file, gRPC provides
 Protocol Compiler plugins that generate Client- and Server-side APIs.
 gRPC users typically call into these APIs on the Client side and implement
@@ -94,7 +93,7 @@ the client and the server can send a stream of messages to each other. The strea
 messages are delivered in the order they were sent.
 
 
-#Protocol
+# Protocol
 
 The [gRPC protocol](doc/PROTOCOL-HTTP2.md) specifies the abstract requirements for communication between
 clients and servers. A concrete embedding over HTTP/2 completes the picture by
diff --git a/Rakefile b/Rakefile
index 12ac12710fb8876d8d5f77edd7d17174d0c6d7a0..7f8d3a2f4acb418de7eba6adba38a8d0899e9bd5 100755
--- a/Rakefile
+++ b/Rakefile
@@ -12,7 +12,8 @@ load 'tools/distrib/docker_for_windows.rb'
 # Add rubocop style checking tasks
 RuboCop::RakeTask.new(:rubocop) do |task|
   task.options = ['-c', 'src/ruby/.rubocop.yml']
-  task.patterns = ['src/ruby/{lib,spec}/**/*.rb']
+  # add end2end tests to formatter but don't add generated proto _pb.rb's
+  task.patterns = ['src/ruby/{lib,spec}/**/*.rb', 'src/ruby/end2end/*.rb']
 end
 
 spec = Gem::Specification.load('grpc.gemspec')
@@ -79,7 +80,7 @@ task 'dlls' do
   grpc_config = ENV['GRPC_CONFIG'] || 'opt'
   verbose = ENV['V'] || '0'
 
-  env = 'CPPFLAGS="-D_WIN32_WINNT=0x600 -DUNICODE -D_UNICODE -Wno-unused-variable -Wno-unused-result" '
+  env = 'CPPFLAGS="-D_WIN32_WINNT=0x600 -DUNICODE -D_UNICODE -Wno-unused-variable -Wno-unused-result -DCARES_STATICLIB" '
   env += 'LDFLAGS=-static '
   env += 'SYSTEM=MINGW32 '
   env += 'EMBED_ZLIB=true '
diff --git a/WORKSPACE b/WORKSPACE
index 9b79d04cde6f9e7fd6750f4e592d0e0064f61078..a78a88979e7d149283a9cf3582a31cf964909927 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -15,17 +15,22 @@ bind(
 
 bind(
     name = "protobuf",
-    actual = "@submodule_protobuf//:protobuf",
+    actual = "@com_google_protobuf//:protobuf",
 )
 
 bind(
     name = "protobuf_clib",
-    actual = "@submodule_protobuf//:protoc_lib",
+    actual = "@com_google_protobuf//:protoc_lib",
 )
 
 bind(
     name = "protocol_compiler",
-    actual = "@submodule_protobuf//:protoc",
+    actual = "@com_google_protobuf//:protoc",
+)
+
+bind(
+    name = "cares",
+    actual = "@submodule_cares//:ares",
 )
 
 bind(
@@ -33,14 +38,18 @@ bind(
     actual = "@submodule_gtest//:gtest",
 )
 
+bind(
+    name = "benchmark",
+    actual = "@submodule_benchmark//:benchmark",
+)
+
 bind(
     name = "gflags",
     actual = "@com_github_gflags_gflags//:gflags",
 )
 
-new_local_repository(
+local_repository(
     name = "submodule_boringssl",
-    build_file = "third_party/boringssl-with-bazel/BUILD",
     path = "third_party/boringssl-with-bazel",
 )
 
@@ -51,7 +60,7 @@ new_local_repository(
 )
 
 new_local_repository(
-    name = "submodule_protobuf",
+    name = "com_google_protobuf",
     build_file = "third_party/protobuf/BUILD",
     path = "third_party/protobuf",
 )
@@ -66,3 +75,15 @@ local_repository(
     name = "com_github_gflags_gflags",
     path = "third_party/gflags",
 )
+
+new_local_repository(
+    name = "submodule_benchmark",
+    path = "third_party/benchmark",
+    build_file = "third_party/benchmark.BUILD",
+)
+
+new_local_repository(
+    name = "submodule_cares",
+    path = "third_party/cares",
+    build_file = "third_party/cares/cares.BUILD",
+)
diff --git a/bazel/BUILD b/bazel/BUILD
index b86dcc2ad7ef79bb7308fc4b898d0e2cb64a7433..cb2d9d66aeed3e12f6dd11e4541ab57afe4f2f49 100644
--- a/bazel/BUILD
+++ b/bazel/BUILD
@@ -35,12 +35,12 @@ load(":cc_grpc_library.bzl", "cc_grpc_library")
 
 proto_library(
     name = "well_known_protos_list",
-    srcs = ["@submodule_protobuf//:well_known_protos"],
+    srcs = ["@com_google_protobuf//:well_known_protos"],
 )
 
 cc_grpc_library(
     name = "well_known_protos",
     srcs = "well_known_protos_list",
-    deps = [],
     proto_only = True,
+    deps = [],
 )
diff --git a/bazel/cc_grpc_library.bzl b/bazel/cc_grpc_library.bzl
index 9020eacb740453cbb4f96250aa13d8e2c184e586..0600bb9e304c4f3a92cba88d0a9830d258563e68 100644
--- a/bazel/cc_grpc_library.bzl
+++ b/bazel/cc_grpc_library.bzl
@@ -2,7 +2,7 @@
 
 load("//:bazel/generate_cc.bzl", "generate_cc")
 
-def cc_grpc_library(name, srcs, deps, proto_only, **kwargs):
+def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, generate_mock, use_external = False, **kwargs):
   """Generates C++ grpc classes from a .proto file.
 
   Assumes the generated classes will be used in cc_api_version = 2.
@@ -12,6 +12,12 @@ def cc_grpc_library(name, srcs, deps, proto_only, **kwargs):
       srcs: a single proto_library, which wraps the .proto files with services.
       deps: a list of C++ proto_library (or cc_proto_library) which provides
         the compiled code of any message that the services depend on.
+      well_known_protos: The target from protobuf library that exports well
+        known protos. Currently it will only work if the value is
+        "@com_google_protobuf//:well_known_protos"
+      use_external: When True the grpc deps are prefixed with //external. This
+        allows grpc to be used as a dependency in other bazel projects.
+      generate_mock: When true GMOCk code for client stub is generated.
       **kwargs: rest of arguments, e.g., compatible_with and visibility.
   """
   if len(srcs) > 1:
@@ -33,22 +39,38 @@ def cc_grpc_library(name, srcs, deps, proto_only, **kwargs):
   generate_cc(
       name = codegen_target,
       srcs = [proto_target],
+      well_known_protos = well_known_protos,
       **kwargs
   )
 
   if not proto_only:
+    if use_external:
+      # when this file is used by non-grpc projects
+      plugin = "//external:grpc_cpp_plugin"
+    else:
+      plugin = "//:grpc_cpp_plugin"
+
     generate_cc(
         name = codegen_grpc_target,
         srcs = [proto_target],
-        plugin = "//:grpc_cpp_plugin",
+        plugin = plugin,
+        well_known_protos = well_known_protos,
+        generate_mock = generate_mock,
         **kwargs
     )
 
+    if use_external:
+      # when this file is used by non-grpc projects
+      grpc_deps = ["//external:grpc++", "//external:grpc++_codegen_proto",
+                   "//external:protobuf"]
+    else:
+      grpc_deps = ["//:grpc++", "//:grpc++_codegen_proto", "//external:protobuf"]
+
     native.cc_library(
         name = name,
         srcs = [":" + codegen_grpc_target, ":" + codegen_target],
         hdrs = [":" + codegen_grpc_target, ":" + codegen_target],
-        deps = deps + ["//:grpc++", "//:grpc++_codegen_proto", "//external:protobuf"],
+        deps = deps + grpc_deps,
         **kwargs
     )
   else:
diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl
index d49cbe8d7289e8f4355f59f8f794d5dcaa2b303b..d05509fc153280f2283c3d0437922b009e25188c 100644
--- a/bazel/generate_cc.bzl
+++ b/bazel/generate_cc.bzl
@@ -9,21 +9,26 @@ def generate_cc_impl(ctx):
   protos = [f for src in ctx.attr.srcs for f in src.proto.direct_sources]
   includes = [f for src in ctx.attr.srcs for f in src.proto.transitive_imports]
   outs = []
+  # label_len is length of the path from WORKSPACE root to the location of this build file
+  label_len = len(ctx.label.package) + 1
   if ctx.executable.plugin:
-    outs += [proto.basename[:-len(".proto")] + ".grpc.pb.h" for proto in protos]
-    outs += [proto.basename[:-len(".proto")] + ".grpc.pb.cc" for proto in protos]
+    outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.h" for proto in protos]
+    outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.cc" for proto in protos]
+    if ctx.attr.generate_mock:
+      outs += [proto.path[label_len:-len(".proto")] + "_mock.grpc.pb.h" for proto in protos]
   else:
-    outs += [proto.basename[:-len(".proto")] + ".pb.h" for proto in protos]
-    outs += [proto.basename[:-len(".proto")] + ".pb.cc" for proto in protos]
+    outs += [proto.path[label_len:-len(".proto")] + ".pb.h" for proto in protos]
+    outs += [proto.path[label_len:-len(".proto")] + ".pb.cc" for proto in protos]
   out_files = [ctx.new_file(out) for out in outs]
-  # The following should be replaced with ctx.configuration.buildout
-  # whenever this is added to Skylark.
-  dir_out = out_files[0].dirname[:-len(protos[0].dirname)]
+  dir_out = str(ctx.genfiles_dir.path)
 
   arguments = []
   if ctx.executable.plugin:
     arguments += ["--plugin=protoc-gen-PLUGIN=" + ctx.executable.plugin.path]
-    arguments += ["--PLUGIN_out=" + ",".join(ctx.attr.flags) + ":" + dir_out]
+    flags = list(ctx.attr.flags)
+    if ctx.attr.generate_mock:
+      flags.append("generate_mock_code=true")
+    arguments += ["--PLUGIN_out=" + ",".join(flags) + ":" + dir_out]
     additional_input = [ctx.executable.plugin]
   else:
     arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out]
@@ -31,8 +36,20 @@ def generate_cc_impl(ctx):
   arguments += ["-I{0}={0}".format(include.path) for include in includes]
   arguments += [proto.path for proto in protos]
 
+  # create a list of well known proto files if the argument is non-None
+  well_known_proto_files = []
+  if ctx.attr.well_known_protos:
+    f = ctx.attr.well_known_protos.files.to_list()[0].dirname
+    if f != "external/com_google_protobuf/src/google/protobuf":
+      print("Error: Only @com_google_protobuf//:well_known_protos is supported")
+    else:
+      # f points to "external/com_google_protobuf/src/google/protobuf"
+      # add -I argument to protoc so it knows where to look for the proto files.
+      arguments += ["-I{0}".format(f + "/../..")]
+      well_known_proto_files = [f for f in ctx.attr.well_known_protos.files]
+
   ctx.action(
-      inputs = protos + includes + additional_input,
+      inputs = protos + includes + additional_input + well_known_proto_files,
       outputs = out_files,
       executable = ctx.executable._protoc,
       arguments = arguments,
@@ -56,6 +73,13 @@ generate_cc = rule(
             mandatory = False,
             allow_empty = True,
         ),
+        "well_known_protos" : attr.label(
+            mandatory = False,
+        ),
+        "generate_mock" : attr.bool(
+            default = False,
+            mandatory = False,
+        ),
         "_protoc": attr.label(
             default = Label("//external:protocol_compiler"),
             executable = True,
diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl
index daf8b78527a23b4a8dd77f89c0c0c95217e7fb59..a104fa00a0b9d6164fdc4534a71626caa711a428 100644
--- a/bazel/grpc_build_system.bzl
+++ b/bazel/grpc_build_system.bzl
@@ -49,6 +49,22 @@ def grpc_cc_library(name, srcs = [], public_hdrs = [], hdrs = [], external_deps
     ]
   )
 
+def grpc_cc_libraries(name_list, additional_src_list = [], additional_dep_list = [], srcs = [], public_hdrs = [], hdrs = [], external_deps = [], deps = [], standalone = False, language="C++"):
+  names = len(name_list)
+  asl = additional_src_list + [[]]*(names - len(additional_src_list))
+  adl = additional_dep_list + [[]]*(names - len(additional_dep_list))
+  for i in range(names):
+    grpc_cc_library(
+      name = name_list[i],
+      srcs = srcs + asl[i],
+      hdrs = hdrs,
+      public_hdrs = public_hdrs,
+      deps = deps + adl[i],
+      external_deps = external_deps,
+      standalone = standalone,
+      language = language
+    )
+
 def grpc_proto_plugin(name, srcs = [], deps = []):
   native.cc_binary(
     name = name,
@@ -58,11 +74,15 @@ def grpc_proto_plugin(name, srcs = [], deps = []):
 
 load("//:bazel/cc_grpc_library.bzl", "cc_grpc_library")
 
-def grpc_proto_library(name, srcs = [], deps = [], well_known_deps = [], has_services = True):
+def grpc_proto_library(name, srcs = [], deps = [], well_known_protos = None,
+                       has_services = True, use_external = False, generate_mock = False):
   cc_grpc_library(
     name = name,
     srcs = srcs,
     deps = deps,
+    well_known_protos = well_known_protos,
     proto_only = not has_services,
+    use_external = use_external,
+    generate_mock = generate_mock,
   )
 
diff --git a/binding.gyp b/binding.gyp
index 6fbe59bd6e5a9815b9acbe1eaecf5c185a74066c..c8dd5c1cfdde7d5a6aeb99eb92b9d5690673987b 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -39,24 +39,80 @@
 {
   'variables': {
     'runtime%': 'node',
-    # UV integration in C core is disabled by default while bugs are ironed
-    # out. It can be re-enabled for one build by setting the npm config
-    # variable grpc_uv to true, and it can be re-enabled permanently by
-    # setting it to true here.
-    'grpc_uv%': 'false'
+    # Some Node installations use the system installation of OpenSSL, and on
+    # some systems, the system OpenSSL still does not have ALPN support. This
+    # will let users recompile gRPC to work without ALPN.
+    'grpc_alpn%': 'true',
+    # Indicates that the library should be built with gcov.
+    'grpc_gcov%': 'false',
+    # Indicates that the library should be built with compatibility for musl
+    # libc, so that it can run on Alpine Linux. This is only necessary if not
+    # building on Alpine Linux
+    'grpc_alpine%': 'false'
   },
   'target_defaults': {
+    'configurations': {
+      'Release': {
+        'cflags': [
+            '-O2',
+        ],
+        'defines': [
+            'NDEBUG',
+        ],
+      },
+      'Debug': {
+        'cflags': [
+            '-O0',
+        ],
+        'defines': [
+            '_DEBUG',
+            'DEBUG',
+        ],
+      },
+    },
+    'cflags': [
+        '-g',
+        '-Wall',
+        '-Wextra',
+        '-Werror',
+        '-Wno-long-long',
+        '-Wno-unused-parameter',
+        '-DOSATOMIC_USE_INLINED=1',
+    ],
+    'ldflags': [
+        '-g',
+    ],
     'include_dirs': [
       '.',
       'include'
     ],
     'defines': [
-      'GPR_BACKWARDS_COMPATIBILITY_MODE'
+      'GPR_BACKWARDS_COMPATIBILITY_MODE',
+      'GRPC_ARES=0',
+      'GRPC_UV'
     ],
     'conditions': [
-      ['grpc_uv=="true"', {
+      ['grpc_gcov=="true"', {
+        'cflags': [
+            '-O0',
+            '-fprofile-arcs',
+            '-ftest-coverage',
+            '-Wno-return-type',
+        ],
         'defines': [
-          'GRPC_UV'
+            '_DEBUG',
+            'DEBUG',
+            'GPR_GCOV',
+        ],
+        'ldflags': [
+            '-fprofile-arcs',
+            '-ftest-coverage',
+            '-rdynamic',
+        ],
+      }],
+      ['grpc_alpine=="true"', {
+        'defines': [
+          'GPR_MUSL_LIBC_COMPAT'
         ]
       }],
       ['OS!="win" and runtime=="electron"', {
@@ -73,10 +129,16 @@
           'OPENSSL_NO_ASM'
         ]
       }, {
-        # As of the beginning of 2017, we only support versions of Node with
-        # embedded versions of OpenSSL that support ALPN
-        'defines': [
-          'TSI_OPENSSL_ALPN_SUPPORT=1'
+        'conditions': [
+          ['grpc_alpn=="true"', {
+            'defines': [
+              'TSI_OPENSSL_ALPN_SUPPORT=1'
+            ],
+          }, {
+            'defines': [
+              'TSI_OPENSSL_ALPN_SUPPORT=0'
+            ],
+          }]
         ],
         'include_dirs': [
           '<(node_root_dir)/deps/openssl/openssl/include',
@@ -95,7 +157,8 @@
       }],
       ['OS == "win"', {
         "include_dirs": [
-          "third_party/zlib"
+          "third_party/zlib",
+          "third_party/cares/cares"
         ],
         "defines": [
           '_WIN32_WINNT=0x0600',
@@ -114,25 +177,9 @@
           "ws2_32"
         ]
       }, { # OS != "win"
-        'variables': {
-          'config': '<!(echo $CONFIG)',
-        },
         'include_dirs': [
-          '<(node_root_dir)/deps/zlib'
-        ],
-        'conditions': [
-          ['config=="gcov"', {
-            'cflags': [
-              '-ftest-coverage',
-              '-fprofile-arcs',
-              '-O0'
-            ],
-            'ldflags': [
-              '-ftest-coverage',
-              '-fprofile-arcs'
-            ]
-          }
-         ]
+          '<(node_root_dir)/deps/zlib',
+          '<(node_root_dir)/deps/cares/include'
         ]
       }]
     ]
@@ -460,7 +507,7 @@
         },
       ]
     }],
-    ['OS == "win"', {
+    ['OS == "win" and runtime!="electron"', {
       'targets': [
         {
           # IMPORTANT WINDOWS BUILD INFORMATION
@@ -471,10 +518,13 @@
           # when including the Node headers. The remedy for this is to remove
           # the OpenSSL headers, from the downloaded Node development package,
           # which is typically located in `.node-gyp` in your home directory.
+          #
+          # This is not true of Electron, which does not have OpenSSL headers.
           'target_name': 'WINDOWS_BUILD_WARNING',
-          'actions': [
+          'rules': [
             {
-              'action_name': 'WINDOWS_BUILD_WARNING',
+              'rule_name': 'WINDOWS_BUILD_WARNING',
+              'extension': 'S',
               'inputs': [
                 'package.json'
               ],
@@ -485,6 +535,10 @@
             }
           ]
         },
+      ]
+    }],
+    ['OS == "win"', {
+      'targets': [
         # Only want to compile zlib under Windows
         {
           'cflags': [
@@ -534,6 +588,8 @@
         'src/core/lib/profiling/basic_timers.c',
         'src/core/lib/profiling/stap_timers.c',
         'src/core/lib/support/alloc.c',
+        'src/core/lib/support/arena.c',
+        'src/core/lib/support/atm.c',
         'src/core/lib/support/avl.c',
         'src/core/lib/support/backoff.c',
         'src/core/lib/support/cmdline.c',
@@ -601,15 +657,10 @@
         'src/core/lib/channel/channel_args.c',
         'src/core/lib/channel/channel_stack.c',
         'src/core/lib/channel/channel_stack_builder.c',
-        'src/core/lib/channel/compress_filter.c',
         'src/core/lib/channel/connected_channel.c',
-        'src/core/lib/channel/deadline_filter.c',
         'src/core/lib/channel/handshaker.c',
         'src/core/lib/channel/handshaker_factory.c',
         'src/core/lib/channel/handshaker_registry.c',
-        'src/core/lib/channel/http_client_filter.c',
-        'src/core/lib/channel/http_server_filter.c',
-        'src/core/lib/channel/message_size_filter.c',
         'src/core/lib/compression/compression.c',
         'src/core/lib/compression/message_compress.c',
         'src/core/lib/debug/trace.c',
@@ -634,6 +685,7 @@
         'src/core/lib/iomgr/iomgr_uv.c',
         'src/core/lib/iomgr/iomgr_windows.c',
         'src/core/lib/iomgr/load_file.c',
+        'src/core/lib/iomgr/lockfree_event.c',
         'src/core/lib/iomgr/network_status_tracker.c',
         'src/core/lib/iomgr/polling_entity.c',
         'src/core/lib/iomgr/pollset_set_uv.c',
@@ -645,6 +697,7 @@
         'src/core/lib/iomgr/resolve_address_windows.c',
         'src/core/lib/iomgr/resource_quota.c',
         'src/core/lib/iomgr/sockaddr_utils.c',
+        'src/core/lib/iomgr/socket_factory_posix.c',
         'src/core/lib/iomgr/socket_mutator.c',
         'src/core/lib/iomgr/socket_utils_common_posix.c',
         'src/core/lib/iomgr/socket_utils_linux.c',
@@ -657,6 +710,9 @@
         'src/core/lib/iomgr/tcp_client_windows.c',
         'src/core/lib/iomgr/tcp_posix.c',
         'src/core/lib/iomgr/tcp_server_posix.c',
+        'src/core/lib/iomgr/tcp_server_utils_posix_common.c',
+        'src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c',
+        'src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c',
         'src/core/lib/iomgr/tcp_server_uv.c',
         'src/core/lib/iomgr/tcp_server_windows.c',
         'src/core/lib/iomgr/tcp_uv.c',
@@ -679,6 +735,7 @@
         'src/core/lib/json/json_reader.c',
         'src/core/lib/json/json_string.c',
         'src/core/lib/json/json_writer.c',
+        'src/core/lib/slice/b64.c',
         'src/core/lib/slice/percent_encoding.c',
         'src/core/lib/slice/slice.c',
         'src/core/lib/slice/slice_buffer.c',
@@ -697,8 +754,9 @@
         'src/core/lib/surface/channel_ping.c',
         'src/core/lib/surface/channel_stack_type.c',
         'src/core/lib/surface/completion_queue.c',
+        'src/core/lib/surface/completion_queue_factory.c',
         'src/core/lib/surface/event_string.c',
-        'src/core/lib/surface/lame_client.c',
+        'src/core/lib/surface/lame_client.cc',
         'src/core/lib/surface/metadata_array.c',
         'src/core/lib/surface/server.c',
         'src/core/lib/surface/validate_metadata.c',
@@ -730,6 +788,7 @@
         'src/core/ext/transport/chttp2/transport/hpack_encoder.c',
         'src/core/ext/transport/chttp2/transport/hpack_parser.c',
         'src/core/ext/transport/chttp2/transport/hpack_table.c',
+        'src/core/ext/transport/chttp2/transport/http2_settings.c',
         'src/core/ext/transport/chttp2/transport/huffsyms.c',
         'src/core/ext/transport/chttp2/transport/incoming_metadata.c',
         'src/core/ext/transport/chttp2/transport/parsing.c',
@@ -738,6 +797,10 @@
         'src/core/ext/transport/chttp2/transport/varint.c',
         'src/core/ext/transport/chttp2/transport/writing.c',
         'src/core/ext/transport/chttp2/alpn/alpn.c',
+        'src/core/ext/filters/http/client/http_client_filter.c',
+        'src/core/ext/filters/http/http_filters_plugin.c',
+        'src/core/ext/filters/http/message_compress/message_compress_filter.c',
+        'src/core/ext/filters/http/server/http_server_filter.c',
         'src/core/lib/http/httpcli_security_connector.c',
         'src/core/lib/security/context/security_context.c',
         'src/core/lib/security/credentials/composite/composite_credentials.c',
@@ -760,53 +823,58 @@
         'src/core/lib/security/transport/security_handshaker.c',
         'src/core/lib/security/transport/server_auth_filter.c',
         'src/core/lib/security/transport/tsi_error.c',
-        'src/core/lib/security/util/b64.c',
         'src/core/lib/security/util/json_util.c',
         'src/core/lib/surface/init_secure.c',
-        'src/core/lib/tsi/fake_transport_security.c',
-        'src/core/lib/tsi/ssl_transport_security.c',
-        'src/core/lib/tsi/transport_security.c',
+        'src/core/tsi/fake_transport_security.c',
+        'src/core/tsi/ssl_transport_security.c',
+        'src/core/tsi/transport_security.c',
+        'src/core/tsi/transport_security_adapter.c',
         'src/core/ext/transport/chttp2/server/chttp2_server.c',
         'src/core/ext/transport/chttp2/client/secure/secure_channel_create.c',
-        'src/core/ext/client_channel/channel_connectivity.c',
-        'src/core/ext/client_channel/client_channel.c',
-        'src/core/ext/client_channel/client_channel_factory.c',
-        'src/core/ext/client_channel/client_channel_plugin.c',
-        'src/core/ext/client_channel/connector.c',
-        'src/core/ext/client_channel/default_initial_connect_string.c',
-        'src/core/ext/client_channel/http_connect_handshaker.c',
-        'src/core/ext/client_channel/http_proxy.c',
-        'src/core/ext/client_channel/initial_connect_string.c',
-        'src/core/ext/client_channel/lb_policy.c',
-        'src/core/ext/client_channel/lb_policy_factory.c',
-        'src/core/ext/client_channel/lb_policy_registry.c',
-        'src/core/ext/client_channel/parse_address.c',
-        'src/core/ext/client_channel/proxy_mapper.c',
-        'src/core/ext/client_channel/proxy_mapper_registry.c',
-        'src/core/ext/client_channel/resolver.c',
-        'src/core/ext/client_channel/resolver_factory.c',
-        'src/core/ext/client_channel/resolver_registry.c',
-        'src/core/ext/client_channel/subchannel.c',
-        'src/core/ext/client_channel/subchannel_index.c',
-        'src/core/ext/client_channel/uri_parser.c',
+        'src/core/ext/filters/client_channel/channel_connectivity.c',
+        'src/core/ext/filters/client_channel/client_channel.c',
+        'src/core/ext/filters/client_channel/client_channel_factory.c',
+        'src/core/ext/filters/client_channel/client_channel_plugin.c',
+        'src/core/ext/filters/client_channel/connector.c',
+        'src/core/ext/filters/client_channel/http_connect_handshaker.c',
+        'src/core/ext/filters/client_channel/http_proxy.c',
+        'src/core/ext/filters/client_channel/lb_policy.c',
+        'src/core/ext/filters/client_channel/lb_policy_factory.c',
+        'src/core/ext/filters/client_channel/lb_policy_registry.c',
+        'src/core/ext/filters/client_channel/parse_address.c',
+        'src/core/ext/filters/client_channel/proxy_mapper.c',
+        'src/core/ext/filters/client_channel/proxy_mapper_registry.c',
+        'src/core/ext/filters/client_channel/resolver.c',
+        'src/core/ext/filters/client_channel/resolver_factory.c',
+        'src/core/ext/filters/client_channel/resolver_registry.c',
+        'src/core/ext/filters/client_channel/retry_throttle.c',
+        'src/core/ext/filters/client_channel/subchannel.c',
+        'src/core/ext/filters/client_channel/subchannel_index.c',
+        'src/core/ext/filters/client_channel/uri_parser.c',
+        'src/core/ext/filters/deadline/deadline_filter.c',
         'src/core/ext/transport/chttp2/client/chttp2_connector.c',
         'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
         'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c',
         'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
         'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c',
-        'src/core/ext/lb_policy/grpclb/grpclb.c',
-        'src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c',
-        'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
-        'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
+        'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c',
+        'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c',
+        'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c',
+        'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c',
+        'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c',
+        'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
         'third_party/nanopb/pb_common.c',
         'third_party/nanopb/pb_decode.c',
         'third_party/nanopb/pb_encode.c',
-        'src/core/ext/lb_policy/pick_first/pick_first.c',
-        'src/core/ext/lb_policy/round_robin/round_robin.c',
-        'src/core/ext/resolver/dns/native/dns_resolver.c',
-        'src/core/ext/resolver/sockaddr/sockaddr_resolver.c',
-        'src/core/ext/load_reporting/load_reporting.c',
-        'src/core/ext/load_reporting/load_reporting_filter.c',
+        'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c',
+        'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c',
+        'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c',
+        'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c',
+        'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c',
+        'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c',
+        'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c',
+        'src/core/ext/filters/load_reporting/load_reporting.c',
+        'src/core/ext/filters/load_reporting/load_reporting_filter.c',
         'src/core/ext/census/base_resources.c',
         'src/core/ext/census/context.c',
         'src/core/ext/census/gen/census.pb.c',
@@ -821,6 +889,8 @@
         'src/core/ext/census/resource.c',
         'src/core/ext/census/trace_context.c',
         'src/core/ext/census/tracing.c',
+        'src/core/ext/filters/max_age/max_age_filter.c',
+        'src/core/ext/filters/message_size/message_size_filter.c',
         'src/core/plugin_registry/grpc_plugin_registry.c',
       ],
       "conditions": [
@@ -837,16 +907,10 @@
       ],
       'cflags': [
         '-std=c++11',
-        '-Wall',
         '-pthread',
-        '-g',
         '-zdefs',
-        '-Werror',
         '-Wno-error=deprecated-declarations'
       ],
-      'ldflags': [
-        '-g'
-      ],
       "conditions": [
         ['OS=="win" or runtime=="electron"', {
           'dependencies': [
@@ -880,13 +944,10 @@
         "src/node/ext/call_credentials.cc",
         "src/node/ext/channel.cc",
         "src/node/ext/channel_credentials.cc",
-        "src/node/ext/completion_queue_threadpool.cc",
-        "src/node/ext/completion_queue_uv.cc",
+        "src/node/ext/completion_queue.cc",
         "src/node/ext/node_grpc.cc",
         "src/node/ext/server.cc",
         "src/node/ext/server_credentials.cc",
-        "src/node/ext/server_generic.cc",
-        "src/node/ext/server_uv.cc",
         "src/node/ext/slice.cc",
         "src/node/ext/timeval.cc",
       ],
diff --git a/build.yaml b/build.yaml
index f59640f8abbde8733f7314ee92ecec345218ff59..b29306023460ba413c06c97928e1c242ac5ca4e4 100644
--- a/build.yaml
+++ b/build.yaml
@@ -6,15 +6,15 @@ settings:
   '#02': ===
   '#03': Please update the 'g_stands_for' field periodically with a new g word
   '#04': not listed in doc/g_stands_for.md - and update that document to list the
-  '#05': new word.
+  '#05': new word. When doing so, please also update BUILD.
   '#06': ===
   '#07': Master always has a "-dev" suffix
   '#08': Use "-preN" suffixes to identify pre-release versions
   '#09': Per-language overrides are possible with (eg) ruby_version tag here
   '#10': See the expand_version.py for all the quirks here
-  core_version: 3.0.0-dev
-  g_stands_for: green
-  version: 1.2.0-dev
+  core_version: 4.0.0-dev
+  g_stands_for: gregarious
+  version: 1.4.0-dev
 filegroups:
 - name: census
   public_headers:
@@ -85,9 +85,14 @@ filegroups:
   - include/grpc/support/useful.h
   headers:
   - src/core/lib/profiling/timers.h
+  - src/core/lib/support/arena.h
+  - src/core/lib/support/atomic.h
+  - src/core/lib/support/atomic_with_atm.h
+  - src/core/lib/support/atomic_with_std.h
   - src/core/lib/support/backoff.h
   - src/core/lib/support/block_annotate.h
   - src/core/lib/support/env.h
+  - src/core/lib/support/memory.h
   - src/core/lib/support/mpscq.h
   - src/core/lib/support/murmur_hash.h
   - src/core/lib/support/spinlock.h
@@ -101,6 +106,8 @@ filegroups:
   - src/core/lib/profiling/basic_timers.c
   - src/core/lib/profiling/stap_timers.c
   - src/core/lib/support/alloc.c
+  - src/core/lib/support/arena.c
+  - src/core/lib/support/atm.c
   - src/core/lib/support/avl.c
   - src/core/lib/support/backoff.c
   - src/core/lib/support/cmdline.c
@@ -153,7 +160,6 @@ filegroups:
   - include/grpc/impl/codegen/gpr_slice.h
   - include/grpc/impl/codegen/gpr_types.h
   - include/grpc/impl/codegen/port_platform.h
-  - include/grpc/impl/codegen/slice.h
   - include/grpc/impl/codegen/sync.h
   - include/grpc/impl/codegen/sync_generic.h
   - include/grpc/impl/codegen/sync_posix.h
@@ -174,16 +180,11 @@ filegroups:
   - src/core/lib/channel/channel_args.h
   - src/core/lib/channel/channel_stack.h
   - src/core/lib/channel/channel_stack_builder.h
-  - src/core/lib/channel/compress_filter.h
   - src/core/lib/channel/connected_channel.h
   - src/core/lib/channel/context.h
-  - src/core/lib/channel/deadline_filter.h
   - src/core/lib/channel/handshaker.h
   - src/core/lib/channel/handshaker_factory.h
   - src/core/lib/channel/handshaker_registry.h
-  - src/core/lib/channel/http_client_filter.h
-  - src/core/lib/channel/http_server_filter.h
-  - src/core/lib/channel/message_size_filter.h
   - src/core/lib/compression/algorithm_metadata.h
   - src/core/lib/compression/message_compress.h
   - src/core/lib/debug/trace.h
@@ -206,6 +207,7 @@ filegroups:
   - src/core/lib/iomgr/iomgr_internal.h
   - src/core/lib/iomgr/iomgr_posix.h
   - src/core/lib/iomgr/load_file.h
+  - src/core/lib/iomgr/lockfree_event.h
   - src/core/lib/iomgr/network_status_tracker.h
   - src/core/lib/iomgr/polling_entity.h
   - src/core/lib/iomgr/pollset.h
@@ -220,6 +222,7 @@ filegroups:
   - src/core/lib/iomgr/sockaddr_posix.h
   - src/core/lib/iomgr/sockaddr_utils.h
   - src/core/lib/iomgr/sockaddr_windows.h
+  - src/core/lib/iomgr/socket_factory_posix.h
   - src/core/lib/iomgr/socket_mutator.h
   - src/core/lib/iomgr/socket_utils.h
   - src/core/lib/iomgr/socket_utils_posix.h
@@ -228,6 +231,7 @@ filegroups:
   - src/core/lib/iomgr/tcp_client_posix.h
   - src/core/lib/iomgr/tcp_posix.h
   - src/core/lib/iomgr/tcp_server.h
+  - src/core/lib/iomgr/tcp_server_utils_posix.h
   - src/core/lib/iomgr/tcp_uv.h
   - src/core/lib/iomgr/tcp_windows.h
   - src/core/lib/iomgr/time_averaged_stats.h
@@ -247,6 +251,7 @@ filegroups:
   - src/core/lib/json/json_common.h
   - src/core/lib/json/json_reader.h
   - src/core/lib/json/json_writer.h
+  - src/core/lib/slice/b64.h
   - src/core/lib/slice/percent_encoding.h
   - src/core/lib/slice/slice_hash_table.h
   - src/core/lib/slice/slice_internal.h
@@ -258,6 +263,7 @@ filegroups:
   - src/core/lib/surface/channel_init.h
   - src/core/lib/surface/channel_stack_type.h
   - src/core/lib/surface/completion_queue.h
+  - src/core/lib/surface/completion_queue_factory.h
   - src/core/lib/surface/event_string.h
   - src/core/lib/surface/init.h
   - src/core/lib/surface/lame_client.h
@@ -281,15 +287,10 @@ filegroups:
   - src/core/lib/channel/channel_args.c
   - src/core/lib/channel/channel_stack.c
   - src/core/lib/channel/channel_stack_builder.c
-  - src/core/lib/channel/compress_filter.c
   - src/core/lib/channel/connected_channel.c
-  - src/core/lib/channel/deadline_filter.c
   - src/core/lib/channel/handshaker.c
   - src/core/lib/channel/handshaker_factory.c
   - src/core/lib/channel/handshaker_registry.c
-  - src/core/lib/channel/http_client_filter.c
-  - src/core/lib/channel/http_server_filter.c
-  - src/core/lib/channel/message_size_filter.c
   - src/core/lib/compression/compression.c
   - src/core/lib/compression/message_compress.c
   - src/core/lib/debug/trace.c
@@ -314,6 +315,7 @@ filegroups:
   - src/core/lib/iomgr/iomgr_uv.c
   - src/core/lib/iomgr/iomgr_windows.c
   - src/core/lib/iomgr/load_file.c
+  - src/core/lib/iomgr/lockfree_event.c
   - src/core/lib/iomgr/network_status_tracker.c
   - src/core/lib/iomgr/polling_entity.c
   - src/core/lib/iomgr/pollset_set_uv.c
@@ -325,6 +327,7 @@ filegroups:
   - src/core/lib/iomgr/resolve_address_windows.c
   - src/core/lib/iomgr/resource_quota.c
   - src/core/lib/iomgr/sockaddr_utils.c
+  - src/core/lib/iomgr/socket_factory_posix.c
   - src/core/lib/iomgr/socket_mutator.c
   - src/core/lib/iomgr/socket_utils_common_posix.c
   - src/core/lib/iomgr/socket_utils_linux.c
@@ -337,6 +340,9 @@ filegroups:
   - src/core/lib/iomgr/tcp_client_windows.c
   - src/core/lib/iomgr/tcp_posix.c
   - src/core/lib/iomgr/tcp_server_posix.c
+  - src/core/lib/iomgr/tcp_server_utils_posix_common.c
+  - src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
+  - src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
   - src/core/lib/iomgr/tcp_server_uv.c
   - src/core/lib/iomgr/tcp_server_windows.c
   - src/core/lib/iomgr/tcp_uv.c
@@ -359,6 +365,7 @@ filegroups:
   - src/core/lib/json/json_reader.c
   - src/core/lib/json/json_string.c
   - src/core/lib/json/json_writer.c
+  - src/core/lib/slice/b64.c
   - src/core/lib/slice/percent_encoding.c
   - src/core/lib/slice/slice.c
   - src/core/lib/slice/slice_buffer.c
@@ -377,8 +384,9 @@ filegroups:
   - src/core/lib/surface/channel_ping.c
   - src/core/lib/surface/channel_stack_type.c
   - src/core/lib/surface/completion_queue.c
+  - src/core/lib/surface/completion_queue_factory.c
   - src/core/lib/surface/event_string.c
-  - src/core/lib/surface/lame_client.c
+  - src/core/lib/surface/lame_client.cc
   - src/core/lib/surface/metadata_array.c
   - src/core/lib/surface/server.c
   - src/core/lib/surface/validate_metadata.c
@@ -402,49 +410,49 @@ filegroups:
   - grpc_codegen
 - name: grpc_client_channel
   headers:
-  - src/core/ext/client_channel/client_channel.h
-  - src/core/ext/client_channel/client_channel_factory.h
-  - src/core/ext/client_channel/connector.h
-  - src/core/ext/client_channel/http_connect_handshaker.h
-  - src/core/ext/client_channel/http_proxy.h
-  - src/core/ext/client_channel/initial_connect_string.h
-  - src/core/ext/client_channel/lb_policy.h
-  - src/core/ext/client_channel/lb_policy_factory.h
-  - src/core/ext/client_channel/lb_policy_registry.h
-  - src/core/ext/client_channel/parse_address.h
-  - src/core/ext/client_channel/proxy_mapper.h
-  - src/core/ext/client_channel/proxy_mapper_registry.h
-  - src/core/ext/client_channel/resolver.h
-  - src/core/ext/client_channel/resolver_factory.h
-  - src/core/ext/client_channel/resolver_registry.h
-  - src/core/ext/client_channel/subchannel.h
-  - src/core/ext/client_channel/subchannel_index.h
-  - src/core/ext/client_channel/uri_parser.h
-  src:
-  - src/core/ext/client_channel/channel_connectivity.c
-  - src/core/ext/client_channel/client_channel.c
-  - src/core/ext/client_channel/client_channel_factory.c
-  - src/core/ext/client_channel/client_channel_plugin.c
-  - src/core/ext/client_channel/connector.c
-  - src/core/ext/client_channel/default_initial_connect_string.c
-  - src/core/ext/client_channel/http_connect_handshaker.c
-  - src/core/ext/client_channel/http_proxy.c
-  - src/core/ext/client_channel/initial_connect_string.c
-  - src/core/ext/client_channel/lb_policy.c
-  - src/core/ext/client_channel/lb_policy_factory.c
-  - src/core/ext/client_channel/lb_policy_registry.c
-  - src/core/ext/client_channel/parse_address.c
-  - src/core/ext/client_channel/proxy_mapper.c
-  - src/core/ext/client_channel/proxy_mapper_registry.c
-  - src/core/ext/client_channel/resolver.c
-  - src/core/ext/client_channel/resolver_factory.c
-  - src/core/ext/client_channel/resolver_registry.c
-  - src/core/ext/client_channel/subchannel.c
-  - src/core/ext/client_channel/subchannel_index.c
-  - src/core/ext/client_channel/uri_parser.c
+  - src/core/ext/filters/client_channel/client_channel.h
+  - src/core/ext/filters/client_channel/client_channel_factory.h
+  - src/core/ext/filters/client_channel/connector.h
+  - src/core/ext/filters/client_channel/http_connect_handshaker.h
+  - src/core/ext/filters/client_channel/http_proxy.h
+  - src/core/ext/filters/client_channel/lb_policy.h
+  - src/core/ext/filters/client_channel/lb_policy_factory.h
+  - src/core/ext/filters/client_channel/lb_policy_registry.h
+  - src/core/ext/filters/client_channel/parse_address.h
+  - src/core/ext/filters/client_channel/proxy_mapper.h
+  - src/core/ext/filters/client_channel/proxy_mapper_registry.h
+  - src/core/ext/filters/client_channel/resolver.h
+  - src/core/ext/filters/client_channel/resolver_factory.h
+  - src/core/ext/filters/client_channel/resolver_registry.h
+  - src/core/ext/filters/client_channel/retry_throttle.h
+  - src/core/ext/filters/client_channel/subchannel.h
+  - src/core/ext/filters/client_channel/subchannel_index.h
+  - src/core/ext/filters/client_channel/uri_parser.h
+  src:
+  - src/core/ext/filters/client_channel/channel_connectivity.c
+  - src/core/ext/filters/client_channel/client_channel.c
+  - src/core/ext/filters/client_channel/client_channel_factory.c
+  - src/core/ext/filters/client_channel/client_channel_plugin.c
+  - src/core/ext/filters/client_channel/connector.c
+  - src/core/ext/filters/client_channel/http_connect_handshaker.c
+  - src/core/ext/filters/client_channel/http_proxy.c
+  - src/core/ext/filters/client_channel/lb_policy.c
+  - src/core/ext/filters/client_channel/lb_policy_factory.c
+  - src/core/ext/filters/client_channel/lb_policy_registry.c
+  - src/core/ext/filters/client_channel/parse_address.c
+  - src/core/ext/filters/client_channel/proxy_mapper.c
+  - src/core/ext/filters/client_channel/proxy_mapper_registry.c
+  - src/core/ext/filters/client_channel/resolver.c
+  - src/core/ext/filters/client_channel/resolver_factory.c
+  - src/core/ext/filters/client_channel/resolver_registry.c
+  - src/core/ext/filters/client_channel/retry_throttle.c
+  - src/core/ext/filters/client_channel/subchannel.c
+  - src/core/ext/filters/client_channel/subchannel_index.c
+  - src/core/ext/filters/client_channel/uri_parser.c
   plugin: grpc_client_channel
   uses:
   - grpc_base
+  - grpc_deadline_filter
 - name: grpc_codegen
   public_headers:
   - include/grpc/impl/codegen/byte_buffer_reader.h
@@ -453,20 +461,46 @@ filegroups:
   - include/grpc/impl/codegen/exec_ctx_fwd.h
   - include/grpc/impl/codegen/grpc_types.h
   - include/grpc/impl/codegen/propagation_bits.h
+  - include/grpc/impl/codegen/slice.h
   - include/grpc/impl/codegen/status.h
   uses:
   - gpr_codegen
+- name: grpc_deadline_filter
+  headers:
+  - src/core/ext/filters/deadline/deadline_filter.h
+  src:
+  - src/core/ext/filters/deadline/deadline_filter.c
+  plugin: grpc_deadline_filter
+  uses:
+  - grpc_base
+- name: grpc_http_filters
+  headers:
+  - src/core/ext/filters/http/client/http_client_filter.h
+  - src/core/ext/filters/http/message_compress/message_compress_filter.h
+  - src/core/ext/filters/http/server/http_server_filter.h
+  src:
+  - src/core/ext/filters/http/client/http_client_filter.c
+  - src/core/ext/filters/http/http_filters_plugin.c
+  - src/core/ext/filters/http/message_compress/message_compress_filter.c
+  - src/core/ext/filters/http/server/http_server_filter.c
+  plugin: grpc_http_filters
+  uses:
+  - grpc_base
 - name: grpc_lb_policy_grpclb
   headers:
-  - src/core/ext/lb_policy/grpclb/grpclb.h
-  - src/core/ext/lb_policy/grpclb/grpclb_channel.h
-  - src/core/ext/lb_policy/grpclb/load_balancer_api.h
-  - src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
-  src:
-  - src/core/ext/lb_policy/grpclb/grpclb.c
-  - src/core/ext/lb_policy/grpclb/grpclb_channel.c
-  - src/core/ext/lb_policy/grpclb/load_balancer_api.c
-  - src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
+  src:
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
   plugin: grpc_lb_policy_grpclb
   uses:
   - grpc_base
@@ -474,54 +508,87 @@ filegroups:
   - nanopb
 - name: grpc_lb_policy_grpclb_secure
   headers:
-  - src/core/ext/lb_policy/grpclb/grpclb.h
-  - src/core/ext/lb_policy/grpclb/grpclb_channel.h
-  - src/core/ext/lb_policy/grpclb/load_balancer_api.h
-  - src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
-  src:
-  - src/core/ext/lb_policy/grpclb/grpclb.c
-  - src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c
-  - src/core/ext/lb_policy/grpclb/load_balancer_api.c
-  - src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
+  src:
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c
+  - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
   plugin: grpc_lb_policy_grpclb
   uses:
   - grpc_base
+  - grpc_secure
   - grpc_client_channel
   - nanopb
 - name: grpc_lb_policy_pick_first
   src:
-  - src/core/ext/lb_policy/pick_first/pick_first.c
+  - src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c
   plugin: grpc_lb_policy_pick_first
   uses:
   - grpc_base
   - grpc_client_channel
 - name: grpc_lb_policy_round_robin
   src:
-  - src/core/ext/lb_policy/round_robin/round_robin.c
+  - src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c
   plugin: grpc_lb_policy_round_robin
   uses:
   - grpc_base
   - grpc_client_channel
 - name: grpc_load_reporting
   headers:
-  - src/core/ext/load_reporting/load_reporting.h
-  - src/core/ext/load_reporting/load_reporting_filter.h
+  - src/core/ext/filters/load_reporting/load_reporting.h
+  - src/core/ext/filters/load_reporting/load_reporting_filter.h
   src:
-  - src/core/ext/load_reporting/load_reporting.c
-  - src/core/ext/load_reporting/load_reporting_filter.c
+  - src/core/ext/filters/load_reporting/load_reporting.c
+  - src/core/ext/filters/load_reporting/load_reporting_filter.c
   plugin: grpc_load_reporting_plugin
   uses:
   - grpc_base
+- name: grpc_max_age_filter
+  headers:
+  - src/core/ext/filters/max_age/max_age_filter.h
+  src:
+  - src/core/ext/filters/max_age/max_age_filter.c
+  plugin: grpc_max_age_filter
+  uses:
+  - grpc_base
+- name: grpc_message_size_filter
+  headers:
+  - src/core/ext/filters/message_size/message_size_filter.h
+  src:
+  - src/core/ext/filters/message_size/message_size_filter.c
+  plugin: grpc_message_size_filter
+  uses:
+  - grpc_base
+- name: grpc_resolver_dns_ares
+  headers:
+  - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
+  - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
+  src:
+  - src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c
+  - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
+  - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
+  plugin: grpc_resolver_dns_ares
+  uses:
+  - grpc_base
+  - grpc_client_channel
 - name: grpc_resolver_dns_native
   src:
-  - src/core/ext/resolver/dns/native/dns_resolver.c
+  - src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c
   plugin: grpc_resolver_dns_native
   uses:
   - grpc_base
   - grpc_client_channel
 - name: grpc_resolver_sockaddr
   src:
-  - src/core/ext/resolver/sockaddr/sockaddr_resolver.c
+  - src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c
   plugin: grpc_resolver_sockaddr
   uses:
   - grpc_base
@@ -548,7 +615,6 @@ filegroups:
   - src/core/lib/security/transport/security_connector.h
   - src/core/lib/security/transport/security_handshaker.h
   - src/core/lib/security/transport/tsi_error.h
-  - src/core/lib/security/util/b64.h
   - src/core/lib/security/util/json_util.h
   src:
   - src/core/lib/http/httpcli_security_connector.c
@@ -573,7 +639,6 @@ filegroups:
   - src/core/lib/security/transport/security_handshaker.c
   - src/core/lib/security/transport/server_auth_filter.c
   - src/core/lib/security/transport/tsi_error.c
-  - src/core/lib/security/util/b64.c
   - src/core/lib/security/util/json_util.c
   - src/core/lib/surface/init_secure.c
   secure: true
@@ -586,7 +651,7 @@ filegroups:
   headers:
   - test/core/end2end/cq_verifier.h
   - test/core/end2end/fake_resolver.h
-  - test/core/end2end/fixtures/http_proxy.h
+  - test/core/end2end/fixtures/http_proxy_fixture.h
   - test/core/end2end/fixtures/proxy.h
   - test/core/iomgr/endpoint_tests.h
   - test/core/util/debugger_macros.h
@@ -602,7 +667,7 @@ filegroups:
   src:
   - test/core/end2end/cq_verifier.c
   - test/core/end2end/fake_resolver.c
-  - test/core/end2end/fixtures/http_proxy.c
+  - test/core/end2end/fixtures/http_proxy_fixture.c
   - test/core/end2end/fixtures/proxy.c
   - test/core/iomgr/endpoint_tests.c
   - test/core/util/debugger_macros.c
@@ -633,6 +698,7 @@ filegroups:
   - src/core/ext/transport/chttp2/transport/hpack_encoder.h
   - src/core/ext/transport/chttp2/transport/hpack_parser.h
   - src/core/ext/transport/chttp2/transport/hpack_table.h
+  - src/core/ext/transport/chttp2/transport/http2_settings.h
   - src/core/ext/transport/chttp2/transport/huffsyms.h
   - src/core/ext/transport/chttp2/transport/incoming_metadata.h
   - src/core/ext/transport/chttp2/transport/internal.h
@@ -652,6 +718,7 @@ filegroups:
   - src/core/ext/transport/chttp2/transport/hpack_encoder.c
   - src/core/ext/transport/chttp2/transport/hpack_parser.c
   - src/core/ext/transport/chttp2/transport/hpack_table.c
+  - src/core/ext/transport/chttp2/transport/http2_settings.c
   - src/core/ext/transport/chttp2/transport/huffsyms.c
   - src/core/ext/transport/chttp2/transport/incoming_metadata.c
   - src/core/ext/transport/chttp2/transport/parsing.c
@@ -663,6 +730,7 @@ filegroups:
   uses:
   - grpc_base
   - grpc_transport_chttp2_alpn
+  - grpc_http_filters
 - name: grpc_transport_chttp2_alpn
   headers:
   - src/core/ext/transport/chttp2/alpn/alpn.h
@@ -678,6 +746,7 @@ filegroups:
   uses:
   - grpc_transport_chttp2
   - grpc_base
+  - grpc_client_channel
 - name: grpc_transport_chttp2_client_insecure
   src:
   - src/core/ext/transport/chttp2/client/insecure/channel_create.c
@@ -735,6 +804,7 @@ filegroups:
   filegroups:
   - grpc_base
   - grpc_transport_chttp2
+  - grpc_http_filters
 - name: nanopb
   headers:
   - third_party/nanopb/pb.h
@@ -747,15 +817,17 @@ filegroups:
   - third_party/nanopb/pb_encode.c
 - name: tsi
   headers:
-  - src/core/lib/tsi/fake_transport_security.h
-  - src/core/lib/tsi/ssl_transport_security.h
-  - src/core/lib/tsi/ssl_types.h
-  - src/core/lib/tsi/transport_security.h
-  - src/core/lib/tsi/transport_security_interface.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_adapter.h
+  - src/core/tsi/transport_security_interface.h
   src:
-  - src/core/lib/tsi/fake_transport_security.c
-  - src/core/lib/tsi/ssl_transport_security.c
-  - src/core/lib/tsi/transport_security.c
+  - src/core/tsi/fake_transport_security.c
+  - src/core/tsi/ssl_transport_security.c
+  - src/core/tsi/transport_security.c
+  - src/core/tsi/transport_security_adapter.c
   deps:
   - gpr
   secure: true
@@ -774,6 +846,7 @@ filegroups:
   - include/grpc++/grpc++.h
   - include/grpc++/health_check_service_interface.h
   - include/grpc++/impl/call.h
+  - include/grpc++/impl/channel_argument_option.h
   - include/grpc++/impl/client_unary_call.h
   - include/grpc++/impl/codegen/core_codegen.h
   - include/grpc++/impl/grpc_library.h
@@ -830,6 +903,7 @@ filegroups:
   - src/cpp/common/rpc_method.cc
   - src/cpp/common/version_cc.cc
   - src/cpp/server/async_generic_service.cc
+  - src/cpp/server/channel_argument_option.cc
   - src/cpp/server/create_default_thread_pool.cc
   - src/cpp/server/dynamic_thread_pool.cc
   - src/cpp/server/health/default_health_check_service.cc
@@ -849,6 +923,8 @@ filegroups:
   - src/cpp/util/time_cc.cc
   uses:
   - grpc++_codegen_base
+  - grpc_base
+  - nanopb
 - name: grpc++_codegen_base
   language: c++
   public_headers:
@@ -877,7 +953,6 @@ filegroups:
   - include/grpc++/impl/codegen/slice.h
   - include/grpc++/impl/codegen/status.h
   - include/grpc++/impl/codegen/status_code_enum.h
-  - include/grpc++/impl/codegen/status_helper.h
   - include/grpc++/impl/codegen/string_ref.h
   - include/grpc++/impl/codegen/stub_options.h
   - include/grpc++/impl/codegen/sync_stream.h
@@ -908,16 +983,10 @@ filegroups:
 - name: grpc++_test
   language: c++
   public_headers:
+  - include/grpc++/test/mock_stream.h
   - include/grpc++/test/server_context_test_spouse.h
   deps:
   - grpc++
-- name: thrift_util
-  language: c++
-  public_headers:
-  - include/grpc++/impl/codegen/thrift_serializer.h
-  - include/grpc++/impl/codegen/thrift_utils.h
-  uses:
-  - grpc++_codegen_base
 libs:
 - name: gpr
   build: all
@@ -954,11 +1023,15 @@ libs:
   - grpc_lb_policy_grpclb_secure
   - grpc_lb_policy_pick_first
   - grpc_lb_policy_round_robin
+  - grpc_resolver_dns_ares
   - grpc_resolver_dns_native
   - grpc_resolver_sockaddr
   - grpc_load_reporting
   - grpc_secure
   - census
+  - grpc_max_age_filter
+  - grpc_message_size_filter
+  - grpc_deadline_filter
   generate_plugin_registry: true
   secure: true
   vs_packages:
@@ -1047,6 +1120,7 @@ libs:
   - grpc_base
   - grpc_transport_chttp2_server_insecure
   - grpc_transport_chttp2_client_insecure
+  - grpc_resolver_dns_ares
   - grpc_resolver_dns_native
   - grpc_resolver_sockaddr
   - grpc_load_reporting
@@ -1054,6 +1128,9 @@ libs:
   - grpc_lb_policy_pick_first
   - grpc_lb_policy_round_robin
   - census
+  - grpc_max_age_filter
+  - grpc_message_size_filter
+  - grpc_deadline_filter
   generate_plugin_registry: true
   secure: false
   vs_project_guid: '{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}'
@@ -1133,6 +1210,18 @@ libs:
   platforms:
   - linux
   secure: true
+- name: grpc++_error_details
+  build: all
+  language: c++
+  public_headers:
+  - include/grpc++/support/error_details.h
+  src:
+  - src/proto/grpc/status/status.proto
+  - src/cpp/util/error_details.cc
+  deps:
+  - grpc++
+  baselib: true
+  vs_project_guid: '{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}'
 - name: grpc++_proto_reflection_desc_db
   build: private
   language: c++
@@ -1195,7 +1284,6 @@ libs:
   - grpc++_codegen_base_src
   - grpc++_codegen_proto
   - grpc++_config_proto
-  - thrift_util
 - name: grpc++_unsecure
   build: all
   language: c++
@@ -1214,6 +1302,21 @@ libs:
   - grpc++_codegen_base_src
   secure: false
   vs_project_guid: '{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}'
+- name: grpc_benchmark
+  build: test
+  language: c++
+  headers:
+  - test/cpp/microbenchmarks/fullstack_context_mutators.h
+  - test/cpp/microbenchmarks/fullstack_fixtures.h
+  - test/cpp/microbenchmarks/helpers.h
+  src:
+  - test/cpp/microbenchmarks/helpers.cc
+  deps:
+  - benchmark
+  - grpc++
+  - grpc_test_util
+  - grpc
+  defaults: benchmark
 - name: grpc_cli_libs
   build: private
   language: c++
@@ -1252,11 +1355,15 @@ libs:
   - src/compiler/objective_c_generator_helpers.h
   - src/compiler/php_generator.h
   - src/compiler/php_generator_helpers.h
+  - src/compiler/protobuf_plugin.h
   - src/compiler/python_generator.h
+  - src/compiler/python_generator_helpers.h
+  - src/compiler/python_private_generator.h
   - src/compiler/ruby_generator.h
   - src/compiler/ruby_generator_helpers-inl.h
   - src/compiler/ruby_generator_map-inl.h
   - src/compiler/ruby_generator_string-inl.h
+  - src/compiler/schema_interface.h
   src:
   - src/compiler/cpp_generator.cc
   - src/compiler/csharp_generator.cc
@@ -1362,6 +1469,7 @@ libs:
   build: private
   language: c++
   headers:
+  - test/cpp/qps/benchmark_config.h
   - test/cpp/qps/client.h
   - test/cpp/qps/driver.h
   - test/cpp/qps/histogram.h
@@ -1372,13 +1480,13 @@ libs:
   - test/cpp/qps/server.h
   - test/cpp/qps/stats.h
   - test/cpp/qps/usage_timer.h
-  - test/cpp/util/benchmark_config.h
   src:
   - src/proto/grpc/testing/messages.proto
   - src/proto/grpc/testing/payloads.proto
   - src/proto/grpc/testing/stats.proto
   - src/proto/grpc/testing/control.proto
   - src/proto/grpc/testing/services.proto
+  - test/cpp/qps/benchmark_config.cc
   - test/cpp/qps/client_async.cc
   - test/cpp/qps/client_sync.cc
   - test/cpp/qps/driver.cc
@@ -1388,7 +1496,6 @@ libs:
   - test/cpp/qps/server_async.cc
   - test/cpp/qps/server_sync.cc
   - test/cpp/qps/usage_timer.cc
-  - test/cpp/util/benchmark_config.cc
   deps:
   - grpc_test_util
   - grpc++_test_util
@@ -1416,6 +1523,7 @@ libs:
   - global
 targets:
 - name: alarm_test
+  cpu_cost: 0.1
   build: test
   language: c
   src:
@@ -1467,6 +1575,14 @@ targets:
   - test/core/end2end/fuzzers/api_fuzzer_corpus
   dict: test/core/end2end/fuzzers/api_fuzzer.dictionary
   maxlen: 2048
+- name: arena_test
+  build: test
+  language: c
+  src:
+  - test/core/support/arena_test.c
+  deps:
+  - gpr_test_util
+  - gpr
 - name: bad_server_response_test
   build: test
   language: c
@@ -1591,7 +1707,7 @@ targets:
   dict: test/core/end2end/fuzzers/hpack.dictionary
   maxlen: 2048
 - name: combiner_test
-  cpu_cost: 30
+  cpu_cost: 10
   build: test
   language: c
   src:
@@ -1612,6 +1728,7 @@ targets:
   - gpr_test_util
   - gpr
 - name: concurrent_connectivity_test
+  cpu_cost: 2.0
   build: test
   language: c
   src:
@@ -1686,7 +1803,19 @@ targets:
   - gpr
   exclude_iomgrs:
   - uv
+- name: error_test
+  cpu_cost: 30
+  build: test
+  language: c
+  src:
+  - test/core/iomgr/error_test.c
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr_test_util
+  - gpr
 - name: ev_epoll_linux_test
+  cpu_cost: 3
   build: test
   language: c
   src:
@@ -1700,6 +1829,16 @@ targets:
   - uv
   platforms:
   - linux
+- name: fake_resolver_test
+  build: test
+  language: c
+  src:
+  - test/core/client_channel/resolvers/fake_resolver_test.c
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr_test_util
+  - gpr
 - name: fd_conservation_posix_test
   build: test
   language: c
@@ -1846,6 +1985,7 @@ targets:
   - gpr_test_util
   - gpr
 - name: gpr_cpu_test
+  cpu_cost: 30
   build: test
   language: c
   src:
@@ -1895,7 +2035,7 @@ targets:
   - gpr_test_util
   - gpr
 - name: gpr_spinlock_test
-  cpu_cost: 10
+  cpu_cost: 3
   build: test
   language: c
   src:
@@ -1976,7 +2116,7 @@ targets:
   build: test
   language: c
   src:
-  - test/core/security/b64_test.c
+  - test/core/slice/b64_test.c
   deps:
   - grpc_test_util
   - grpc
@@ -2426,6 +2566,16 @@ targets:
   - grpc
   - gpr_test_util
   - gpr
+- name: minimal_stack_is_minimal_test
+  build: test
+  language: c
+  src:
+  - test/core/channel/minimal_stack_is_minimal_test.c
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr_test_util
+  - gpr
 - name: mlog_test
   flaky: true
   build: test
@@ -2492,6 +2642,16 @@ targets:
   - grpc
   - gpr_test_util
   - gpr
+- name: parse_address_test
+  build: test
+  language: c
+  src:
+  - test/core/client_channel/parse_address_test.c
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr_test_util
+  - gpr
 - name: percent_decode_fuzzer
   build: fuzzer
   language: c
@@ -2552,6 +2712,8 @@ targets:
   - grpc
   - gpr_test_util
   - gpr
+  exclude_iomgrs:
+  - uv
   platforms:
   - mac
   - linux
@@ -2645,25 +2807,21 @@ targets:
   - grpc
   - gpr_test_util
   - gpr
-- name: set_initial_connect_string_test
-  cpu_cost: 0.1
+- name: slice_buffer_test
   build: test
   language: c
   src:
-  - test/core/client_channel/set_initial_connect_string_test.c
+  - test/core/slice/slice_buffer_test.c
   deps:
-  - test_tcp_server
   - grpc_test_util
   - grpc
   - gpr_test_util
   - gpr
-  exclude_iomgrs:
-  - uv
-- name: slice_buffer_test
+- name: slice_hash_table_test
   build: test
   language: c
   src:
-  - test/core/slice/slice_buffer_test.c
+  - test/core/slice/slice_hash_table_test.c
   deps:
   - grpc_test_util
   - grpc
@@ -2748,6 +2906,16 @@ targets:
   - grpc
   - gpr_test_util
   - gpr
+- name: stream_owned_slice_test
+  build: test
+  language: c
+  src:
+  - test/core/transport/stream_owned_slice_test.c
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr_test_util
+  - gpr
 - name: tcp_client_posix_test
   cpu_cost: 0.5
   build: test
@@ -3005,12 +3173,34 @@ targets:
   - grpc
   - gpr_test_util
   - gpr
+- name: bm_arena
+  build: test
+  language: c++
+  src:
+  - test/cpp/microbenchmarks/bm_arena.cc
+  deps:
+  - grpc_benchmark
+  - benchmark
+  - grpc++_test_util
+  - grpc_test_util
+  - grpc++
+  - grpc
+  - gpr_test_util
+  - gpr
+  args:
+  - --benchmark_min_time=0
+  defaults: benchmark
+  platforms:
+  - mac
+  - linux
+  - posix
 - name: bm_call_create
   build: test
   language: c++
   src:
   - test/cpp/microbenchmarks/bm_call_create.cc
   deps:
+  - grpc_benchmark
   - benchmark
   - grpc++_test_util
   - grpc_test_util
@@ -3020,6 +3210,7 @@ targets:
   - gpr
   args:
   - --benchmark_min_time=0
+  defaults: benchmark
   platforms:
   - mac
   - linux
@@ -3030,6 +3221,7 @@ targets:
   src:
   - test/cpp/microbenchmarks/bm_chttp2_hpack.cc
   deps:
+  - grpc_benchmark
   - benchmark
   - grpc++_test_util
   - grpc_test_util
@@ -3039,6 +3231,28 @@ targets:
   - gpr
   args:
   - --benchmark_min_time=0
+  defaults: benchmark
+  platforms:
+  - mac
+  - linux
+  - posix
+- name: bm_chttp2_transport
+  build: test
+  language: c++
+  src:
+  - test/cpp/microbenchmarks/bm_chttp2_transport.cc
+  deps:
+  - grpc_benchmark
+  - benchmark
+  - grpc++_test_util
+  - grpc_test_util
+  - grpc++
+  - grpc
+  - gpr_test_util
+  - gpr
+  args:
+  - --benchmark_min_time=0
+  defaults: benchmark
   platforms:
   - mac
   - linux
@@ -3049,6 +3263,7 @@ targets:
   src:
   - test/cpp/microbenchmarks/bm_closure.cc
   deps:
+  - grpc_benchmark
   - benchmark
   - grpc++_test_util
   - grpc_test_util
@@ -3058,6 +3273,7 @@ targets:
   - gpr
   args:
   - --benchmark_min_time=0
+  defaults: benchmark
   platforms:
   - mac
   - linux
@@ -3068,6 +3284,7 @@ targets:
   src:
   - test/cpp/microbenchmarks/bm_cq.cc
   deps:
+  - grpc_benchmark
   - benchmark
   - grpc++_test_util
   - grpc_test_util
@@ -3077,6 +3294,28 @@ targets:
   - gpr
   args:
   - --benchmark_min_time=0
+  defaults: benchmark
+  platforms:
+  - mac
+  - linux
+  - posix
+- name: bm_cq_multiple_threads
+  build: test
+  language: c++
+  src:
+  - test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
+  deps:
+  - grpc_benchmark
+  - benchmark
+  - grpc++_test_util
+  - grpc_test_util
+  - grpc++
+  - grpc
+  - gpr_test_util
+  - gpr
+  args:
+  - --benchmark_min_time=0
+  defaults: benchmark
   platforms:
   - mac
   - linux
@@ -3087,6 +3326,53 @@ targets:
   src:
   - test/cpp/microbenchmarks/bm_error.cc
   deps:
+  - grpc_benchmark
+  - benchmark
+  - grpc++_test_util
+  - grpc_test_util
+  - grpc++
+  - grpc
+  - gpr_test_util
+  - gpr
+  args:
+  - --benchmark_min_time=0
+  defaults: benchmark
+  platforms:
+  - mac
+  - linux
+  - posix
+- name: bm_fullstack_streaming_ping_pong
+  build: test
+  language: c++
+  src:
+  - test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc
+  deps:
+  - grpc_benchmark
+  - benchmark
+  - grpc++_test_util
+  - grpc_test_util
+  - grpc++
+  - grpc
+  - gpr_test_util
+  - gpr
+  args:
+  - --benchmark_min_time=0
+  defaults: benchmark
+  excluded_poll_engines:
+  - poll
+  - poll-cv
+  platforms:
+  - mac
+  - linux
+  - posix
+  timeout_seconds: 1200
+- name: bm_fullstack_streaming_pump
+  build: test
+  language: c++
+  src:
+  - test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc
+  deps:
+  - grpc_benchmark
   - benchmark
   - grpc++_test_util
   - grpc_test_util
@@ -3096,16 +3382,47 @@ targets:
   - gpr
   args:
   - --benchmark_min_time=0
+  defaults: benchmark
+  excluded_poll_engines:
+  - poll
+  - poll-cv
   platforms:
   - mac
   - linux
   - posix
-- name: bm_fullstack
+  timeout_seconds: 1200
+- name: bm_fullstack_trickle
+  build: test
+  language: c++
+  src:
+  - test/cpp/microbenchmarks/bm_fullstack_trickle.cc
+  deps:
+  - grpc_benchmark
+  - benchmark
+  - grpc++_test_util
+  - grpc_test_util
+  - grpc++
+  - grpc
+  - gpr_test_util
+  - gpr
+  args:
+  - --benchmark_min_time=0
+  defaults: benchmark
+  excluded_poll_engines:
+  - poll
+  - poll-cv
+  platforms:
+  - mac
+  - linux
+  - posix
+  timeout_seconds: 1200
+- name: bm_fullstack_unary_ping_pong
   build: test
   language: c++
   src:
-  - test/cpp/microbenchmarks/bm_fullstack.cc
+  - test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc
   deps:
+  - grpc_benchmark
   - benchmark
   - grpc++_test_util
   - grpc_test_util
@@ -3115,6 +3432,7 @@ targets:
   - gpr
   args:
   - --benchmark_min_time=0
+  defaults: benchmark
   excluded_poll_engines:
   - poll
   - poll-cv
@@ -3129,13 +3447,38 @@ targets:
   src:
   - test/cpp/microbenchmarks/bm_metadata.cc
   deps:
+  - grpc_benchmark
   - benchmark
+  - grpc++_test_util
   - grpc_test_util
+  - grpc++
+  - grpc
+  - gpr_test_util
+  - gpr
+  args:
+  - --benchmark_min_time=0
+  defaults: benchmark
+  platforms:
+  - mac
+  - linux
+  - posix
+- name: bm_pollset
+  build: test
+  language: c++
+  src:
+  - test/cpp/microbenchmarks/bm_pollset.cc
+  deps:
+  - grpc_benchmark
+  - benchmark
+  - grpc++_test_util
+  - grpc_test_util
+  - grpc++
   - grpc
   - gpr_test_util
   - gpr
   args:
   - --benchmark_min_time=0
+  defaults: benchmark
   platforms:
   - mac
   - linux
@@ -3233,6 +3576,9 @@ targets:
   - src/proto/grpc/testing/services.proto
   - src/proto/grpc/testing/stats.proto
   - test/cpp/codegen/codegen_test_minimal.cc
+  deps:
+  - grpc
+  - gpr
   filegroups:
   - grpc++_codegen_base
   - grpc++_codegen_base_src
@@ -3304,6 +3650,16 @@ targets:
   - grpc
   - gpr_test_util
   - gpr
+- name: error_details_test
+  gtest: true
+  build: test
+  language: c++
+  src:
+  - src/proto/grpc/testing/echo_messages.proto
+  - test/cpp/util/error_details_test.cc
+  deps:
+  - grpc++_error_details
+  - grpc++
 - name: filter_end2end_test
   gtest: true
   build: test
@@ -3342,7 +3698,7 @@ targets:
   - grpc
   - gpr
   args:
-  - --generated_file_path=gens/src/proto/grpc/testing/compiler_test.grpc.pb.h
+  - --generated_file_path=gens/src/proto/grpc/testing/
 - name: grpc_cli
   build: test
   run: false
@@ -3456,6 +3812,20 @@ targets:
   - grpc_test_util
   - grpc++
   - grpc
+- name: grpclb_end2end_test
+  gtest: true
+  build: test
+  language: c++
+  src:
+  - src/proto/grpc/lb/v1/load_balancer.proto
+  - test/cpp/end2end/grpclb_end2end_test.cc
+  deps:
+  - grpc++_test_util
+  - grpc_test_util
+  - grpc++
+  - grpc
+  - gpr_test_util
+  - gpr
 - name: grpclb_test
   gtest: false
   build: test
@@ -3585,6 +3955,20 @@ targets:
   - mac
   - linux
   - posix
+- name: memory_test
+  gtest: true
+  build: test
+  language: c++
+  src:
+  - test/core/support/memory_test.cc
+  deps:
+  - grpc_test_util
+  - grpc++
+  - grpc
+  - gpr_test_util
+  - gpr
+  uses:
+  - grpc++_test
 - name: metrics_client
   build: test
   run: false
@@ -3603,6 +3987,8 @@ targets:
   gtest: true
   build: test
   language: c++
+  headers:
+  - include/grpc++/test/mock_stream.h
   src:
   - test/cpp/end2end/mock_test.cc
   deps:
@@ -3619,6 +4005,7 @@ targets:
   - test/cpp/microbenchmarks/noop-benchmark.cc
   deps:
   - benchmark
+  defaults: benchmark
 - name: proto_server_reflection_test
   gtest: true
   build: test
@@ -3808,6 +4195,21 @@ targets:
   - grpc
   - gpr_test_util
   - gpr
+- name: server_builder_test
+  gtest: true
+  build: test
+  language: c++
+  src:
+  - src/proto/grpc/testing/echo_messages.proto
+  - src/proto/grpc/testing/echo.proto
+  - test/cpp/server/server_builder_test.cc
+  deps:
+  - grpc++_test_util
+  - grpc_test_util
+  - gpr_test_util
+  - grpc++
+  - grpc
+  - gpr
 - name: server_context_test_spouse_test
   gtest: true
   build: test
@@ -3912,7 +4314,6 @@ targets:
   - test/cpp/interop/interop_client.cc
   - test/cpp/interop/stress_interop_client.cc
   - test/cpp/interop/stress_test.cc
-  - test/cpp/util/create_test_channel.cc
   - test/cpp/util/metrics_server.cc
   deps:
   - grpc++_test_util
@@ -3997,7 +4398,7 @@ configs:
     CPPFLAGS: -O0 -fsanitize-coverage=edge -fsanitize=address -fno-omit-frame-pointer
       -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
     CXX: clang++
-    LD: clang
+    LD: clang++
     LDFLAGS: -fsanitize=address
     LDXX: clang++
     compile_the_world: true
@@ -4009,7 +4410,7 @@ configs:
     CPPFLAGS: -O0 -fsanitize-coverage=edge -fsanitize=address -fno-omit-frame-pointer
       -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
     CXX: clang++
-    LD: clang
+    LD: clang++
     LDFLAGS: -fsanitize=address
     LDXX: clang++
     compile_the_world: true
@@ -4020,7 +4421,7 @@ configs:
     CPPFLAGS: -O0 -fsanitize-coverage=edge -fsanitize-coverage=trace-cmp -fsanitize=address
       -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
     CXX: clang++
-    LD: clang
+    LD: clang++
     LDFLAGS: -fsanitize=address
     LDXX: clang++
     compile_the_world: true
@@ -4030,11 +4431,16 @@ configs:
   basicprof:
     CPPFLAGS: -O2 -DGRPC_BASIC_PROFILER -DGRPC_TIMERS_RDTSC
     DEFINES: NDEBUG
+  c++-compat:
+    CFLAGS: -Wc++-compat
+    CPPFLAGS: -O0
+    DEFINES: _DEBUG DEBUG
   counters:
     CPPFLAGS: -O2 -DGPR_LOW_LEVEL_COUNTERS
     DEFINES: NDEBUG
   dbg:
     CPPFLAGS: -O0
+    CXXFLAGS: -fno-exceptions
     DEFINES: _DEBUG DEBUG
   gcov:
     CC: gcc
@@ -4049,6 +4455,9 @@ configs:
     DEFINES: _DEBUG DEBUG
     LDFLAGS: -rdynamic
     valgrind: --tool=helgrind
+  lto:
+    CPPFLAGS: -O2
+    DEFINES: NDEBUG
   memcheck:
     CPPFLAGS: -O0
     DEFINES: _DEBUG DEBUG
@@ -4061,7 +4470,7 @@ configs:
       -Wno-unused-command-line-argument -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS
     CXX: clang++
     DEFINES: NDEBUG
-    LD: clang
+    LD: clang++
     LDFLAGS: -fsanitize=memory -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1
       -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
     LDXX: clang++
@@ -4072,6 +4481,7 @@ configs:
     LDFLAGS: -rdynamic
   opt:
     CPPFLAGS: -O2
+    CXXFLAGS: -fno-exceptions
     DEFINES: NDEBUG
   stapprof:
     CPPFLAGS: -O2 -DGRPC_STAP_PROFILER
@@ -4082,7 +4492,7 @@ configs:
       -DGPR_NO_DIRECT_SYSCALLS
     CXX: clang++
     DEFINES: GRPC_TSAN
-    LD: clang
+    LD: clang++
     LDFLAGS: -fsanitize=thread
     LDXX: clang++
     compile_the_world: true
@@ -4090,17 +4500,23 @@ configs:
       TSAN_OPTIONS: suppressions=tools/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1
   ubsan:
     CC: clang
-    CPPFLAGS: -O0 -fsanitize-coverage=edge -fsanitize=undefined,unsigned-integer-overflow
-      -fno-omit-frame-pointer -Wno-unused-command-line-argument -Wvarargs
+    CPPFLAGS: -O0 -fsanitize-coverage=edge -fsanitize=undefined -fno-omit-frame-pointer
+      -Wno-unused-command-line-argument -Wvarargs
     CXX: clang++
-    DEFINES: NDEBUG
-    LD: clang
+    DEFINES: NDEBUG GRPC_UBSAN
+    LD: clang++
     LDFLAGS: -fsanitize=undefined,unsigned-integer-overflow
     LDXX: clang++
     compile_the_world: true
     test_environ:
-      UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1
+      UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1:suppressions=tools/ubsan_suppressions.txt
 defaults:
+  ares:
+    CFLAGS: -Wno-sign-conversion $(if $(subst MINGW32,,$(SYSTEM)),-Wno-invalid-source-encoding,)
+    CPPFLAGS: -Ithird_party/cares -Ithird_party/cares/cares $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux)
+      $(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) -fvisibility=hidden
+      -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(if $(subst
+      MINGW32,,$(SYSTEM)),-DHAVE_CONFIG_H,)
   benchmark:
     CPPFLAGS: -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
   boringssl:
@@ -4146,13 +4562,10 @@ node_modules:
   - src/node/ext/call_credentials.cc
   - src/node/ext/channel.cc
   - src/node/ext/channel_credentials.cc
-  - src/node/ext/completion_queue_threadpool.cc
-  - src/node/ext/completion_queue_uv.cc
+  - src/node/ext/completion_queue.cc
   - src/node/ext/node_grpc.cc
   - src/node/ext/server.cc
   - src/node/ext/server_credentials.cc
-  - src/node/ext/server_generic.cc
-  - src/node/ext/server_uv.cc
   - src/node/ext/slice.cc
   - src/node/ext/timeval.cc
 openssl_fallback:
@@ -4163,6 +4576,7 @@ php_config_m4:
   deps:
   - grpc
   - gpr
+  - ares
   - boringssl
   headers:
   - src/php/ext/grpc/byte_buffer.h
@@ -4191,11 +4605,13 @@ python_dependencies:
   deps:
   - grpc
   - gpr
+  - ares
   - boringssl
   - z
 ruby_gem:
   deps:
   - grpc
   - gpr
+  - ares
   - boringssl
   - z
diff --git a/build_config.rb b/build_config.rb
index b5a8c2020ba698ec91f47b57adcb3da14ba6db41..9a69070dc719d577be2bd66a15846b48e85d6ea6 100644
--- a/build_config.rb
+++ b/build_config.rb
@@ -28,5 +28,5 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 module GrpcBuildConfig
-  CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-3.dll'
+  CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-4.dll'
 end
diff --git a/cmake/msvc_static_runtime.cmake b/cmake/msvc_static_runtime.cmake
index 5a31ab3d2429e7c257dd892bc63beb546a08e491..fc6d1d62d32925e3f59bd30fe14c4e513116cae6 100644
--- a/cmake/msvc_static_runtime.cmake
+++ b/cmake/msvc_static_runtime.cmake
@@ -3,6 +3,8 @@ option(gRPC_MSVC_STATIC_RUNTIME "Link with static msvc runtime libraries" OFF)
 if(gRPC_MSVC_STATIC_RUNTIME)
   # switch from dynamic to static linking of msvcrt
   foreach(flag_var
+    CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
+    CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
     CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
     CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
 
diff --git a/config.m4 b/config.m4
index 90536e503edacc09fa2d5b2f3e30870916d39406..1c0c6d92fc404a07c2eb178bb8032dc5d5540e6b 100644
--- a/config.m4
+++ b/config.m4
@@ -8,6 +8,8 @@ if test "$PHP_GRPC" != "no"; then
   PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/include)
   PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/src/php/ext/grpc)
   PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/boringssl/include)
+  PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/cares)
+  PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/cares/cares)
 
   LIBS="-lpthread $LIBS"
 
@@ -18,8 +20,11 @@ if test "$PHP_GRPC" != "no"; then
   PHP_ADD_LIBRARY(dl)
 
   case $host in
-    *darwin*) ;;
+    *darwin*)
+      PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/cares/config_darwin)
+      ;;
     *)
+      PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/cares/config_linux)
       PHP_ADD_LIBRARY(rt,,GRPC_SHARED_LIBADD)
       PHP_ADD_LIBRARY(rt)
       ;;
@@ -39,6 +44,8 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/profiling/basic_timers.c \
     src/core/lib/profiling/stap_timers.c \
     src/core/lib/support/alloc.c \
+    src/core/lib/support/arena.c \
+    src/core/lib/support/atm.c \
     src/core/lib/support/avl.c \
     src/core/lib/support/backoff.c \
     src/core/lib/support/cmdline.c \
@@ -84,15 +91,10 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/channel/channel_args.c \
     src/core/lib/channel/channel_stack.c \
     src/core/lib/channel/channel_stack_builder.c \
-    src/core/lib/channel/compress_filter.c \
     src/core/lib/channel/connected_channel.c \
-    src/core/lib/channel/deadline_filter.c \
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/handshaker_factory.c \
     src/core/lib/channel/handshaker_registry.c \
-    src/core/lib/channel/http_client_filter.c \
-    src/core/lib/channel/http_server_filter.c \
-    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
@@ -117,6 +119,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/iomgr/iomgr_uv.c \
     src/core/lib/iomgr/iomgr_windows.c \
     src/core/lib/iomgr/load_file.c \
+    src/core/lib/iomgr/lockfree_event.c \
     src/core/lib/iomgr/network_status_tracker.c \
     src/core/lib/iomgr/polling_entity.c \
     src/core/lib/iomgr/pollset_set_uv.c \
@@ -128,6 +131,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/iomgr/resolve_address_windows.c \
     src/core/lib/iomgr/resource_quota.c \
     src/core/lib/iomgr/sockaddr_utils.c \
+    src/core/lib/iomgr/socket_factory_posix.c \
     src/core/lib/iomgr/socket_mutator.c \
     src/core/lib/iomgr/socket_utils_common_posix.c \
     src/core/lib/iomgr/socket_utils_linux.c \
@@ -140,6 +144,9 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/iomgr/tcp_client_windows.c \
     src/core/lib/iomgr/tcp_posix.c \
     src/core/lib/iomgr/tcp_server_posix.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_common.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c \
+    src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c \
     src/core/lib/iomgr/tcp_server_uv.c \
     src/core/lib/iomgr/tcp_server_windows.c \
     src/core/lib/iomgr/tcp_uv.c \
@@ -162,6 +169,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/json/json_reader.c \
     src/core/lib/json/json_string.c \
     src/core/lib/json/json_writer.c \
+    src/core/lib/slice/b64.c \
     src/core/lib/slice/percent_encoding.c \
     src/core/lib/slice/slice.c \
     src/core/lib/slice/slice_buffer.c \
@@ -180,8 +188,9 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/surface/channel_ping.c \
     src/core/lib/surface/channel_stack_type.c \
     src/core/lib/surface/completion_queue.c \
+    src/core/lib/surface/completion_queue_factory.c \
     src/core/lib/surface/event_string.c \
-    src/core/lib/surface/lame_client.c \
+    src/core/lib/surface/lame_client.cc \
     src/core/lib/surface/metadata_array.c \
     src/core/lib/surface/server.c \
     src/core/lib/surface/validate_metadata.c \
@@ -213,6 +222,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/transport/chttp2/transport/hpack_encoder.c \
     src/core/ext/transport/chttp2/transport/hpack_parser.c \
     src/core/ext/transport/chttp2/transport/hpack_table.c \
+    src/core/ext/transport/chttp2/transport/http2_settings.c \
     src/core/ext/transport/chttp2/transport/huffsyms.c \
     src/core/ext/transport/chttp2/transport/incoming_metadata.c \
     src/core/ext/transport/chttp2/transport/parsing.c \
@@ -221,6 +231,10 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/transport/chttp2/transport/varint.c \
     src/core/ext/transport/chttp2/transport/writing.c \
     src/core/ext/transport/chttp2/alpn/alpn.c \
+    src/core/ext/filters/http/client/http_client_filter.c \
+    src/core/ext/filters/http/http_filters_plugin.c \
+    src/core/ext/filters/http/message_compress/message_compress_filter.c \
+    src/core/ext/filters/http/server/http_server_filter.c \
     src/core/lib/http/httpcli_security_connector.c \
     src/core/lib/security/context/security_context.c \
     src/core/lib/security/credentials/composite/composite_credentials.c \
@@ -243,53 +257,58 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/security/transport/security_handshaker.c \
     src/core/lib/security/transport/server_auth_filter.c \
     src/core/lib/security/transport/tsi_error.c \
-    src/core/lib/security/util/b64.c \
     src/core/lib/security/util/json_util.c \
     src/core/lib/surface/init_secure.c \
-    src/core/lib/tsi/fake_transport_security.c \
-    src/core/lib/tsi/ssl_transport_security.c \
-    src/core/lib/tsi/transport_security.c \
+    src/core/tsi/fake_transport_security.c \
+    src/core/tsi/ssl_transport_security.c \
+    src/core/tsi/transport_security.c \
+    src/core/tsi/transport_security_adapter.c \
     src/core/ext/transport/chttp2/server/chttp2_server.c \
     src/core/ext/transport/chttp2/client/secure/secure_channel_create.c \
-    src/core/ext/client_channel/channel_connectivity.c \
-    src/core/ext/client_channel/client_channel.c \
-    src/core/ext/client_channel/client_channel_factory.c \
-    src/core/ext/client_channel/client_channel_plugin.c \
-    src/core/ext/client_channel/connector.c \
-    src/core/ext/client_channel/default_initial_connect_string.c \
-    src/core/ext/client_channel/http_connect_handshaker.c \
-    src/core/ext/client_channel/http_proxy.c \
-    src/core/ext/client_channel/initial_connect_string.c \
-    src/core/ext/client_channel/lb_policy.c \
-    src/core/ext/client_channel/lb_policy_factory.c \
-    src/core/ext/client_channel/lb_policy_registry.c \
-    src/core/ext/client_channel/parse_address.c \
-    src/core/ext/client_channel/proxy_mapper.c \
-    src/core/ext/client_channel/proxy_mapper_registry.c \
-    src/core/ext/client_channel/resolver.c \
-    src/core/ext/client_channel/resolver_factory.c \
-    src/core/ext/client_channel/resolver_registry.c \
-    src/core/ext/client_channel/subchannel.c \
-    src/core/ext/client_channel/subchannel_index.c \
-    src/core/ext/client_channel/uri_parser.c \
+    src/core/ext/filters/client_channel/channel_connectivity.c \
+    src/core/ext/filters/client_channel/client_channel.c \
+    src/core/ext/filters/client_channel/client_channel_factory.c \
+    src/core/ext/filters/client_channel/client_channel_plugin.c \
+    src/core/ext/filters/client_channel/connector.c \
+    src/core/ext/filters/client_channel/http_connect_handshaker.c \
+    src/core/ext/filters/client_channel/http_proxy.c \
+    src/core/ext/filters/client_channel/lb_policy.c \
+    src/core/ext/filters/client_channel/lb_policy_factory.c \
+    src/core/ext/filters/client_channel/lb_policy_registry.c \
+    src/core/ext/filters/client_channel/parse_address.c \
+    src/core/ext/filters/client_channel/proxy_mapper.c \
+    src/core/ext/filters/client_channel/proxy_mapper_registry.c \
+    src/core/ext/filters/client_channel/resolver.c \
+    src/core/ext/filters/client_channel/resolver_factory.c \
+    src/core/ext/filters/client_channel/resolver_registry.c \
+    src/core/ext/filters/client_channel/retry_throttle.c \
+    src/core/ext/filters/client_channel/subchannel.c \
+    src/core/ext/filters/client_channel/subchannel_index.c \
+    src/core/ext/filters/client_channel/uri_parser.c \
+    src/core/ext/filters/deadline/deadline_filter.c \
     src/core/ext/transport/chttp2/client/chttp2_connector.c \
     src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
     src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \
     src/core/ext/transport/chttp2/client/insecure/channel_create.c \
     src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
-    src/core/ext/lb_policy/grpclb/grpclb.c \
-    src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c \
-    src/core/ext/lb_policy/grpclb/load_balancer_api.c \
-    src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
     third_party/nanopb/pb_common.c \
     third_party/nanopb/pb_decode.c \
     third_party/nanopb/pb_encode.c \
-    src/core/ext/lb_policy/pick_first/pick_first.c \
-    src/core/ext/lb_policy/round_robin/round_robin.c \
-    src/core/ext/resolver/dns/native/dns_resolver.c \
-    src/core/ext/resolver/sockaddr/sockaddr_resolver.c \
-    src/core/ext/load_reporting/load_reporting.c \
-    src/core/ext/load_reporting/load_reporting_filter.c \
+    src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c \
+    src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c \
+    src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c \
+    src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c \
+    src/core/ext/filters/load_reporting/load_reporting.c \
+    src/core/ext/filters/load_reporting/load_reporting_filter.c \
     src/core/ext/census/base_resources.c \
     src/core/ext/census/context.c \
     src/core/ext/census/gen/census.pb.c \
@@ -304,6 +323,8 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/census/resource.c \
     src/core/ext/census/trace_context.c \
     src/core/ext/census/tracing.c \
+    src/core/ext/filters/max_age/max_age_filter.c \
+    src/core/ext/filters/message_size/message_size_filter.c \
     src/core/plugin_registry/grpc_plugin_registry.c \
     src/boringssl/err_data.c \
     third_party/boringssl/crypto/aes/aes.c \
@@ -609,6 +630,55 @@ if test "$PHP_GRPC" != "no"; then
     third_party/boringssl/ssl/tls13_server.c \
     third_party/boringssl/ssl/tls_method.c \
     third_party/boringssl/ssl/tls_record.c \
+    third_party/cares/cares/ares__close_sockets.c \
+    third_party/cares/cares/ares__get_hostent.c \
+    third_party/cares/cares/ares__read_line.c \
+    third_party/cares/cares/ares__timeval.c \
+    third_party/cares/cares/ares_cancel.c \
+    third_party/cares/cares/ares_create_query.c \
+    third_party/cares/cares/ares_data.c \
+    third_party/cares/cares/ares_destroy.c \
+    third_party/cares/cares/ares_expand_name.c \
+    third_party/cares/cares/ares_expand_string.c \
+    third_party/cares/cares/ares_fds.c \
+    third_party/cares/cares/ares_free_hostent.c \
+    third_party/cares/cares/ares_free_string.c \
+    third_party/cares/cares/ares_getenv.c \
+    third_party/cares/cares/ares_gethostbyaddr.c \
+    third_party/cares/cares/ares_gethostbyname.c \
+    third_party/cares/cares/ares_getnameinfo.c \
+    third_party/cares/cares/ares_getopt.c \
+    third_party/cares/cares/ares_getsock.c \
+    third_party/cares/cares/ares_init.c \
+    third_party/cares/cares/ares_library_init.c \
+    third_party/cares/cares/ares_llist.c \
+    third_party/cares/cares/ares_mkquery.c \
+    third_party/cares/cares/ares_nowarn.c \
+    third_party/cares/cares/ares_options.c \
+    third_party/cares/cares/ares_parse_a_reply.c \
+    third_party/cares/cares/ares_parse_aaaa_reply.c \
+    third_party/cares/cares/ares_parse_mx_reply.c \
+    third_party/cares/cares/ares_parse_naptr_reply.c \
+    third_party/cares/cares/ares_parse_ns_reply.c \
+    third_party/cares/cares/ares_parse_ptr_reply.c \
+    third_party/cares/cares/ares_parse_soa_reply.c \
+    third_party/cares/cares/ares_parse_srv_reply.c \
+    third_party/cares/cares/ares_parse_txt_reply.c \
+    third_party/cares/cares/ares_platform.c \
+    third_party/cares/cares/ares_process.c \
+    third_party/cares/cares/ares_query.c \
+    third_party/cares/cares/ares_search.c \
+    third_party/cares/cares/ares_send.c \
+    third_party/cares/cares/ares_strcasecmp.c \
+    third_party/cares/cares/ares_strdup.c \
+    third_party/cares/cares/ares_strerror.c \
+    third_party/cares/cares/ares_timeout.c \
+    third_party/cares/cares/ares_version.c \
+    third_party/cares/cares/ares_writev.c \
+    third_party/cares/cares/bitncmp.c \
+    third_party/cares/cares/inet_net_pton.c \
+    third_party/cares/cares/inet_ntop.c \
+    third_party/cares/cares/windows_port.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 \
@@ -619,14 +689,22 @@ if test "$PHP_GRPC" != "no"; then
   PHP_ADD_BUILD_DIR($ext_builddir/src/boringssl)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/census)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/census/gen)
-  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/client_channel)
-  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/lb_policy/grpclb)
-  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1)
-  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/lb_policy/pick_first)
-  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/lb_policy/round_robin)
-  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/load_reporting)
-  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/resolver/dns/native)
-  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/resolver/sockaddr)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/pick_first)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/round_robin)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/c_ares)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/native)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/sockaddr)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/deadline)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/http)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/http/client)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/http/message_compress)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/http/server)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/load_reporting)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/max_age)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/message_size)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/alpn)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/client)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/client/insecure)
@@ -658,8 +736,8 @@ if test "$PHP_GRPC" != "no"; then
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/support)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/surface)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/transport)
-  PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/tsi)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/plugin_registry)
+  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)
@@ -703,5 +781,6 @@ if test "$PHP_GRPC" != "no"; then
   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/cares/cares)
   PHP_ADD_BUILD_DIR($ext_builddir/third_party/nanopb)
 fi
diff --git a/doc/PROTOCOL-HTTP2.md b/doc/PROTOCOL-HTTP2.md
index 2df1c74beef7b5d8f7e8796424d7abe391c20f3f..68af1f2ca19ef73da33ae041fa7335302fa49176 100644
--- a/doc/PROTOCOL-HTTP2.md
+++ b/doc/PROTOCOL-HTTP2.md
@@ -91,7 +91,7 @@ A **Compressed-Flag** value of 1 indicates that the binary octet sequence of **M
 
 For requests, **EOS** (end-of-stream) is indicated by the presence of the END_STREAM flag on the last received DATA frame. In scenarios where the **Request** stream needs to be closed but no data remains to be sent implementations MUST send an empty DATA frame with this flag set.
 
-###Responses
+### Responses
 
 * **Response** → (Response-Headers \*Length-Prefixed-Message Trailers) / Trailers-Only
 * **Response-Headers** → HTTP-Status [Message-Encoding] [Message-Accept-Encoding] Content-Type \*Custom-Metadata
@@ -128,7 +128,7 @@ implementation can decode valid portions while leaving broken %-encodings as-is
 or replacing them with a replacement character (e.g., '?' or the Unicode
 replacement character).
 
-####Example
+#### Example
 
 Sample unary-call showing HTTP2 framing sequence
 
@@ -162,7 +162,7 @@ HEADERS (flags = END_STREAM, END_HEADERS)
 grpc-status = 0 # OK
 trace-proto-bin = jher831yy13JHy3hc
 ```
-####User Agents
+#### User Agents
 
 While the protocol does not require a user-agent to function it is recommended that clients provide a structured user-agent string that provides a basic description of the calling library, version & platform to facilitate issue diagnosis in heterogeneous environments. The following structure is recommended to library developers
 ```
@@ -177,7 +177,7 @@ grpc-ruby-jruby/1.3.4
 grpc-java-android/0.9.1 (gingerbread/1.2.4; nexus5; tmobile)
 ```
 
-####Idempotency and Retries
+#### Idempotency and Retries
 
 Unless explicitly defined to be, gRPC Calls are not assumed to be idempotent.  Specifically:
 
@@ -186,15 +186,15 @@ Unless explicitly defined to be, gRPC Calls are not assumed to be idempotent.  S
 * Calls that are marked as idempotent may be sent multiple times.
 
 
-####HTTP2 Transport Mapping
+#### HTTP2 Transport Mapping
 
-#####Stream Identification
+##### Stream Identification
 All GRPC calls need to specify an internal ID. We will use HTTP2 stream-ids as call identifiers in this scheme. NOTE: These id’s are contextual to an open HTTP2 session and will not be unique within a given process that is handling more than one HTTP2 session nor can they be used as GUIDs.
 
-#####Data Frames
+##### Data Frames
 DATA frame boundaries have no relation to **Length-Prefixed-Message** boundaries and implementations should make no assumptions about their alignment.
 
-#####Errors
+##### Errors
 
 When an application or runtime error occurs during an RPC a **Status** and **Status-Message** are delivered in **Trailers**.
 
@@ -219,20 +219,20 @@ ENHANCE_YOUR_CALM|RESOURCE_EXHAUSTED ...with additional error detail provided by
 INADEQUATE_SECURITY| PERMISSION_DENIED … with additional detail indicating that permission was denied as protocol is not secure enough for call.
 
 
-#####Security
+##### Security
 
 The HTTP2 specification mandates the use of TLS 1.2 or higher when TLS is used with HTTP2. It also places some additional constraints on the allowed ciphers in deployments to avoid known-problems as well as requiring SNI support. It is also expected that HTTP2 will be used in conjunction with proprietary transport security mechanisms about which the specification can make no meaningful recommendations.
 
-#####Connection Management
-######GOAWAY Frame
+##### Connection Management
+###### GOAWAY Frame
 Sent by servers to clients to indicate that they will no longer accept any new streams on the associated connections. This frame includes the id of the last successfully accepted stream by the server. Clients should consider any stream initiated after the last successfully accepted stream as UNAVAILABLE and retry the call elsewhere. Clients are free to continue working with the already accepted streams until they complete or the connection is terminated.
 
 Servers should send GOAWAY before terminating a connection to reliably inform clients which work has been accepted by the server and is being executed.
 
-######PING Frame
+###### PING Frame
 Both clients and servers can send a PING frame that the peer must respond to by precisely echoing what they received. This is used to assert that the connection is still live as well as providing a means to estimate end-to-end latency. If a server initiated PING does not receive a response within the deadline expected by the runtime all outstanding calls on the server will be closed with a CANCELLED status. An expired client initiated PING will cause all calls to be closed with an UNAVAILABLE status. Note that the frequency of PINGs is highly dependent on the network environment, implementations are free to adjust PING frequency based on network and application requirements.
 
-######Connection failure
+###### Connection failure
 If a detectable connection failure occurs on the client all calls will be closed with an UNAVAILABLE status. For servers open calls will be closed with a CANCELLED status.
 
 
diff --git a/doc/PROTOCOL-WEB.md b/doc/PROTOCOL-WEB.md
index 0b54e0f34fc7ebe2ef2ae300982a8098956bf24d..6bb280894ab9e8a8b8c87560c68afaeed0ca1d03 100644
--- a/doc/PROTOCOL-WEB.md
+++ b/doc/PROTOCOL-WEB.md
@@ -83,7 +83,8 @@ in the body.
 
 User Agent
 
-* U-A: grpc-web-javascript
+* Do NOT use User-Agent header (which is to be set by browsers, by default)
+* Use X-User-Agent: grpc-web-javascript/0.1 (follow the same format as specified in [gRPC over HTTP2](http://www.grpc.io/docs/guides/wire.html))
 
 ---
 
@@ -94,8 +95,6 @@ the response stream needs to be text encoded e.g. when XHR is used or due
 to security policies with XHR
   * Accept: application/grpc-web-text
 2. The default text encoding is base64
-  * Text encoding may be specified with Content-Type or Accept headers as
-      * application/grpc-web-text-base64
   * Note that “Content-Transfer-Encoding: base64” should not be used.
   Due to in-stream base64 padding when delimiting messages, the entire
   response body is not necessarily a valid base64-encoded entity
diff --git a/doc/binary-logging.md b/doc/binary-logging.md
index 69020d9828513a03b6f27fb1df0438905db7318c..86b3f766dbd753d315c9e8429bac3968d178b626 100644
--- a/doc/binary-logging.md
+++ b/doc/binary-logging.md
@@ -2,7 +2,7 @@
 
 ## Format
 
-The log format is described in [this proto file](src/proto/grpc/binary_log/v1alpha/log.proto). It is intended that multiple parts of the call will be logged in separate files, and then correlated by analysis tools using the rpc\_id.
+The log format is described in [this proto file](/src/proto/grpc/binary_log/v1alpha/log.proto). It is intended that multiple parts of the call will be logged in separate files, and then correlated by analysis tools using the rpc\_id.
 
 ## API
 
diff --git a/doc/combiner-explainer.md b/doc/combiner-explainer.md
new file mode 100644
index 0000000000000000000000000000000000000000..9e9d077273ec0c2b15eb846e0bee2e188f08b5a8
--- /dev/null
+++ b/doc/combiner-explainer.md
@@ -0,0 +1,158 @@
+# Combiner Explanation
+## Talk by ctiller, notes by vjpai
+
+Typical way of doing critical section
+
+```
+mu.lock()
+do_stuff()
+mu.unlock()
+```
+
+An alternative way of doing it is
+
+```
+class combiner {
+  run(f) {
+    mu.lock()
+    f()
+    mu.unlock()
+  }
+  mutex mu;
+}
+
+combiner.run(do_stuff)
+```
+
+If you have two threads calling combiner, there will be some kind of
+queuing in place. It's called `combiner` because you can pass in more
+than one do_stuff at once and they will run under a common `mu`.
+
+The implementation described above has the issue that you're blocking a thread
+for a period of time, and this is considered harmful because it's an application thread that you're blocking.
+
+Instead, get a new property:
+* Keep things running in serial execution
+* Don't ever sleep the thread
+* But maybe allow things to end up running on a different thread from where they were started
+* This means that `do_stuff` doesn't necessarily run to completion when `combiner.run` is invoked
+
+```
+class combiner {
+  mpscq q; // multi-producer single-consumer queue can be made non-blocking
+  state s; // is it empty or executing
+  
+  run(f) {
+    if (q.push(f)) { 
+      // q.push returns true if it's the first thing
+      while (q.pop(&f)) { // modulo some extra work to avoid races
+        f();
+      }
+    }
+  }
+}
+```
+
+The basic idea is that the first one to push onto the combiner
+executes the work and then keeps executing functions from the queue
+until the combiner is drained.
+
+Our combiner does some additional work, with the motivation of write-batching.
+
+We have a second tier of `run` called `run_finally`. Anything queued
+onto `run_finally` runs after we have drained the queue. That means
+that there is essentially a finally-queue. This is not guaranteed to
+be final, but it's best-effort. In the process of running the finally
+item, we might put something onto the main combiner queue and so we'll
+need to re-enter.
+
+`chttp2` runs all ops in the run state except if it sees a write it puts that into a finally. That way anything else that gets put into the combiner can add to that write.
+
+```
+class combiner {
+  mpscq q; // multi-producer single-consumer queue can be made non-blocking
+  state s; // is it empty or executing
+  queue finally; // you can only do run_finally when you are already running something from the combiner
+  
+  run(f) {
+    if (q.push(f)) { 
+      // q.push returns true if it's the first thing
+      loop:
+      while (q.pop(&f)) { // modulo some extra work to avoid races
+        f();
+      }
+      while (finally.pop(&f)) {
+        f();
+      }
+      goto loop;
+    }
+  }
+}
+```
+
+So that explains how combiners work in general. In gRPC, there is
+`start_batch(..., tag)` and then work only gets activated by somebody
+calling `cq::next` which returns a tag. This gives an API-level
+guarantee that there will be a thread doing polling to actually make
+work happen. However, some operations are not covered by a poller
+thread, such as cancellation that doesn't have a completion. Other
+callbacks that don't have a completion are the internal work that gets
+done before the batch gets completed. We need a condition called
+`covered_by_poller` that means that the item will definitely need some
+thread at some point to call `cq::next` . This includes those
+callbacks that directly cause a completion but also those that are
+indirectly required before getting a completion. If we can't tell for
+sure for a specific path, we have to assumed it is not covered by
+poller.
+
+The above combiner has the problem that it keeps draining for a
+potentially infinite amount of time and that can lead to a huge tail
+latency for some operations. So we can tweak it by returning to the application
+if we know that it is valid to do so:
+
+```
+while (q.pop(&f)) {
+  f();
+  if (control_can_be_returned && some_still_queued_thing_is_covered_by_poller) {
+    offload_combiner_work_to_some_other_thread();
+  }
+}
+```
+
+`offload` is more than `break`; it does `break` but also causes some
+other thread that is currently waiting on a poll to break out of its
+poll. This is done by setting up a per-polling-island work-queue
+(distributor) wakeup FD. The work-queue is the converse of the combiner; it
+tries to spray events onto as many threads as possible to get as much concurrency as possible.
+
+So `offload` really does:
+
+``` 
+  workqueue.run(continue_from_while_loop);
+  break;
+```
+
+This needs us to add another class variable for a `workqueue`
+(which is really conceptually a distributor).
+
+```
+workqueue::run(f) {
+  q.push(f)
+  eventfd.wakeup()
+}
+
+workqueue::readable() {
+  eventfd.consume();
+  q.pop(&f);
+  f();
+  if (!q.empty()) {
+    eventfd.wakeup(); // spray across as many threads as are waiting on this workqueue
+  }
+}
+```
+
+In principle, `run_finally` could get starved, but this hasn't
+happened in practice. If we were concerned about this, we could put a
+limit on how many things come off the regular `q` before the `finally`
+queue gets processed.
+
diff --git a/doc/core/grpc-error.md b/doc/core/grpc-error.md
new file mode 100644
index 0000000000000000000000000000000000000000..c05d1dd909a83e510570b74ae1b9f904d68926c1
--- /dev/null
+++ b/doc/core/grpc-error.md
@@ -0,0 +1,160 @@
+# gRPC Error
+
+## Background
+
+`grpc_error` is the c-core's opaque representation of an error. It holds a
+collection of integers, strings, timestamps, and child errors that related to
+the final error.
+
+always present are:
+
+*   GRPC_ERROR_STR_FILE and GRPC_ERROR_INT_FILE_LINE - the source location where
+    the error was generated
+*   GRPC_ERROR_STR_DESCRIPTION - a human readable description of the error
+*   GRPC_ERROR_TIME_CREATED - a timestamp indicating when the error happened
+
+An error can also have children; these are other errors that are believed to
+have contributed to this one. By accumulating children, we can begin to root
+cause high level failures from low level failures, without having to derive
+execution paths from log lines.
+
+grpc_errors are refcounted objects, which means they need strict ownership
+semantics. An extra ref on an error can cause a memory leak, and a missing ref
+can cause a crash.
+
+This document serves as a detailed overview of grpc_error's ownership rules. It
+should help people use the errors, as well as help people debug refcount related
+errors.
+
+## Clarification of Ownership
+
+If a particular function is said to "own" an error, that means it has the
+responsibility of calling unref on the error. A function may have access to an
+error without ownership of it.
+
+This means the function may use the error, but must not call unref on it, since
+that will be done elsewhere in the code. A function that does not own an error
+may explicitly take ownership of it by manually calling GRPC_ERROR_REF.
+
+## Ownership Rules
+
+There are three rules of error ownership, which we will go over in detail.
+
+*   If `grpc_error` is returned by a function, the caller owns a ref to that
+    instance.
+*   If a `grpc_error` is passed to a `grpc_closure` callback function, then that
+    function does not own a ref to the error.
+*   if a `grpc_error` is passed to *any other function*, then that function
+    takes ownership of the error.
+
+### Rule 1
+
+> If `grpc_error` is returned by a function, the caller owns a ref to that
+> instance.*
+
+For example, in the following code block, error1 and error2 are owned by the
+current function.
+
+```C
+grpc_error* error1 = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured");
+grpc_error* error2 = some_operation_that_might_fail(...);
+```
+
+The current function would have to explicitly call GRPC_ERROR_UNREF on the
+errors, or pass them along to a function that would take over the ownership.
+
+### Rule 2
+
+> If a `grpc_error` is passed to a `grpc_closure` callback function, then that
+> function does not own a ref to the error.
+
+A `grpc_closure` callback function is any function that has the signature:
+
+```C
+void (*cb)(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error);
+```
+
+This means that the error ownership is NOT transferred when a functions calls:
+
+```C
+c->cb(exec_ctx, c->cb_arg, err);
+```
+
+The caller is still responsible for unref-ing the error.
+
+However, the above line is currently being phased out! It is safer to invoke
+callbacks with `grpc_closure_run` and `grpc_closure_sched`. These functions are
+not callbacks, so they will take ownership of the error passed to them.
+
+```C
+grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured");
+grpc_closure_run(exec_ctx, cb, error);
+// current function no longer has ownership of the error
+```
+
+If you schedule or run a closure, but still need ownership of the error, then
+you must explicitly take a reference.
+
+```C
+grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured");
+grpc_closure_run(exec_ctx, cb, GRPC_ERROR_REF(error));
+// do some other things with the error
+GRPC_ERROR_UNREF(error);
+```
+
+Rule 2 is more important to keep in mind when **implementing** `grpc_closure`
+callback functions. You must keep in mind that you do not own the error, and
+must not unref it. More importantly, you cannot pass it to any function that
+would take ownership of the error, without explicitly taking ownership yourself.
+For example:
+
+```C
+void on_some_action(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+  // this would cause a crash, because some_function will unref the error,
+  // and the caller of this callback will also unref it.
+  some_function(error);
+
+  // this callback function must take ownership, so it can give that
+  // ownership to the function it is calling.
+  some_function(GRPC_ERROR_REF(error));
+}
+```
+
+### Rule 3
+
+> if a `grpc_error` is passed to *any other function*, then that function takes
+> ownership of the error.
+
+Take the following example:
+
+```C
+grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured");
+// do some things
+some_function(error);
+// can't use error anymore! might be gone.
+```
+
+When some_function is called, it takes over the ownership of the error, and it
+will eventually unref it. So the caller can no longer safely use the error.
+
+If the caller needed to keep using the error (or passing it to other functions),
+if would have to take on a reference to it. This is a common pattern seen.
+
+```C
+void func() {
+  grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error");
+  some_function(GRPC_ERROR_REF(error));
+  // do things
+  some_other_function(GRPC_ERROR_REF(error));
+  // do more things
+  some_last_function(error);
+}
+```
+
+The last call takes ownership and will eventually give the error its final
+unref.
+
+When **implementing** a function that takes an error (and is not a
+`grpc_closure` callback function), you must ensure the error is unref-ed either
+by doing it explicitly with GRPC_ERROR_UNREF, or by passing the error to a
+function that takes over the ownership.
diff --git a/doc/environment_variables.md b/doc/environment_variables.md
index a3806732334302a5e555fb147c536194371535a7..47efb3a1d874db1864d44082d834ec67c8380e43 100644
--- a/doc/environment_variables.md
+++ b/doc/environment_variables.md
@@ -55,6 +55,7 @@ some configuration as environment variables that can be set.
   - queue_timeout
   - server_channel - lightweight trace of significant server channel events
   - secure_endpoint - traces bytes flowing through encrypted channels
+  - timer - timers (alarms) in the grpc internals
   - transport_security - traces metadata about secure channel establishment
   - tcp - traces bytes in and out of a channel
 
@@ -69,3 +70,11 @@ some configuration as environment variables that can be set.
   - DEBUG - log all gRPC messages
   - INFO - log INFO and ERROR message
   - ERROR - log only errors
+
+* GRPC_DNS_RESOLVER
+  Declares which DNS resolver to use. The default is ares if gRPC is built with
+  c-ares support. Otherwise, the value of this environment variable is ignored.
+  Available DNS resolver include:
+  - native (default)- a DNS resolver based around getaddrinfo(), creates a new thread to
+    perform name resolution
+  - ares - a DNS resolver based around the c-ares library
diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md
index 53a1fdf193c08ac4c7678064719b3933bb1c36c2..2078bb37ea1149bda1943a6efcee174935a1c3ec 100644
--- a/doc/g_stands_for.md
+++ b/doc/g_stands_for.md
@@ -7,3 +7,5 @@ future), and the corresponding version numbers that used them:
 - 1.0 'g' stands for 'gRPC'
 - 1.1 'g' stands for 'good'
 - 1.2 'g' stands for 'green'
+- 1.3 'g' stands for 'gentle'
+- 1.4 'g' stands for 'gregarious'
diff --git a/doc/negative-http2-interop-test-descriptions.md b/doc/http2-interop-test-descriptions.md
similarity index 65%
rename from doc/negative-http2-interop-test-descriptions.md
rename to doc/http2-interop-test-descriptions.md
index b64fe6a024d6f06658b93cf5461e1db73d62ee89..435a8de709cbe1374b4f1582e8f4dcc46f77d825 100644
--- a/doc/negative-http2-interop-test-descriptions.md
+++ b/doc/http2-interop-test-descriptions.md
@@ -193,3 +193,79 @@ Server Procedure:
   1. Sets MAX_CONCURRENT_STREAMS to one after the connection is made.
 
 *The assertion that the MAX_CONCURRENT_STREAMS limit is upheld occurs in the http2 library we used.*
+
+### data_frame_padding
+
+This test verifies that the client can correctly receive padded http2 data
+frames. It also stresses the client's flow control (there is a high chance
+that the sender will deadlock if the client's flow control logic doesn't
+correctly account for padding).
+
+Client Procedure:
+(Note this is the same procedure as in the "large_unary" gRPC interop tests.
+Clients should use their "large_unary" gRPC interop test implementations.)
+Procedure:
+ 1. Client calls UnaryCall with:
+
+    ```
+    {
+      response_size: 314159
+      payload:{
+        body: 271828 bytes of zeros
+      }
+    }
+    ```
+
+Client asserts:
+* call was successful
+* response payload body is 314159 bytes in size
+* clients are free to assert that the response payload body contents are zero
+  and comparing the entire response message against a golden response
+
+Server Procedure:
+  1. Reply to the client's request with a `SimpleResponse`, with a payload
+  body length of `SimpleRequest.response_size`. But send it across specific
+  http2 data frames as follows:
+    * Each http2 data frame contains a 5 byte payload and 255 bytes of padding.
+
+  * Note the 5 byte payload and 255 byte padding are partly arbitrary,
+  and other numbers are also ok. With 255 bytes of padding for each 5 bytes of
+  payload containing actual gRPC message, the 300KB response size will
+  multiply into around 15 megabytes of flow control debt, which should stress
+  flow control accounting.
+
+### no_df_padding_sanity_test
+
+This test verifies that the client can correctly receive a series of small
+data frames. Note that this test is intentionally a slight variation of
+"data_frame_padding", with the only difference being that this test doesn't use data
+frame padding when the response is sent. This test is primarily meant to
+prove correctness of the http2 server implementation and highlight failures
+of the "data_frame_padding" test.
+
+Client Procedure:
+(Note this is the same procedure as in the "large_unary" gRPC interop tests.
+Clients should use their "large_unary" gRPC interop test implementations.)
+Procedure:
+ 1. Client calls UnaryCall with:
+
+    ```
+    {
+      response_size: 314159
+      payload:{
+        body: 271828 bytes of zeros
+      }
+    }
+    ```
+
+Client asserts:
+* call was successful
+* response payload body is 314159 bytes in size
+* clients are free to assert that the response payload body contents are zero
+  and comparing the entire response message against a golden response
+
+Server Procedure:
+  1. Reply to the client's request with a `SimpleResponse`, with a payload
+  body length of `SimpleRequest.response_size`. But send it across series of
+  http2 data frames that contain 5 bytes of "payload" and zero bytes of
+  "padding" (the padding flags on the data frames should not be set).
diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md
index da3b97674438b5f36d0b3fe6512f5b0f70a4d156..b040621f8834cd472338d5601e433904e406764b 100644
--- a/doc/interop-test-descriptions.md
+++ b/doc/interop-test-descriptions.md
@@ -27,7 +27,7 @@ Clients should accept these arguments:
     * Whether to use a plaintext or encrypted connection
 * --use_test_ca=BOOLEAN
     * Whether to replace platform root CAs with
-      [ca.pem](https://github.com/grpc/grpc/blob/master/src/core/lib/tsi/test_creds/ca.pem)
+      [ca.pem](https://github.com/grpc/grpc/blob/master/src/core/tsi/test_creds/ca.pem)
       as the CA root
 * --default_service_account=ACCOUNT_EMAIL
     * Email of the GCE default service account.
@@ -81,9 +81,8 @@ Procedure:
     Client marks the request as cacheable by setting the cacheable flag in the
     request context. Longer term this should be driven by the method option
     specified in the proto file itself.
- 2. Client calls CacheableUnaryCall with `SimpleRequest` request again
-    immediately with the same payload as the previous request. Cacheable flag is
-    also set for this request's context.
+ 2. Client calls CacheableUnaryCall again immediately with the same request and
+    configuration as the previous call.
 
 Client asserts:
 * Both calls were successful
@@ -969,7 +968,7 @@ Servers should accept these arguments:
     * Whether to use a plaintext or encrypted connection
 
 Servers must support TLS with ALPN. They should use
-[server1.pem](https://github.com/grpc/grpc/blob/master/src/core/lib/tsi/test_creds/server1.pem)
+[server1.pem](https://github.com/grpc/grpc/blob/master/src/core/tsi/test_creds/server1.pem)
 for their certificate.
 
 ### EmptyCall
@@ -986,6 +985,7 @@ for the `SimpleRequest.response_type`. If the server does not support the
 `response_type`, then it should fail the RPC with `INVALID_ARGUMENT`.
 
 ### CacheableUnaryCall
+[CacheableUnaryCall]: #cacheableunarycall
 
 Server gets the default SimpleRequest proto as the request. The content of the
 request is ignored. It returns the SimpleResponse proto with the payload set
diff --git a/doc/server_side_auth.md b/doc/server_side_auth.md
index 288c6e9cb38b9eb9ee17a8240305ad83c8eb02e7..d260237928d773bf49c4272a58a11ebbe48676d1 100644
--- a/doc/server_side_auth.md
+++ b/doc/server_side_auth.md
@@ -13,7 +13,7 @@ The contents of the *auth properties* are populated by an *auth interceptor*. Th
 
 WARNING: AuthContext is the only reliable source of truth when it comes to authenticating RPCs. Using any other call/context properties for authentication purposes is wrong and inherently unsafe.
 
-####Example AuthContext contents
+#### Example AuthContext contents
 
 For secure channel using mutual TLS authentication with both client and server certificates (test certificates from this repository are used).
 
@@ -45,7 +45,7 @@ gRPC comes with some basic "interceptors" already built-in.
 WARNING: While there is a public API that allows anyone to write their own custom interceptor, please think twice before using it.
 There are legitimate uses for custom interceptors but you should keep in mind that as auth interceptors essentially decide which RPCs are authenticated and which are not, their code is very sensitive from the security perspective and getting things wrong might have serious consequences. If unsure, we strongly recommend to rely on official & proven interceptors that come with gRPC.
 
-####Available auth interceptors
+#### Available auth interceptors
 - TLS/SSL certificate authentication (built into gRPC's security layer, automatically used whenever you use a secure connection)
 - (coming soon) JWT auth token authentication
 - more will be added over time
diff --git a/doc/service_config.md b/doc/service_config.md
index ecc23817d121dec33b06e37e937874da29f37210..8039fcad09586d4f8c6c413dd8f3081c16123a1f 100644
--- a/doc/service_config.md
+++ b/doc/service_config.md
@@ -13,12 +13,21 @@ The service config is a JSON string of the following form:
 ```
 {
   // Load balancing policy name.
-  // Supported values are 'round_robin' and 'grpclb'.
-  // Optional; if unset, the default behavior is pick the first available
-  // backend.
-  // Note that if the resolver returns only balancer addresses and no
-  // backend addresses, gRPC will always use the 'grpclb' policy,
-  // regardless of what this field is set to.
+  // Currently, the only selectable client-side policy provided with gRPC
+  // is 'round_robin', but third parties may add their own policies.
+  // This field is optional; if unset, the default behavior is to pick
+  // the first available backend.
+  // If the policy name is set via the client API, that value overrides
+  // the value specified here.
+  //
+  // Note that if the resolver returns at least one balancer address (as
+  // opposed to backend addresses), gRPC will use grpclb (see
+  // https://github.com/grpc/grpc/blob/master/doc/load-balancing.md),
+  // regardless of what LB policy is requested either here or via the
+  // client API.  However, if the resolver returns at least one backend
+  // address in addition to the balancer address(es), the client may fall
+  // back to the requested policy if it is unable to reach any of the
+  // grpclb load balancers.
   'loadBalancingPolicy': string,
 
   // Per-method configuration.  Optional.
diff --git a/doc/status_ordering.md b/doc/status_ordering.md
new file mode 100644
index 0000000000000000000000000000000000000000..fccfa863a3ef82fee5b7d8fa228e90f7bd2fb63c
--- /dev/null
+++ b/doc/status_ordering.md
@@ -0,0 +1,16 @@
+Ordering Status and Reads in the gRPC API
+-----------------------------------------
+
+Rules for implementors:
+1. Reads and Writes Must not succeed after Status has been delivered.
+2. OK Status is only delivered after all buffered messages are read.
+3. Reads May continue to succeed after a failing write.
+   However, once a write fails, all subsequent writes Must fail,
+   and similarly, once a read fails, all subsequent reads Must fail.
+4. When an error status is known to the library, if the user asks for status,
+   the library Should discard messages received in the library but not delivered
+   to the user and then deliver the status. If the user does not ask for status
+   but continues reading, the library Should deliver buffered messages before
+   delivering status. The library MAY choose to implement the stricter version
+   where errors cause all buffered messages to be dropped, but this is not a
+   requirement.
diff --git a/doc/statuscodes.md b/doc/statuscodes.md
index 1cd72df30ad4cfec034b88f24cf02ec75e0482c4..f2df9e00dec423919be9df8a79927d30c775b6ee 100644
--- a/doc/statuscodes.md
+++ b/doc/statuscodes.md
@@ -1,9 +1,20 @@
 # Status codes and their use in gRPC
 
-gRPC uses a set of well defined status codes as part of the RPC API. All RPCs started at a client return  a `status` object composed of an integer `code` and a string `message`. The server-side can choose the status it returns for a given RPC.
+gRPC uses a set of well defined status codes as part of the RPC API. All
+RPCs started at a client return  a `status` object composed of an integer
+`code` and a string `message`. The server-side can choose the status it
+returns for a given RPC.
 
-The gRPC client and server-side implementations may also generate and return `status` on their own when errors happen.  
-Only a subset of the pre-defined status codes are generated by the gRPC libraries. The following table lists these codes and summarizes the situations in which they are generated, either by the client or the server-side library implementation.
+The gRPC client and server-side implementations may also generate and
+return `status` on their own when errors happen.  Only a subset of
+the pre-defined status codes are generated by the gRPC libraries.  This
+allows applications to be sure that any other code it sees was actually
+returned by the application (although it is also possible for the
+server-side to return one of the codes generated by the gRPC libraries).
+
+The following table lists the codes that may be returned by the gRPC
+libraries (on either the client-side or server-side) and summarizes the
+situations in which they are generated.
 
 | Case        | Code           | Generated at Client or Server  |
 | ------------- |:-------------| :-----:|
@@ -26,7 +37,7 @@ Only a subset of the pre-defined status codes are generated by the gRPC librarie
 | Response cardinality violation (method requires exactly one response but server sent some other number of responses) | UNIMPLEMENTED | Client|
 | Error parsing response proto	| INTERNAL | Client|
 | Error parsing request proto	| INTERNAL | Server|
-
+| Sent or received message was larger than configured limit | RESOURCE_EXHAUSTED | Both |
 
 The following status codes are never generated by the library:
 - INVALID_ARGUMENT
diff --git a/etc/roots.pem b/etc/roots.pem
index 66605675ef0377015f3161ca21d6e464a3157129..b2096fbc4d3c89eb0eebbbf11743c6c76238488f 100644
--- a/etc/roots.pem
+++ b/etc/roots.pem
@@ -1617,42 +1617,6 @@ wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN
 pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
 -----END CERTIFICATE-----
 
-# Issuer: CN=WellsSecure Public Root Certificate Authority O=Wells Fargo WellsSecure OU=Wells Fargo Bank NA
-# Subject: CN=WellsSecure Public Root Certificate Authority O=Wells Fargo WellsSecure OU=Wells Fargo Bank NA
-# Label: "WellsSecure Public Root Certificate Authority"
-# Serial: 1
-# MD5 Fingerprint: 15:ac:a5:c2:92:2d:79:bc:e8:7f:cb:67:ed:02:cf:36
-# SHA1 Fingerprint: e7:b4:f6:9d:61:ec:90:69:db:7e:90:a7:40:1a:3c:f4:7d:4f:e8:ee
-# SHA256 Fingerprint: a7:12:72:ae:aa:a3:cf:e8:72:7f:7f:b3:9f:0f:b3:d1:e5:42:6e:90:60:b0:6e:e6:f1:3e:9a:3c:58:33:cd:43
------BEGIN CERTIFICATE-----
-MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMx
-IDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxs
-cyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9v
-dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDcxMjEzMTcwNzU0WhcNMjIxMjE0
-MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdl
-bGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQD
-DC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+r
-WxxTkqxtnt3CxC5FlAM1iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjU
-Dk/41itMpBb570OYj7OeUt9tkTmPOL13i0Nj67eT/DBMHAGTthP796EfvyXhdDcs
-HqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8bJVhHlfXBIEyg1J55oNj
-z7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiBK0HmOFaf
-SZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/Slwxl
-AgMBAAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqG
-KGh0dHA6Ly9jcmwucGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0P
-AQH/BAQDAgHGMB0GA1UdDgQWBBQmlRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0j
-BIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGBi6SBiDCBhTELMAkGA1UEBhMC
-VVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNX
-ZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg
-Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEB
-ALkVsUSRzCPIK0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd
-/ZDJPHV3V3p9+N701NX3leZ0bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pB
-A4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSljqHyita04pO2t/caaH/+Xc/77szWn
-k4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+esE2fDbbFwRnzVlhE9
-iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJtylv
-2G0xffX8oRAHh84vWdw+WNs=
------END CERTIFICATE-----
-
 # Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited
 # Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited
 # Label: "COMODO ECC Certification Authority"
@@ -1738,57 +1702,6 @@ Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ
 /L7fCg0=
 -----END CERTIFICATE-----
 
-# Issuer: CN=Microsec e-Szigno Root CA O=Microsec Ltd. OU=e-Szigno CA
-# Subject: CN=Microsec e-Szigno Root CA O=Microsec Ltd. OU=e-Szigno CA
-# Label: "Microsec e-Szigno Root CA"
-# Serial: 272122594155480254301341951808045322001
-# MD5 Fingerprint: f0:96:b6:2f:c5:10:d5:67:8e:83:25:32:e8:5e:2e:e5
-# SHA1 Fingerprint: 23:88:c9:d3:71:cc:9e:96:3d:ff:7d:3c:a7:ce:fc:d6:25:ec:19:0d
-# SHA256 Fingerprint: 32:7a:3d:76:1a:ba:de:a0:34:eb:99:84:06:27:5c:b1:a4:77:6e:fd:ae:2f:df:6d:01:68:ea:1c:4f:55:67:d0
------BEGIN CERTIFICATE-----
-MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAw
-cjELMAkGA1UEBhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNy
-b3NlYyBMdGQuMRQwEgYDVQQLEwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9z
-ZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0MDYxMjI4NDRaFw0xNzA0MDYxMjI4
-NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEWMBQGA1UEChMN
-TWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMTGU1p
-Y3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2u
-uO/TEdyB5s87lozWbxXGd36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+
-LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/NoqdNAoI/gqyFxuEPkEeZlApxcpMqyabA
-vjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjcQR/Ji3HWVBTji1R4P770
-Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJPqW+jqpx
-62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcB
-AQRbMFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3Aw
-LQYIKwYBBQUHMAKGIWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAP
-BgNVHRMBAf8EBTADAQH/MIIBcwYDVR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIB
-AQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3LmUtc3ppZ25vLmh1L1NaU1ov
-MIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0AdAB2AOEAbgB5
-ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn
-AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABT
-AHoAbwBsAGcA4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABh
-ACAAcwB6AGUAcgBpAG4AdAAgAGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABo
-AHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMAegBpAGcAbgBvAC4AaAB1AC8AUwBa
-AFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6Ly93d3cuZS1zemln
-bm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NOPU1p
-Y3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxP
-PU1pY3Jvc2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZv
-Y2F0aW9uTGlzdDtiaW5hcnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuB
-EGluZm9AZS1zemlnbm8uaHWkdzB1MSMwIQYDVQQDDBpNaWNyb3NlYyBlLVN6aWdu
-w7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhTWjEWMBQGA1UEChMNTWlj
-cm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhVMIGsBgNV
-HSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJI
-VTERMA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDAS
-BgNVBAsTC2UtU3ppZ25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBS
-b290IENBghEAzLjnv04pGv2i3GalHCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS
-8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMTnGZjWS7KXHAM/IO8VbH0jgds
-ZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FEaGAHQzAxQmHl
-7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a
-86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfR
-hUZLphK3dehKyVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/
-MPMMNz7UwiiAc7EBt51alhQBS6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU=
------END CERTIFICATE-----
-
 # Issuer: CN=Certigna O=Dhimyotis
 # Subject: CN=Certigna O=Dhimyotis
 # Label: "Certigna"
@@ -2014,36 +1927,6 @@ buXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2G8kS1sHNzYDzAgE8yGnLRUhj
 2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5mmxE=
 -----END CERTIFICATE-----
 
-# Issuer: O=Japanese Government OU=ApplicationCA
-# Subject: O=Japanese Government OU=ApplicationCA
-# Label: "ApplicationCA - Japanese Government"
-# Serial: 49
-# MD5 Fingerprint: 7e:23:4e:5b:a7:a5:b4:25:e9:00:07:74:11:62:ae:d6
-# SHA1 Fingerprint: 7f:8a:b0:cf:d0:51:87:6a:66:f3:36:0f:47:c8:8d:8c:d3:35:fc:74
-# SHA256 Fingerprint: 2d:47:43:7d:e1:79:51:21:5a:12:f3:c5:8e:51:c7:29:a5:80:26:ef:1f:cc:0a:5f:b3:d9:dc:01:2f:60:0d:19
------BEGIN CERTIFICATE-----
-MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEc
-MBoGA1UEChMTSmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRp
-b25DQTAeFw0wNzEyMTIxNTAwMDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYT
-AkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zlcm5tZW50MRYwFAYDVQQLEw1BcHBs
-aWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp23gdE6H
-j6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4fl+K
-f5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55
-IrmTwcrNwVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cw
-FO5cjFW6WY2H/CPek9AEjP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDiht
-QWEjdnjDuGWk81quzMKq2edY3rZ+nYVunyoKb58DKTCXKB28t89UKU5RMfkntigm
-/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRUWssmP3HMlEYNllPqa0jQ
-k/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNVBAYTAkpQ
-MRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOC
-seODvOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
-ggEBADlqRHZ3ODrso2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJ
-hyzjVOGjprIIC8CFqMjSnHH2HZ9g/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+
-eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYDio+nEhEMy/0/ecGc/WLuo89U
-DNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmWdupwX3kSa+Sj
-B1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL
-rosot4LKGAfmt1t06SAZf7IbiVQ=
------END CERTIFICATE-----
-
 # Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only
 # Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only
 # Label: "GeoTrust Primary Certification Authority - G3"
@@ -4720,39 +4603,6 @@ Yv4HAqGEVka+lgqaE9chTLd8B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW
 +qtB4Uu2NQvAmxU=
 -----END CERTIFICATE-----
 
-# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6 O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
-# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6 O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
-# Label: "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6"
-# Serial: 138134509972618
-# MD5 Fingerprint: f8:c5:ee:2a:6b:be:95:8d:08:f7:25:4a:ea:71:3e:46
-# SHA1 Fingerprint: 8a:5c:8c:ee:a5:03:e6:05:56:ba:d8:1b:d4:f6:c9:b0:ed:e5:2f:e0
-# SHA256 Fingerprint: 8d:e7:86:55:e1:be:7f:78:47:80:0b:93:f6:94:d2:1d:36:8c:c0:6e:03:3e:7f:ab:04:bb:5e:b9:9d:a6:b7:00
------BEGIN CERTIFICATE-----
-MIIEJjCCAw6gAwIBAgIGfaHyZeyKMA0GCSqGSIb3DQEBCwUAMIGxMQswCQYDVQQG
-EwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYDVQQKDERUw5xSS1RSVVNUIEJpbGdp
-IMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBB
-LsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBI
-aXptZXQgU2HEn2xhecSxY8Sxc8SxIEg2MB4XDTEzMTIxODA5MDQxMFoXDTIzMTIx
-NjA5MDQxMFowgbExCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExTTBLBgNV
-BAoMRFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2
-ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMUIwQAYDVQQDDDlUw5xSS1RSVVNUIEVs
-ZWt0cm9uaWsgU2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLEgSDYwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCdsGjW6L0UlqMACprx9MfMkU1x
-eHe59yEmFXNRFpQJRwXiM/VomjX/3EsvMsew7eKC5W/a2uqsxgbPJQ1BgfbBOCK9
-+bGlprMBvD9QFyv26WZV1DOzXPhDIHiTVRZwGTLmiddk671IUP320EEDwnS3/faA
-z1vFq6TWlRKb55cTMgPp1KtDWxbtMyJkKbbSk60vbNg9tvYdDjTu0n2pVQ8g9P0p
-u5FbHH3GQjhtQiht1AH7zYiXSX6484P4tZgvsycLSF5W506jM7NE1qXyGJTtHB6p
-lVxiSvgNZ1GpryHV+DKdeboaX+UEVU0TRv/yz3THGmNtwx8XEsMeED5gCLMxAgMB
-AAGjQjBAMB0GA1UdDgQWBBTdVRcT9qzoSCHK77Wv0QAy7Z6MtTAOBgNVHQ8BAf8E
-BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAb1gNl0Oq
-FlQ+v6nfkkU/hQu7VtMMUszIv3ZnXuaqs6fvuay0EBQNdH49ba3RfdCaqaXKGDsC
-QC4qnFAUi/5XfldcEQlLNkVS9z2sFP1E34uXI9TDwe7UU5X+LEr+DXCqu4svLcsy
-o4LyVN/Y8t3XSHLuSqMplsNEzm61kod2pLv0kmzOLBQJZo6NrRa1xxsJYTvjIKID
-gI6tflEATseWhvtDmHd9KMeP2Cpu54Rvl0EpABZeTeIT6lnAY2c6RPuY/ATTMHKm
-9ocJV612ph1jmv3XZch4gyt1O6VbuA1df74jrlZVlFjvH4GMKrLN5ptjnhi85WsG
-tAuYSyher4hYyw==
------END CERTIFICATE-----
-
 # Issuer: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903
 # Subject: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903
 # Label: "Certinomis - Root CA"
@@ -5402,3 +5252,37 @@ LSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+
 x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31IiyBMz2TWuJdGsE7RKlY6
 oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr
 -----END CERTIFICATE-----
+
+# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM
+# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM
+# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1"
+# Serial: 1
+# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49
+# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca
+# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16
+-----BEGIN CERTIFICATE-----
+MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx
+GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp
+bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w
+KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0
+BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy
+dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG
+EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll
+IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU
+QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT
+TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg
+LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7
+a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr
+LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr
+N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X
+YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/
+iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f
+AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH
+V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
+BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh
+AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf
+IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4
+lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c
+8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf
+lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM=
+-----END CERTIFICATE-----
diff --git a/examples/cpp/helloworld/BUILD b/examples/BUILD
similarity index 72%
rename from examples/cpp/helloworld/BUILD
rename to examples/BUILD
index b9c3f5dfbed91b87a6a2911ae689980e589efc2d..382713e5e48e56a6ffccbffac51c1cac7104a259 100644
--- a/examples/cpp/helloworld/BUILD
+++ b/examples/BUILD
@@ -27,16 +27,40 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+package(default_visibility = ["//visibility:public"])
+
+load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
+
+grpc_proto_library(
+    name = "auth_sample",
+    srcs = ["protos/auth_sample.proto"],
+)
+
+grpc_proto_library(
+    name = "hellostreamingworld",
+    srcs = ["protos/hellostreamingworld.proto"],
+)
+
+grpc_proto_library(
+    name = "helloworld",
+    srcs = ["protos/helloworld.proto"],
+)
+
+grpc_proto_library(
+    name = "route_guide",
+    srcs = ["protos/route_guide.proto"],
+)
+
 cc_binary(
     name = "greeter_client",
-    srcs = ["greeter_client.cc"],
-    deps = ["//examples/protos:helloworld"],
+    srcs = ["cpp/helloworld/greeter_client.cc"],
+    deps = ["helloworld"],
     defines = ["BAZEL_BUILD"],
 )
 
 cc_binary(
     name = "greeter_server",
-    srcs = ["greeter_server.cc"],
-    deps = ["//examples/protos:helloworld"],
+    srcs = ["cpp/helloworld/greeter_server.cc"],
+    deps = ["helloworld"],
     defines = ["BAZEL_BUILD"],
 )
diff --git a/examples/cpp/README.md b/examples/cpp/README.md
index 783935cd53d3206ded632c3fe0c8571a3c9d048a..8e2bb5d13b1f2abea4d8783f4ea03d98995f9436 100644
--- a/examples/cpp/README.md
+++ b/examples/cpp/README.md
@@ -1,4 +1,4 @@
-#gRPC in 3 minutes (C++)
+# gRPC in 3 minutes (C++)
 
 ## Installation
 
diff --git a/examples/cpp/cpptutorial.md b/examples/cpp/cpptutorial.md
index ae84aba9163a9324f854122c965fa947cf77439a..7d98367da43cd977b1a331826c23efc5aa17721f 100644
--- a/examples/cpp/cpptutorial.md
+++ b/examples/cpp/cpptutorial.md
@@ -1,4 +1,4 @@
-#gRPC Basics: C++
+# gRPC Basics: C++
 
 This tutorial provides a basic C++ programmer's introduction to working with
 gRPC. By walking through this example you'll learn how to:
diff --git a/examples/csharp/helloworld-from-cli/Greeter.sln b/examples/csharp/helloworld-from-cli/Greeter.sln
new file mode 100644
index 0000000000000000000000000000000000000000..ca50470e66498a58564c1d0bdc3ad33fb3bc4bde
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/Greeter.sln
@@ -0,0 +1,34 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26228.4
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Greeter", "Greeter\Greeter.csproj", "{13B6DFC8-F5F6-4CC2-99DF-57A7CF042033}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreeterClient", "GreeterClient\GreeterClient.csproj", "{B754FB02-D501-4308-8B89-33AB7119C80D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreeterServer", "GreeterServer\GreeterServer.csproj", "{DDBFF994-E076-43AD-B18D-049DFC1B670C}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{13B6DFC8-F5F6-4CC2-99DF-57A7CF042033}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{13B6DFC8-F5F6-4CC2-99DF-57A7CF042033}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{13B6DFC8-F5F6-4CC2-99DF-57A7CF042033}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{13B6DFC8-F5F6-4CC2-99DF-57A7CF042033}.Release|Any CPU.Build.0 = Release|Any CPU
+		{B754FB02-D501-4308-8B89-33AB7119C80D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{B754FB02-D501-4308-8B89-33AB7119C80D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{B754FB02-D501-4308-8B89-33AB7119C80D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{B754FB02-D501-4308-8B89-33AB7119C80D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DDBFF994-E076-43AD-B18D-049DFC1B670C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DDBFF994-E076-43AD-B18D-049DFC1B670C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DDBFF994-E076-43AD-B18D-049DFC1B670C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DDBFF994-E076-43AD-B18D-049DFC1B670C}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/examples/csharp/helloworld-from-cli/Greeter/Greeter.csproj b/examples/csharp/helloworld-from-cli/Greeter/Greeter.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..6b26be1c9cd665f07ae86b6bb8014db67ff1e309
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/Greeter/Greeter.csproj
@@ -0,0 +1,19 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <AssemblyTitle>Greeter</AssemblyTitle>
+    <TargetFrameworks>netcoreapp1.0</TargetFrameworks>
+    <DebugType>portable</DebugType>
+    <AssemblyName>Greeter</AssemblyName>
+    <PackageId>Greeter</PackageId>
+    <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Google.Protobuf" Version="3.2.0" />
+    <PackageReference Include="Google.Protobuf.Tools" Version="3.2.0" />
+    <PackageReference Include="Grpc" Version="1.2.2" />
+    <PackageReference Include="Grpc.Tools" Version="1.2.2" />
+  </ItemGroup>
+
+</Project>
diff --git a/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs b/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs
index 6477b4f35be82ac49c60d2c9c661533143d56a06..ecfc8e131cb98059244d6bd0ca4cdc25cf276c47 100644
--- a/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs
+++ b/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs
@@ -10,7 +10,6 @@ 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 HelloworldReflection {
 
     #region Descriptor
@@ -41,31 +40,36 @@ namespace Helloworld {
   }
   #region Messages
   /// <summary>
-  ///  The request message containing the user's name.
+  /// 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());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<HelloRequest> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HelloRequest() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HelloRequest(HelloRequest other) : this() {
       name_ = other.name_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HelloRequest Clone() {
       return new HelloRequest(this);
     }
@@ -73,6 +77,7 @@ namespace Helloworld {
     /// <summary>Field number for the "name" field.</summary>
     public const int NameFieldNumber = 1;
     private string name_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Name {
       get { return name_; }
       set {
@@ -80,10 +85,12 @@ namespace Helloworld {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as HelloRequest);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(HelloRequest other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -95,16 +102,19 @@ namespace Helloworld {
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Name.Length != 0) hash ^= Name.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Name.Length != 0) {
         output.WriteRawTag(10);
@@ -112,6 +122,7 @@ namespace Helloworld {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Name.Length != 0) {
@@ -120,6 +131,7 @@ namespace Helloworld {
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(HelloRequest other) {
       if (other == null) {
         return;
@@ -129,6 +141,7 @@ namespace Helloworld {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -147,31 +160,36 @@ namespace Helloworld {
   }
 
   /// <summary>
-  ///  The response message containing the greetings
+  /// 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());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<HelloReply> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HelloReply() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HelloReply(HelloReply other) : this() {
       message_ = other.message_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HelloReply Clone() {
       return new HelloReply(this);
     }
@@ -179,6 +197,7 @@ namespace Helloworld {
     /// <summary>Field number for the "message" field.</summary>
     public const int MessageFieldNumber = 1;
     private string message_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Message {
       get { return message_; }
       set {
@@ -186,10 +205,12 @@ namespace Helloworld {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as HelloReply);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(HelloReply other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -201,16 +222,19 @@ namespace Helloworld {
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Message.Length != 0) hash ^= Message.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Message.Length != 0) {
         output.WriteRawTag(10);
@@ -218,6 +242,7 @@ namespace Helloworld {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Message.Length != 0) {
@@ -226,6 +251,7 @@ namespace Helloworld {
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(HelloReply other) {
       if (other == null) {
         return;
@@ -235,6 +261,7 @@ namespace Helloworld {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
diff --git a/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs b/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs
index 041f5a78d758f9d4e3653ff013ea77a4a4f36415..b321ea9e682b79be3063e7a28ea535f9103176dc 100644
--- a/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs
+++ b/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs
@@ -35,21 +35,21 @@
 using System;
 using System.Threading;
 using System.Threading.Tasks;
-using Grpc.Core;
+using grpc = global::Grpc.Core;
 
 namespace Helloworld {
   /// <summary>
-  ///  The greeting service definition.
+  /// The greeting service definition.
   /// </summary>
-  public static class Greeter
+  public static partial class Greeter
   {
     static readonly string __ServiceName = "helloworld.Greeter";
 
-    static readonly Marshaller<global::Helloworld.HelloRequest> __Marshaller_HelloRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom);
-    static readonly Marshaller<global::Helloworld.HelloReply> __Marshaller_HelloReply = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Helloworld.HelloRequest> __Marshaller_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Helloworld.HelloReply> __Marshaller_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom);
 
-    static readonly Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>(
-        MethodType.Unary,
+    static readonly grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>(
+        grpc::MethodType.Unary,
         __ServiceName,
         "SayHello",
         __Marshaller_HelloRequest,
@@ -62,29 +62,32 @@ namespace Helloworld {
     }
 
     /// <summary>Base class for server-side implementations of Greeter</summary>
-    public abstract class GreeterBase
+    public abstract partial class GreeterBase
     {
       /// <summary>
-      ///  Sends a greeting
+      /// Sends a greeting
       /// </summary>
-      public virtual global::System.Threading.Tasks.Task<global::Helloworld.HelloReply> SayHello(global::Helloworld.HelloRequest request, ServerCallContext context)
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Helloworld.HelloReply> SayHello(global::Helloworld.HelloRequest request, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
     }
 
     /// <summary>Client for Greeter</summary>
-    public class GreeterClient : ClientBase<GreeterClient>
+    public partial class GreeterClient : grpc::ClientBase<GreeterClient>
     {
       /// <summary>Creates a new client for Greeter</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
-      public GreeterClient(Channel channel) : base(channel)
+      public GreeterClient(grpc::Channel channel) : base(channel)
       {
       }
       /// <summary>Creates a new client for Greeter that uses a custom <c>CallInvoker</c>.</summary>
       /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
-      public GreeterClient(CallInvoker callInvoker) : base(callInvoker)
+      public GreeterClient(grpc::CallInvoker callInvoker) : base(callInvoker)
       {
       }
       /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
@@ -98,33 +101,50 @@ namespace Helloworld {
       }
 
       /// <summary>
-      ///  Sends a greeting
+      /// Sends a greeting
       /// </summary>
-      public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return SayHello(request, new CallOptions(headers, deadline, cancellationToken));
+        return SayHello(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Sends a greeting
+      /// Sends a greeting
       /// </summary>
-      public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, CallOptions options)
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_SayHello, null, options, request);
       }
       /// <summary>
-      ///  Sends a greeting
+      /// Sends a greeting
       /// </summary>
-      public virtual AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return SayHelloAsync(request, new CallOptions(headers, deadline, cancellationToken));
+        return SayHelloAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Sends a greeting
+      /// Sends a greeting
       /// </summary>
-      public virtual AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, CallOptions options)
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_SayHello, null, options, request);
       }
+      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
       protected override GreeterClient NewInstance(ClientBaseConfiguration configuration)
       {
         return new GreeterClient(configuration);
@@ -132,9 +152,10 @@ namespace Helloworld {
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
-    public static ServerServiceDefinition BindService(GreeterBase serviceImpl)
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+    public static grpc::ServerServiceDefinition BindService(GreeterBase serviceImpl)
     {
-      return ServerServiceDefinition.CreateBuilder()
+      return grpc::ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build();
     }
 
diff --git a/examples/csharp/helloworld-from-cli/Greeter/project.json b/examples/csharp/helloworld-from-cli/Greeter/project.json
deleted file mode 100644
index 72254ce73e9b3e65f22d22441bdd81fb39de6a88..0000000000000000000000000000000000000000
--- a/examples/csharp/helloworld-from-cli/Greeter/project.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "title": "Greeter",
-  "version": "1.0.0-*",
-  "buildOptions": {
-    "debugType": "portable",
-  },
-  "dependencies": {
-    "Google.Protobuf": "3.0.0",
-    "Grpc": "1.0.1",
-  },
-  "frameworks": {
-    "net45": {
-      "frameworkAssemblies": {
-        "System.Runtime": "",
-        "System.IO": ""
-      },
-      "dependencies": {
-	"Microsoft.NETCore.Platforms": "1.0.1" 
-      }
-    },
-    "netcoreapp1.0": {
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.1"
-        }
-      },
-      "imports": "dnxcore50"
-    }
-  }
-}
diff --git a/examples/csharp/helloworld-from-cli/GreeterClient/GreeterClient.csproj b/examples/csharp/helloworld-from-cli/GreeterClient/GreeterClient.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..24cacfc0219c77991c04d84e8fb59c98c89fd615
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/GreeterClient/GreeterClient.csproj
@@ -0,0 +1,17 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <AssemblyTitle>GreeterClient</AssemblyTitle>
+    <TargetFrameworks>netcoreapp1.0</TargetFrameworks>
+    <DebugType>portable</DebugType>
+    <AssemblyName>GreeterClient</AssemblyName>
+    <OutputType>Exe</OutputType>
+    <PackageId>GreeterClient</PackageId>
+    <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Greeter\Greeter.csproj" />
+  </ItemGroup>
+
+</Project>
diff --git a/examples/csharp/helloworld-from-cli/GreeterClient/project.json b/examples/csharp/helloworld-from-cli/GreeterClient/project.json
deleted file mode 100644
index 09e156f68e8f3103f587f5b8b822e54feaf68566..0000000000000000000000000000000000000000
--- a/examples/csharp/helloworld-from-cli/GreeterClient/project.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
-  "title": "GreeterClient",
-  "version": "1.0.0-*",
-  "buildOptions": {
-    "debugType": "portable",
-    "emitEntryPoint": "true"
-  },
-  "dependencies": {
-    "Google.Protobuf": "3.0.0",
-    "Grpc": "1.0.1",
-    "Greeter": {
-      "target": "project"
-    }
-  },
-  "frameworks": {
-    "net45": {
-      "frameworkAssemblies": {
-        "System.Runtime": "",
-        "System.IO": ""
-      },
-      "dependencies": {
-	"Microsoft.NETCore.Platforms": "1.0.1" 
-      }
-    },
-    "netcoreapp1.0": {
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.1"
-        }
-      },
-      "imports": "dnxcore50"
-    }
-  }
-}
diff --git a/examples/csharp/helloworld-from-cli/GreeterServer/GreeterServer.csproj b/examples/csharp/helloworld-from-cli/GreeterServer/GreeterServer.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..f7980fa7283a415586a222775f8ff1812d35d3d6
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/GreeterServer/GreeterServer.csproj
@@ -0,0 +1,17 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <AssemblyTitle>GreeterServer</AssemblyTitle>
+    <TargetFrameworks>netcoreapp1.0</TargetFrameworks>
+    <DebugType>portable</DebugType>
+    <AssemblyName>GreeterServer</AssemblyName>
+    <OutputType>Exe</OutputType>
+    <PackageId>GreeterServer</PackageId>
+    <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Greeter\Greeter.csproj" />
+  </ItemGroup>
+
+</Project>
diff --git a/examples/csharp/helloworld-from-cli/GreeterServer/project.json b/examples/csharp/helloworld-from-cli/GreeterServer/project.json
deleted file mode 100644
index 8802fe32657843089e2f6bb4b2a6f71d32d2ed65..0000000000000000000000000000000000000000
--- a/examples/csharp/helloworld-from-cli/GreeterServer/project.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
-  "title": "GreeterServer",
-  "version": "1.0.0-*",
-  "buildOptions": {
-    "debugType": "portable",
-    "emitEntryPoint": "true"
-  },
-  "dependencies": {
-    "Google.Protobuf": "3.0.0",
-    "Grpc": "1.0.1",
-    "Greeter": {
-      "target": "project"
-    }
-  },
-  "frameworks": {
-    "net45": {
-      "frameworkAssemblies": {
-        "System.Runtime": "",
-        "System.IO": ""
-      },
-      "dependencies": {
-	"Microsoft.NETCore.Platforms": "1.0.1" 
-      }
-    },
-    "netcoreapp1.0": {
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.1"
-        }
-      },
-      "imports": "dnxcore50"
-    }
-  }
-}
diff --git a/examples/csharp/helloworld-from-cli/README.md b/examples/csharp/helloworld-from-cli/README.md
index 4db077631d876b0344c4c8eedb56527aef099860..c8f8149f73aed48162854f52582ad36b09735277 100644
--- a/examples/csharp/helloworld-from-cli/README.md
+++ b/examples/csharp/helloworld-from-cli/README.md
@@ -12,26 +12,19 @@ Example projects in this directory depend on the [Grpc](https://www.nuget.org/pa
 and [Google.Protobuf](https://www.nuget.org/packages/Google.Protobuf/) NuGet packages
 which have been already added to the project for you.
 
-The examples in this directory target .NET 4.5 framework, as .NET Core support is
-currently experimental.
-
 PREREQUISITES
 -------------
 
-- The DotNetCore SDK cli.
-
-- The .NET 4.5 framework.
-
-Both are available to download at https://www.microsoft.com/net/download
+- The [.NET Core SDK](https://www.microsoft.com/net/core).
 
 BUILD
 -------
 
 From the `examples/csharp/helloworld-from-cli` directory:
 
-- `dotnet restore`
+- `dotnet restore Greeter.sln`
 
-- `dotnet build **/project.json` (this will automatically download NuGet dependencies)
+- `dotnet build Greeter.sln`
 
 Try it!
 -------
@@ -40,14 +33,14 @@ Try it!
 
   ```
   > cd GreeterServer
-  > dotnet run
+  > dotnet run -f netcoreapp1.0
   ```
 
 - Run the client
 
   ```
   > cd GreeterClient
-  > dotnet run
+  > dotnet run -f netcoreapp1.0
   ```
 
 Tutorial
diff --git a/examples/csharp/helloworld-from-cli/generate_protos.bat b/examples/csharp/helloworld-from-cli/generate_protos.bat
new file mode 100644
index 0000000000000000000000000000000000000000..0a35b70e088912ca89b045e0424192b8421e33cb
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/generate_protos.bat
@@ -0,0 +1,42 @@
+@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 Generate the C# code for .proto files
+
+setlocal
+
+@rem enter this directory
+cd /d %~dp0
+
+set PROTOC=%UserProfile%\.nuget\packages\Google.Protobuf.Tools\3.2.0\tools\windows_x64\protoc.exe
+set PLUGIN=%UserProfile%\.nuget\packages\Grpc.Tools\1.2.2\tools\windows_x64\grpc_csharp_plugin.exe
+
+%PROTOC% -I../../protos --csharp_out Greeter  ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%PLUGIN%
+
+endlocal
diff --git a/examples/csharp/helloworld/Greeter/Greeter.csproj b/examples/csharp/helloworld/Greeter/Greeter.csproj
index 036e6b59fbcfce1854206e191ad37d76e5b692b0..8dcd2d906669984fcd455b2041b7a0d648af2201 100644
--- a/examples/csharp/helloworld/Greeter/Greeter.csproj
+++ b/examples/csharp/helloworld/Greeter/Greeter.csproj
@@ -10,7 +10,8 @@
     <RootNamespace>Greeter</RootNamespace>
     <AssemblyName>Greeter</AssemblyName>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <NuGetPackageImportStamp>2669b4f2</NuGetPackageImportStamp>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -31,18 +32,18 @@
     <ConsolePause>false</ConsolePause>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
+    <Reference Include="Google.Protobuf, Version=3.2.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Protobuf.3.2.0\lib\net45\Google.Protobuf.dll</HintPath>
+      <Private>True</Private>
     </Reference>
-    <Reference Include="Grpc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.1.0.1\lib\net45\Grpc.Core.dll</HintPath>
+    <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+      <HintPath>..\packages\Grpc.Core.1.2.2\lib\net45\Grpc.Core.dll</HintPath>
+      <Private>True</Private>
     </Reference>
     <Reference Include="System" />
-    <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
+    <Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
+      <Private>True</Private>
     </Reference>
   </ItemGroup>
   <ItemGroup>
@@ -61,11 +62,11 @@
     <None Include="packages.config" />
   </ItemGroup>
   <ItemGroup />
-  <Import Project="..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.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>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use 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.Core.1.0.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets'))" />
   </Target>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/examples/csharp/helloworld/Greeter/Helloworld.cs b/examples/csharp/helloworld/Greeter/Helloworld.cs
index 6477b4f35be82ac49c60d2c9c661533143d56a06..ecfc8e131cb98059244d6bd0ca4cdc25cf276c47 100644
--- a/examples/csharp/helloworld/Greeter/Helloworld.cs
+++ b/examples/csharp/helloworld/Greeter/Helloworld.cs
@@ -10,7 +10,6 @@ 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 HelloworldReflection {
 
     #region Descriptor
@@ -41,31 +40,36 @@ namespace Helloworld {
   }
   #region Messages
   /// <summary>
-  ///  The request message containing the user's name.
+  /// 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());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<HelloRequest> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HelloRequest() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HelloRequest(HelloRequest other) : this() {
       name_ = other.name_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HelloRequest Clone() {
       return new HelloRequest(this);
     }
@@ -73,6 +77,7 @@ namespace Helloworld {
     /// <summary>Field number for the "name" field.</summary>
     public const int NameFieldNumber = 1;
     private string name_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Name {
       get { return name_; }
       set {
@@ -80,10 +85,12 @@ namespace Helloworld {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as HelloRequest);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(HelloRequest other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -95,16 +102,19 @@ namespace Helloworld {
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Name.Length != 0) hash ^= Name.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Name.Length != 0) {
         output.WriteRawTag(10);
@@ -112,6 +122,7 @@ namespace Helloworld {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Name.Length != 0) {
@@ -120,6 +131,7 @@ namespace Helloworld {
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(HelloRequest other) {
       if (other == null) {
         return;
@@ -129,6 +141,7 @@ namespace Helloworld {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -147,31 +160,36 @@ namespace Helloworld {
   }
 
   /// <summary>
-  ///  The response message containing the greetings
+  /// 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());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<HelloReply> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HelloReply() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HelloReply(HelloReply other) : this() {
       message_ = other.message_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HelloReply Clone() {
       return new HelloReply(this);
     }
@@ -179,6 +197,7 @@ namespace Helloworld {
     /// <summary>Field number for the "message" field.</summary>
     public const int MessageFieldNumber = 1;
     private string message_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Message {
       get { return message_; }
       set {
@@ -186,10 +205,12 @@ namespace Helloworld {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as HelloReply);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(HelloReply other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -201,16 +222,19 @@ namespace Helloworld {
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Message.Length != 0) hash ^= Message.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Message.Length != 0) {
         output.WriteRawTag(10);
@@ -218,6 +242,7 @@ namespace Helloworld {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Message.Length != 0) {
@@ -226,6 +251,7 @@ namespace Helloworld {
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(HelloReply other) {
       if (other == null) {
         return;
@@ -235,6 +261,7 @@ namespace Helloworld {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
diff --git a/examples/csharp/helloworld/Greeter/HelloworldGrpc.cs b/examples/csharp/helloworld/Greeter/HelloworldGrpc.cs
index 041f5a78d758f9d4e3653ff013ea77a4a4f36415..b321ea9e682b79be3063e7a28ea535f9103176dc 100644
--- a/examples/csharp/helloworld/Greeter/HelloworldGrpc.cs
+++ b/examples/csharp/helloworld/Greeter/HelloworldGrpc.cs
@@ -35,21 +35,21 @@
 using System;
 using System.Threading;
 using System.Threading.Tasks;
-using Grpc.Core;
+using grpc = global::Grpc.Core;
 
 namespace Helloworld {
   /// <summary>
-  ///  The greeting service definition.
+  /// The greeting service definition.
   /// </summary>
-  public static class Greeter
+  public static partial class Greeter
   {
     static readonly string __ServiceName = "helloworld.Greeter";
 
-    static readonly Marshaller<global::Helloworld.HelloRequest> __Marshaller_HelloRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom);
-    static readonly Marshaller<global::Helloworld.HelloReply> __Marshaller_HelloReply = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Helloworld.HelloRequest> __Marshaller_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Helloworld.HelloReply> __Marshaller_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom);
 
-    static readonly Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>(
-        MethodType.Unary,
+    static readonly grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>(
+        grpc::MethodType.Unary,
         __ServiceName,
         "SayHello",
         __Marshaller_HelloRequest,
@@ -62,29 +62,32 @@ namespace Helloworld {
     }
 
     /// <summary>Base class for server-side implementations of Greeter</summary>
-    public abstract class GreeterBase
+    public abstract partial class GreeterBase
     {
       /// <summary>
-      ///  Sends a greeting
+      /// Sends a greeting
       /// </summary>
-      public virtual global::System.Threading.Tasks.Task<global::Helloworld.HelloReply> SayHello(global::Helloworld.HelloRequest request, ServerCallContext context)
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Helloworld.HelloReply> SayHello(global::Helloworld.HelloRequest request, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
     }
 
     /// <summary>Client for Greeter</summary>
-    public class GreeterClient : ClientBase<GreeterClient>
+    public partial class GreeterClient : grpc::ClientBase<GreeterClient>
     {
       /// <summary>Creates a new client for Greeter</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
-      public GreeterClient(Channel channel) : base(channel)
+      public GreeterClient(grpc::Channel channel) : base(channel)
       {
       }
       /// <summary>Creates a new client for Greeter that uses a custom <c>CallInvoker</c>.</summary>
       /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
-      public GreeterClient(CallInvoker callInvoker) : base(callInvoker)
+      public GreeterClient(grpc::CallInvoker callInvoker) : base(callInvoker)
       {
       }
       /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
@@ -98,33 +101,50 @@ namespace Helloworld {
       }
 
       /// <summary>
-      ///  Sends a greeting
+      /// Sends a greeting
       /// </summary>
-      public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return SayHello(request, new CallOptions(headers, deadline, cancellationToken));
+        return SayHello(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Sends a greeting
+      /// Sends a greeting
       /// </summary>
-      public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, CallOptions options)
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_SayHello, null, options, request);
       }
       /// <summary>
-      ///  Sends a greeting
+      /// Sends a greeting
       /// </summary>
-      public virtual AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return SayHelloAsync(request, new CallOptions(headers, deadline, cancellationToken));
+        return SayHelloAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Sends a greeting
+      /// Sends a greeting
       /// </summary>
-      public virtual AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, CallOptions options)
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_SayHello, null, options, request);
       }
+      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
       protected override GreeterClient NewInstance(ClientBaseConfiguration configuration)
       {
         return new GreeterClient(configuration);
@@ -132,9 +152,10 @@ namespace Helloworld {
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
-    public static ServerServiceDefinition BindService(GreeterBase serviceImpl)
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+    public static grpc::ServerServiceDefinition BindService(GreeterBase serviceImpl)
     {
-      return ServerServiceDefinition.CreateBuilder()
+      return grpc::ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build();
     }
 
diff --git a/examples/csharp/helloworld/Greeter/packages.config b/examples/csharp/helloworld/Greeter/packages.config
index 2bb3a182a660b1b20c03a9e4be930586ec3bb58b..ec83cd8300290b3dc22ba8ecaaec18818fba12e7 100644
--- a/examples/csharp/helloworld/Greeter/packages.config
+++ b/examples/csharp/helloworld/Greeter/packages.config
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="Grpc" version="1.0.1" targetFramework="net45" />
-  <package id="Grpc.Core" version="1.0.1" targetFramework="net45" />
-  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
-  <package id="Grpc.Tools" version="1.0.1" targetFramework="net45" />
-</packages>
+  <package id="Google.Protobuf" version="3.2.0" targetFramework="net45" />
+  <package id="Grpc" version="1.2.2" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.2.2" targetFramework="net45" />
+  <package id="Grpc.Tools" version="1.2.2" targetFramework="net45" />
+  <package id="System.Interactive.Async" version="3.1.1" 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 639ac0e70ca00c0b22b80fc1f649f46f9e22c49f..4b6b1b3e12bc201d2b97a6053532f3d9c620c8e2 100644
--- a/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj
+++ b/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj
@@ -10,7 +10,8 @@
     <RootNamespace>GreeterClient</RootNamespace>
     <AssemblyName>GreeterClient</AssemblyName>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <NuGetPackageImportStamp>5e942a7d</NuGetPackageImportStamp>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -31,18 +32,18 @@
     <Externalconsole>true</Externalconsole>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
+    <Reference Include="Google.Protobuf, Version=3.2.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Protobuf.3.2.0\lib\net45\Google.Protobuf.dll</HintPath>
+      <Private>True</Private>
     </Reference>
-    <Reference Include="Grpc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.1.0.1\lib\net45\Grpc.Core.dll</HintPath>
+    <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+      <HintPath>..\packages\Grpc.Core.1.2.2\lib\net45\Grpc.Core.dll</HintPath>
+      <Private>True</Private>
     </Reference>
     <Reference Include="System" />
-    <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
+    <Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
+      <Private>True</Private>
     </Reference>
   </ItemGroup>
   <ItemGroup>
@@ -59,11 +60,11 @@
   <ItemGroup>
     <None Include="packages.config" />
   </ItemGroup>
-  <Import Project="..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.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>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use 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.Core.1.0.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets'))" />
   </Target>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/examples/csharp/helloworld/GreeterClient/packages.config b/examples/csharp/helloworld/GreeterClient/packages.config
index addcae0f17317f727c4361dae91641a7d90c6dc0..b912fd4958069df97e26ac28264cacb5f68a7de6 100644
--- a/examples/csharp/helloworld/GreeterClient/packages.config
+++ b/examples/csharp/helloworld/GreeterClient/packages.config
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="Grpc" version="1.0.1" targetFramework="net45" />
-  <package id="Grpc.Core" version="1.0.1" targetFramework="net45" />
-  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
-</packages>
+  <package id="Google.Protobuf" version="3.2.0" targetFramework="net45" />
+  <package id="Grpc" version="1.2.2" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.2.2" targetFramework="net45" />
+  <package id="System.Interactive.Async" version="3.1.1" 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 aa7188839c5d57050984f9471ce883f16b2c732d..97978fa7acec627a581bffa0fcd14e455b305297 100644
--- a/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj
+++ b/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj
@@ -10,7 +10,8 @@
     <RootNamespace>GreeterServer</RootNamespace>
     <AssemblyName>GreeterServer</AssemblyName>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <NuGetPackageImportStamp>9c7b2963</NuGetPackageImportStamp>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -31,18 +32,18 @@
     <Externalconsole>true</Externalconsole>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
+    <Reference Include="Google.Protobuf, Version=3.2.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Protobuf.3.2.0\lib\net45\Google.Protobuf.dll</HintPath>
+      <Private>True</Private>
     </Reference>
-    <Reference Include="Grpc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.1.0.1\lib\net45\Grpc.Core.dll</HintPath>
+    <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+      <HintPath>..\packages\Grpc.Core.1.2.2\lib\net45\Grpc.Core.dll</HintPath>
+      <Private>True</Private>
     </Reference>
     <Reference Include="System" />
-    <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
+    <Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
+      <Private>True</Private>
     </Reference>
   </ItemGroup>
   <ItemGroup>
@@ -59,11 +60,11 @@
   <ItemGroup>
     <None Include="packages.config" />
   </ItemGroup>
-  <Import Project="..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.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>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use 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.Core.1.0.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets'))" />
   </Target>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/examples/csharp/helloworld/GreeterServer/packages.config b/examples/csharp/helloworld/GreeterServer/packages.config
index addcae0f17317f727c4361dae91641a7d90c6dc0..b912fd4958069df97e26ac28264cacb5f68a7de6 100644
--- a/examples/csharp/helloworld/GreeterServer/packages.config
+++ b/examples/csharp/helloworld/GreeterServer/packages.config
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="Grpc" version="1.0.1" targetFramework="net45" />
-  <package id="Grpc.Core" version="1.0.1" targetFramework="net45" />
-  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
-</packages>
+  <package id="Google.Protobuf" version="3.2.0" targetFramework="net45" />
+  <package id="Grpc" version="1.2.2" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.2.2" targetFramework="net45" />
+  <package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
+</packages>
\ No newline at end of file
diff --git a/examples/csharp/helloworld/generate_protos.bat b/examples/csharp/helloworld/generate_protos.bat
index 0afa1297621b9ececb3f2be722685ab78c18f273..0d6e92d50f97afccc1afb4569d0a20b70a2898e5 100644
--- a/examples/csharp/helloworld/generate_protos.bat
+++ b/examples/csharp/helloworld/generate_protos.bat
@@ -34,7 +34,7 @@ setlocal
 @rem enter this directory
 cd /d %~dp0
 
-set TOOLS_PATH=packages\Grpc.Tools.1.0.1\tools\windows_x86
+set TOOLS_PATH=packages\Grpc.Tools.1.2.2\tools\windows_x86
 
 %TOOLS_PATH%\protoc.exe -I../../protos --csharp_out Greeter  ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe
 
diff --git a/examples/csharp/route_guide/README.md b/examples/csharp/route_guide/README.md
index a9aa87a83dff4669cf32cd8c19e9ba8fc5160d7b..98073b0296342f54590b29704c521455fe43492f 100644
--- a/examples/csharp/route_guide/README.md
+++ b/examples/csharp/route_guide/README.md
@@ -1,4 +1,4 @@
-#gRPC Basics: C# sample code
+# gRPC Basics: C# sample code
 
 The files in this folder are the samples used in [gRPC Basics: C#][],
 a detailed tutorial for using gRPC in C#.
diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuide.cs b/examples/csharp/route_guide/RouteGuide/RouteGuide.cs
index 54cb823983e13dc9ac11dc1092a5ab9a7761f680..603809ee76ff7d1c39bdbef9caa53a078c2d3390 100644
--- a/examples/csharp/route_guide/RouteGuide/RouteGuide.cs
+++ b/examples/csharp/route_guide/RouteGuide/RouteGuide.cs
@@ -53,10 +53,10 @@ namespace Routeguide {
   }
   #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).
+  /// 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>
   public sealed partial class Point : pb::IMessage<Point> {
     private static readonly pb::MessageParser<Point> _parser = new pb::MessageParser<Point>(() => new Point());
@@ -204,8 +204,8 @@ namespace Routeguide {
   }
 
   /// <summary>
-  ///  A latitude-longitude rectangle, represented as two diagonally opposite
-  ///  points "lo" and "hi".
+  /// A latitude-longitude rectangle, represented as two diagonally opposite
+  /// points "lo" and "hi".
   /// </summary>
   public sealed partial class Rectangle : pb::IMessage<Rectangle> {
     private static readonly pb::MessageParser<Rectangle> _parser = new pb::MessageParser<Rectangle>(() => new Rectangle());
@@ -244,7 +244,7 @@ namespace Routeguide {
     public const int LoFieldNumber = 1;
     private global::Routeguide.Point lo_;
     /// <summary>
-    ///  One corner of the rectangle.
+    /// One corner of the rectangle.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Routeguide.Point Lo {
@@ -258,7 +258,7 @@ namespace Routeguide {
     public const int HiFieldNumber = 2;
     private global::Routeguide.Point hi_;
     /// <summary>
-    ///  The other corner of the rectangle.
+    /// The other corner of the rectangle.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Routeguide.Point Hi {
@@ -371,9 +371,9 @@ namespace Routeguide {
   }
 
   /// <summary>
-  ///  A feature names something at a given point.
+  /// A feature names something at a given point.
   ///
-  ///  If a feature could not be named, the name is empty.
+  /// If a feature could not be named, the name is empty.
   /// </summary>
   public sealed partial class Feature : pb::IMessage<Feature> {
     private static readonly pb::MessageParser<Feature> _parser = new pb::MessageParser<Feature>(() => new Feature());
@@ -412,7 +412,7 @@ namespace Routeguide {
     public const int NameFieldNumber = 1;
     private string name_ = "";
     /// <summary>
-    ///  The name of the feature.
+    /// The name of the feature.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Name {
@@ -426,7 +426,7 @@ namespace Routeguide {
     public const int LocationFieldNumber = 2;
     private global::Routeguide.Point location_;
     /// <summary>
-    ///  The point where the feature is detected.
+    /// The point where the feature is detected.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Routeguide.Point Location {
@@ -533,7 +533,7 @@ namespace Routeguide {
   }
 
   /// <summary>
-  ///  A RouteNote is a message sent while at a given point.
+  /// A RouteNote is a message sent while at a given point.
   /// </summary>
   public sealed partial class RouteNote : pb::IMessage<RouteNote> {
     private static readonly pb::MessageParser<RouteNote> _parser = new pb::MessageParser<RouteNote>(() => new RouteNote());
@@ -572,7 +572,7 @@ namespace Routeguide {
     public const int LocationFieldNumber = 1;
     private global::Routeguide.Point location_;
     /// <summary>
-    ///  The location from which the message is sent.
+    /// The location from which the message is sent.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Routeguide.Point Location {
@@ -586,7 +586,7 @@ namespace Routeguide {
     public const int MessageFieldNumber = 2;
     private string message_ = "";
     /// <summary>
-    ///  The message to be sent.
+    /// The message to be sent.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Message {
@@ -693,11 +693,11 @@ namespace Routeguide {
   }
 
   /// <summary>
-  ///  A RouteSummary is received in response to a RecordRoute rpc.
+  /// 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.
+  /// 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>
   public sealed partial class RouteSummary : pb::IMessage<RouteSummary> {
     private static readonly pb::MessageParser<RouteSummary> _parser = new pb::MessageParser<RouteSummary>(() => new RouteSummary());
@@ -738,7 +738,7 @@ namespace Routeguide {
     public const int PointCountFieldNumber = 1;
     private int pointCount_;
     /// <summary>
-    ///  The number of points received.
+    /// The number of points received.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int PointCount {
@@ -752,7 +752,7 @@ namespace Routeguide {
     public const int FeatureCountFieldNumber = 2;
     private int featureCount_;
     /// <summary>
-    ///  The number of known features passed while traversing the route.
+    /// The number of known features passed while traversing the route.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FeatureCount {
@@ -766,7 +766,7 @@ namespace Routeguide {
     public const int DistanceFieldNumber = 3;
     private int distance_;
     /// <summary>
-    ///  The distance covered in metres.
+    /// The distance covered in metres.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Distance {
@@ -780,7 +780,7 @@ namespace Routeguide {
     public const int ElapsedTimeFieldNumber = 4;
     private int elapsedTime_;
     /// <summary>
-    ///  The duration of the traversal in seconds.
+    /// The duration of the traversal in seconds.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int ElapsedTime {
diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj
index eee8f0a1bcee1bc63907d02bbf43b05ea346b254..360444e491826bb9c8de55dbb8713291c541cf34 100644
--- a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj
+++ b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj
@@ -11,7 +11,8 @@
     <AssemblyName>RouteGuide</AssemblyName>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
-    <NuGetPackageImportStamp>de2137f9</NuGetPackageImportStamp>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -31,13 +32,13 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
+    <Reference Include="Google.Protobuf, Version=3.2.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Protobuf.3.2.0\lib\net45\Google.Protobuf.dll</HintPath>
+      <Private>True</Private>
     </Reference>
-    <Reference Include="Grpc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.1.0.1\lib\net45\Grpc.Core.dll</HintPath>
+    <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+      <HintPath>..\packages\Grpc.Core.1.2.2\lib\net45\Grpc.Core.dll</HintPath>
+      <Private>True</Private>
     </Reference>
     <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -45,15 +46,15 @@
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
+    <Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Data" />
     <Reference Include="System.Xml" />
-    <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
-    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Properties\AssemblyInfo.cs" />
@@ -74,12 +75,12 @@
     </None>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.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>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use 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.Core.1.0.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets'))" />
   </Target>
   <!-- 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.
@@ -88,4 +89,4 @@
   <Target Name="AfterBuild">
   </Target>
   -->
-</Project>
+</Project>
\ No newline at end of file
diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs b/examples/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs
index eb70c8e2db5b81cce75a8f1314261f87a0790e86..6f2d6bde6204b5b39dd7b1f9ff358179d7de9be5 100644
--- a/examples/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs
+++ b/examples/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs
@@ -35,45 +35,45 @@
 using System;
 using System.Threading;
 using System.Threading.Tasks;
-using Grpc.Core;
+using grpc = global::Grpc.Core;
 
 namespace Routeguide {
   /// <summary>
-  ///  Interface exported by the server.
+  /// Interface exported by the server.
   /// </summary>
-  public static class RouteGuide
+  public static partial class RouteGuide
   {
     static readonly string __ServiceName = "routeguide.RouteGuide";
 
-    static readonly Marshaller<global::Routeguide.Point> __Marshaller_Point = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Point.Parser.ParseFrom);
-    static readonly Marshaller<global::Routeguide.Feature> __Marshaller_Feature = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Feature.Parser.ParseFrom);
-    static readonly Marshaller<global::Routeguide.Rectangle> __Marshaller_Rectangle = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Rectangle.Parser.ParseFrom);
-    static readonly Marshaller<global::Routeguide.RouteSummary> __Marshaller_RouteSummary = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteSummary.Parser.ParseFrom);
-    static readonly Marshaller<global::Routeguide.RouteNote> __Marshaller_RouteNote = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteNote.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Routeguide.Point> __Marshaller_Point = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Point.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Routeguide.Feature> __Marshaller_Feature = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Feature.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Routeguide.Rectangle> __Marshaller_Rectangle = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Rectangle.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Routeguide.RouteSummary> __Marshaller_RouteSummary = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteSummary.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Routeguide.RouteNote> __Marshaller_RouteNote = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteNote.Parser.ParseFrom);
 
-    static readonly Method<global::Routeguide.Point, global::Routeguide.Feature> __Method_GetFeature = new Method<global::Routeguide.Point, global::Routeguide.Feature>(
-        MethodType.Unary,
+    static readonly grpc::Method<global::Routeguide.Point, global::Routeguide.Feature> __Method_GetFeature = new grpc::Method<global::Routeguide.Point, global::Routeguide.Feature>(
+        grpc::MethodType.Unary,
         __ServiceName,
         "GetFeature",
         __Marshaller_Point,
         __Marshaller_Feature);
 
-    static readonly Method<global::Routeguide.Rectangle, global::Routeguide.Feature> __Method_ListFeatures = new Method<global::Routeguide.Rectangle, global::Routeguide.Feature>(
-        MethodType.ServerStreaming,
+    static readonly grpc::Method<global::Routeguide.Rectangle, global::Routeguide.Feature> __Method_ListFeatures = new grpc::Method<global::Routeguide.Rectangle, global::Routeguide.Feature>(
+        grpc::MethodType.ServerStreaming,
         __ServiceName,
         "ListFeatures",
         __Marshaller_Rectangle,
         __Marshaller_Feature);
 
-    static readonly Method<global::Routeguide.Point, global::Routeguide.RouteSummary> __Method_RecordRoute = new Method<global::Routeguide.Point, global::Routeguide.RouteSummary>(
-        MethodType.ClientStreaming,
+    static readonly grpc::Method<global::Routeguide.Point, global::Routeguide.RouteSummary> __Method_RecordRoute = new grpc::Method<global::Routeguide.Point, global::Routeguide.RouteSummary>(
+        grpc::MethodType.ClientStreaming,
         __ServiceName,
         "RecordRoute",
         __Marshaller_Point,
         __Marshaller_RouteSummary);
 
-    static readonly Method<global::Routeguide.RouteNote, global::Routeguide.RouteNote> __Method_RouteChat = new Method<global::Routeguide.RouteNote, global::Routeguide.RouteNote>(
-        MethodType.DuplexStreaming,
+    static readonly grpc::Method<global::Routeguide.RouteNote, global::Routeguide.RouteNote> __Method_RouteChat = new grpc::Method<global::Routeguide.RouteNote, global::Routeguide.RouteNote>(
+        grpc::MethodType.DuplexStreaming,
         __ServiceName,
         "RouteChat",
         __Marshaller_RouteNote,
@@ -86,69 +86,83 @@ namespace Routeguide {
     }
 
     /// <summary>Base class for server-side implementations of RouteGuide</summary>
-    public abstract class RouteGuideBase
+    public abstract partial class RouteGuideBase
     {
       /// <summary>
-      ///  A simple RPC.
+      /// A simple RPC.
       ///
-      ///  Obtains the feature at a given position.
+      /// Obtains the feature at a given position.
       ///
-      ///  A feature with an empty name is returned if there's no feature at the given
-      ///  position.
+      /// A feature with an empty name is returned if there's no feature at the given
+      /// position.
       /// </summary>
-      public virtual global::System.Threading.Tasks.Task<global::Routeguide.Feature> GetFeature(global::Routeguide.Point request, ServerCallContext context)
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Routeguide.Feature> GetFeature(global::Routeguide.Point request, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
-      ///  A server-to-client streaming RPC.
+      /// A server-to-client streaming RPC.
       ///
-      ///  Obtains the Features available within the given Rectangle.  Results are
-      ///  streamed rather than returned at once (e.g. in a response message with a
-      ///  repeated field), as the rectangle may cover a large area and contain a
-      ///  huge number of features.
+      /// Obtains the Features available within the given Rectangle.  Results are
+      /// streamed rather than returned at once (e.g. in a response message with a
+      /// repeated field), as the rectangle may cover a large area and contain a
+      /// huge number of features.
       /// </summary>
-      public virtual global::System.Threading.Tasks.Task ListFeatures(global::Routeguide.Rectangle request, IServerStreamWriter<global::Routeguide.Feature> responseStream, ServerCallContext context)
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
+      public virtual global::System.Threading.Tasks.Task ListFeatures(global::Routeguide.Rectangle request, grpc::IServerStreamWriter<global::Routeguide.Feature> responseStream, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
-      ///  A client-to-server streaming RPC.
+      /// A client-to-server streaming RPC.
       ///
-      ///  Accepts a stream of Points on a route being traversed, returning a
-      ///  RouteSummary when traversal is completed.
+      /// Accepts a stream of Points on a route being traversed, returning a
+      /// RouteSummary when traversal is completed.
       /// </summary>
-      public virtual global::System.Threading.Tasks.Task<global::Routeguide.RouteSummary> RecordRoute(IAsyncStreamReader<global::Routeguide.Point> requestStream, ServerCallContext context)
+      /// <param name="requestStream">Used for reading requests from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Routeguide.RouteSummary> RecordRoute(grpc::IAsyncStreamReader<global::Routeguide.Point> requestStream, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
-      ///  A Bidirectional streaming RPC.
+      /// A Bidirectional streaming RPC.
       ///
-      ///  Accepts a stream of RouteNotes sent while a route is being traversed,
-      ///  while receiving other RouteNotes (e.g. from other users).
+      /// Accepts a stream of RouteNotes sent while a route is being traversed,
+      /// while receiving other RouteNotes (e.g. from other users).
       /// </summary>
-      public virtual global::System.Threading.Tasks.Task RouteChat(IAsyncStreamReader<global::Routeguide.RouteNote> requestStream, IServerStreamWriter<global::Routeguide.RouteNote> responseStream, ServerCallContext context)
+      /// <param name="requestStream">Used for reading requests from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
+      public virtual global::System.Threading.Tasks.Task RouteChat(grpc::IAsyncStreamReader<global::Routeguide.RouteNote> requestStream, grpc::IServerStreamWriter<global::Routeguide.RouteNote> responseStream, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
     }
 
     /// <summary>Client for RouteGuide</summary>
-    public class RouteGuideClient : ClientBase<RouteGuideClient>
+    public partial class RouteGuideClient : grpc::ClientBase<RouteGuideClient>
     {
       /// <summary>Creates a new client for RouteGuide</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
-      public RouteGuideClient(Channel channel) : base(channel)
+      public RouteGuideClient(grpc::Channel channel) : base(channel)
       {
       }
       /// <summary>Creates a new client for RouteGuide that uses a custom <c>CallInvoker</c>.</summary>
       /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
-      public RouteGuideClient(CallInvoker callInvoker) : base(callInvoker)
+      public RouteGuideClient(grpc::CallInvoker callInvoker) : base(callInvoker)
       {
       }
       /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
@@ -162,117 +176,154 @@ namespace Routeguide {
       }
 
       /// <summary>
-      ///  A simple RPC.
+      /// A simple RPC.
       ///
-      ///  Obtains the feature at a given position.
+      /// Obtains the feature at a given position.
       ///
-      ///  A feature with an empty name is returned if there's no feature at the given
-      ///  position.
+      /// A feature with an empty name is returned if there's no feature at the given
+      /// position.
       /// </summary>
-      public virtual global::Routeguide.Feature GetFeature(global::Routeguide.Point request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Routeguide.Feature GetFeature(global::Routeguide.Point request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return GetFeature(request, new CallOptions(headers, deadline, cancellationToken));
+        return GetFeature(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  A simple RPC.
+      /// A simple RPC.
       ///
-      ///  Obtains the feature at a given position.
+      /// Obtains the feature at a given position.
       ///
-      ///  A feature with an empty name is returned if there's no feature at the given
-      ///  position.
+      /// A feature with an empty name is returned if there's no feature at the given
+      /// position.
       /// </summary>
-      public virtual global::Routeguide.Feature GetFeature(global::Routeguide.Point request, CallOptions options)
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Routeguide.Feature GetFeature(global::Routeguide.Point request, grpc::CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_GetFeature, null, options, request);
       }
       /// <summary>
-      ///  A simple RPC.
+      /// A simple RPC.
       ///
-      ///  Obtains the feature at a given position.
+      /// Obtains the feature at a given position.
       ///
-      ///  A feature with an empty name is returned if there's no feature at the given
-      ///  position.
+      /// A feature with an empty name is returned if there's no feature at the given
+      /// position.
       /// </summary>
-      public virtual AsyncUnaryCall<global::Routeguide.Feature> GetFeatureAsync(global::Routeguide.Point request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Routeguide.Feature> GetFeatureAsync(global::Routeguide.Point request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return GetFeatureAsync(request, new CallOptions(headers, deadline, cancellationToken));
+        return GetFeatureAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  A simple RPC.
+      /// A simple RPC.
       ///
-      ///  Obtains the feature at a given position.
+      /// Obtains the feature at a given position.
       ///
-      ///  A feature with an empty name is returned if there's no feature at the given
-      ///  position.
+      /// A feature with an empty name is returned if there's no feature at the given
+      /// position.
       /// </summary>
-      public virtual AsyncUnaryCall<global::Routeguide.Feature> GetFeatureAsync(global::Routeguide.Point request, CallOptions options)
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Routeguide.Feature> GetFeatureAsync(global::Routeguide.Point request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_GetFeature, null, options, request);
       }
       /// <summary>
-      ///  A server-to-client streaming RPC.
+      /// A server-to-client streaming RPC.
       ///
-      ///  Obtains the Features available within the given Rectangle.  Results are
-      ///  streamed rather than returned at once (e.g. in a response message with a
-      ///  repeated field), as the rectangle may cover a large area and contain a
-      ///  huge number of features.
+      /// Obtains the Features available within the given Rectangle.  Results are
+      /// streamed rather than returned at once (e.g. in a response message with a
+      /// repeated field), as the rectangle may cover a large area and contain a
+      /// huge number of features.
       /// </summary>
-      public virtual AsyncServerStreamingCall<global::Routeguide.Feature> ListFeatures(global::Routeguide.Rectangle request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncServerStreamingCall<global::Routeguide.Feature> ListFeatures(global::Routeguide.Rectangle request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return ListFeatures(request, new CallOptions(headers, deadline, cancellationToken));
+        return ListFeatures(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  A server-to-client streaming RPC.
+      /// A server-to-client streaming RPC.
       ///
-      ///  Obtains the Features available within the given Rectangle.  Results are
-      ///  streamed rather than returned at once (e.g. in a response message with a
-      ///  repeated field), as the rectangle may cover a large area and contain a
-      ///  huge number of features.
+      /// Obtains the Features available within the given Rectangle.  Results are
+      /// streamed rather than returned at once (e.g. in a response message with a
+      /// repeated field), as the rectangle may cover a large area and contain a
+      /// huge number of features.
       /// </summary>
-      public virtual AsyncServerStreamingCall<global::Routeguide.Feature> ListFeatures(global::Routeguide.Rectangle request, CallOptions options)
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncServerStreamingCall<global::Routeguide.Feature> ListFeatures(global::Routeguide.Rectangle request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncServerStreamingCall(__Method_ListFeatures, null, options, request);
       }
       /// <summary>
-      ///  A client-to-server streaming RPC.
+      /// A client-to-server streaming RPC.
       ///
-      ///  Accepts a stream of Points on a route being traversed, returning a
-      ///  RouteSummary when traversal is completed.
+      /// Accepts a stream of Points on a route being traversed, returning a
+      /// RouteSummary when traversal is completed.
       /// </summary>
-      public virtual AsyncClientStreamingCall<global::Routeguide.Point, global::Routeguide.RouteSummary> RecordRoute(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncClientStreamingCall<global::Routeguide.Point, global::Routeguide.RouteSummary> RecordRoute(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return RecordRoute(new CallOptions(headers, deadline, cancellationToken));
+        return RecordRoute(new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  A client-to-server streaming RPC.
+      /// A client-to-server streaming RPC.
       ///
-      ///  Accepts a stream of Points on a route being traversed, returning a
-      ///  RouteSummary when traversal is completed.
+      /// Accepts a stream of Points on a route being traversed, returning a
+      /// RouteSummary when traversal is completed.
       /// </summary>
-      public virtual AsyncClientStreamingCall<global::Routeguide.Point, global::Routeguide.RouteSummary> RecordRoute(CallOptions options)
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncClientStreamingCall<global::Routeguide.Point, global::Routeguide.RouteSummary> RecordRoute(grpc::CallOptions options)
       {
         return CallInvoker.AsyncClientStreamingCall(__Method_RecordRoute, null, options);
       }
       /// <summary>
-      ///  A Bidirectional streaming RPC.
+      /// A Bidirectional streaming RPC.
       ///
-      ///  Accepts a stream of RouteNotes sent while a route is being traversed,
-      ///  while receiving other RouteNotes (e.g. from other users).
+      /// Accepts a stream of RouteNotes sent while a route is being traversed,
+      /// while receiving other RouteNotes (e.g. from other users).
       /// </summary>
-      public virtual AsyncDuplexStreamingCall<global::Routeguide.RouteNote, global::Routeguide.RouteNote> RouteChat(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncDuplexStreamingCall<global::Routeguide.RouteNote, global::Routeguide.RouteNote> RouteChat(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return RouteChat(new CallOptions(headers, deadline, cancellationToken));
+        return RouteChat(new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  A Bidirectional streaming RPC.
+      /// A Bidirectional streaming RPC.
       ///
-      ///  Accepts a stream of RouteNotes sent while a route is being traversed,
-      ///  while receiving other RouteNotes (e.g. from other users).
+      /// Accepts a stream of RouteNotes sent while a route is being traversed,
+      /// while receiving other RouteNotes (e.g. from other users).
       /// </summary>
-      public virtual AsyncDuplexStreamingCall<global::Routeguide.RouteNote, global::Routeguide.RouteNote> RouteChat(CallOptions options)
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncDuplexStreamingCall<global::Routeguide.RouteNote, global::Routeguide.RouteNote> RouteChat(grpc::CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_RouteChat, null, options);
       }
+      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
       protected override RouteGuideClient NewInstance(ClientBaseConfiguration configuration)
       {
         return new RouteGuideClient(configuration);
@@ -280,9 +331,10 @@ namespace Routeguide {
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
-    public static ServerServiceDefinition BindService(RouteGuideBase serviceImpl)
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+    public static grpc::ServerServiceDefinition BindService(RouteGuideBase serviceImpl)
     {
-      return ServerServiceDefinition.CreateBuilder()
+      return grpc::ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_GetFeature, serviceImpl.GetFeature)
           .AddMethod(__Method_ListFeatures, serviceImpl.ListFeatures)
           .AddMethod(__Method_RecordRoute, serviceImpl.RecordRoute)
diff --git a/examples/csharp/route_guide/RouteGuide/packages.config b/examples/csharp/route_guide/RouteGuide/packages.config
index b7c401b3c85140ca5c8c98f9ad83053a6ff2e56a..2dde11f1dd3f45b81904f7918c32f651c752de0e 100644
--- a/examples/csharp/route_guide/RouteGuide/packages.config
+++ b/examples/csharp/route_guide/RouteGuide/packages.config
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="Grpc" version="1.0.1" targetFramework="net45" />
-  <package id="Grpc.Core" version="1.0.1" targetFramework="net45" />
-  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.2.0" targetFramework="net45" />
+  <package id="Grpc" version="1.2.2" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.2.2" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
-</packages>
+  <package id="System.Interactive.Async" version="3.1.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 a513f6af877b60b87f9f228ed693be826e210266..162eaeddc13f323e742a9f5a49715a5f6e60951a 100644
--- a/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
+++ b/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
@@ -11,7 +11,8 @@
     <AssemblyName>RouteGuideClient</AssemblyName>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
-    <NuGetPackageImportStamp>b880049a</NuGetPackageImportStamp>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -33,13 +34,13 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
+    <Reference Include="Google.Protobuf, Version=3.2.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Protobuf.3.2.0\lib\net45\Google.Protobuf.dll</HintPath>
+      <Private>True</Private>
     </Reference>
-    <Reference Include="Grpc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.1.0.1\lib\net45\Grpc.Core.dll</HintPath>
+    <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+      <HintPath>..\packages\Grpc.Core.1.2.2\lib\net45\Grpc.Core.dll</HintPath>
+      <Private>True</Private>
     </Reference>
     <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -47,9 +48,9 @@
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
-    <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
+    <Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
+      <Private>True</Private>
     </Reference>
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
@@ -71,12 +72,12 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.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>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use 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.Core.1.0.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets'))" />
   </Target>
   <!-- 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.
@@ -85,4 +86,4 @@
   <Target Name="AfterBuild">
   </Target>
   -->
-</Project>
+</Project>
\ No newline at end of file
diff --git a/examples/csharp/route_guide/RouteGuideClient/packages.config b/examples/csharp/route_guide/RouteGuideClient/packages.config
index b7c401b3c85140ca5c8c98f9ad83053a6ff2e56a..2dde11f1dd3f45b81904f7918c32f651c752de0e 100644
--- a/examples/csharp/route_guide/RouteGuideClient/packages.config
+++ b/examples/csharp/route_guide/RouteGuideClient/packages.config
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="Grpc" version="1.0.1" targetFramework="net45" />
-  <package id="Grpc.Core" version="1.0.1" targetFramework="net45" />
-  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.2.0" targetFramework="net45" />
+  <package id="Grpc" version="1.2.2" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.2.2" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
-</packages>
+  <package id="System.Interactive.Async" version="3.1.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 8892554b7edc4df8f1612794d5ecf1f32b0e5e3b..b6f2f351aaa2383213560cfa874de0a14af75290 100644
--- a/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
+++ b/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
@@ -11,7 +11,8 @@
     <AssemblyName>RouteGuideServer</AssemblyName>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
-    <NuGetPackageImportStamp>946ecc79</NuGetPackageImportStamp>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -33,13 +34,13 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
+    <Reference Include="Google.Protobuf, Version=3.2.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Protobuf.3.2.0\lib\net45\Google.Protobuf.dll</HintPath>
+      <Private>True</Private>
     </Reference>
-    <Reference Include="Grpc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.1.0.1\lib\net45\Grpc.Core.dll</HintPath>
+    <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+      <HintPath>..\packages\Grpc.Core.1.2.2\lib\net45\Grpc.Core.dll</HintPath>
+      <Private>True</Private>
     </Reference>
     <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -47,15 +48,15 @@
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
+    <Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Data" />
     <Reference Include="System.Xml" />
-    <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
-    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Program.cs" />
@@ -72,12 +73,12 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.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>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use 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.Core.1.0.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.2.2\build\net45\Grpc.Core.targets'))" />
   </Target>
   <!-- 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.
@@ -86,4 +87,4 @@
   <Target Name="AfterBuild">
   </Target>
   -->
-</Project>
+</Project>
\ No newline at end of file
diff --git a/examples/csharp/route_guide/RouteGuideServer/packages.config b/examples/csharp/route_guide/RouteGuideServer/packages.config
index dd498f48ea34ac16a98c78ee5aa73067a2d4ea5c..46df6453da63d59fd9dfcd55aa576532a17b72e0 100644
--- a/examples/csharp/route_guide/RouteGuideServer/packages.config
+++ b/examples/csharp/route_guide/RouteGuideServer/packages.config
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="Grpc" version="1.0.1" targetFramework="net45" />
-  <package id="Grpc.Core" version="1.0.1" targetFramework="net45" />
-  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.2.0" targetFramework="net45" />
+  <package id="Grpc" version="1.2.2" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.2.2" targetFramework="net45" />
+  <package id="Grpc.Tools" version="1.2.2" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
-  <package id="Grpc.Tools" version="1.0.1" targetFramework="net45" />
-</packages>
+  <package id="System.Interactive.Async" version="3.1.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 69f5e0f4a397d44212ce8594fb2129b8bd7771fd..fbd951aeb278d4f54859caa4301044e5fcceb8e3 100644
--- a/examples/csharp/route_guide/generate_protos.bat
+++ b/examples/csharp/route_guide/generate_protos.bat
@@ -34,7 +34,7 @@ setlocal
 @rem enter this directory
 cd /d %~dp0
 
-set TOOLS_PATH=packages\Grpc.Tools.1.0.0\tools\windows_x86
+set TOOLS_PATH=packages\Grpc.Tools.1.2.2\tools\windows_x86
 
 %TOOLS_PATH%\protoc.exe -I../../protos --csharp_out RouteGuide  ../../protos/route_guide.proto --grpc_out RouteGuide --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe
 
diff --git a/examples/node/dynamic_codegen/route_guide/README.md b/examples/node/dynamic_codegen/route_guide/README.md
index 22bcf789863df05d58b03b5cc1cf19ed3a32bf7e..7ec519c76bbeefdf8a69a2f6c4f1e30e0d6c9051 100644
--- a/examples/node/dynamic_codegen/route_guide/README.md
+++ b/examples/node/dynamic_codegen/route_guide/README.md
@@ -1,4 +1,4 @@
-#gRPC Basics: Node.js sample code
+# gRPC Basics: Node.js sample code
 
 The files in this folder are the samples used in [gRPC Basics: Node.js][], a detailed tutorial for using gRPC in Node.js.
 
diff --git a/examples/node/static_codegen/README.md b/examples/node/static_codegen/README.md
index fc97d34a3868a449ef35bace323af4a9d434ce06..0441b27f25a65f3b5d410bfe9841e6ee060e13c4 100644
--- a/examples/node/static_codegen/README.md
+++ b/examples/node/static_codegen/README.md
@@ -1,7 +1,8 @@
-This is the static code generation variant of the Node examples. Code in these examples is pre-generated using protoc and the Node gRPC protoc plugin, and the generated code can be found in various `*_pb.js` files. The command line sequence for generating those files is as follows (assuming that `protoc` and `grpc_node_plugin` are present, and starting in the base directory of this package):
+This is the static code generation variant of the Node examples. Code in these examples is pre-generated using protoc and the Node gRPC protoc plugin, and the generated code can be found in various `*_pb.js` files. The command line sequence for generating those files is as follows (assuming that `protoc` and `grpc_node_plugin` are present, and starting in the directory which contains this README.md file):
 
 ```sh
-cd ../protos
-protoc --js_out=import_style=commonjs,binary:../node/static_codegen/ --grpc_out=../node/static_codegen --plugin=protoc-gen-grpc=grpc_node_plugin helloworld.proto
-protoc --js_out=import_style=commonjs,binary:../node/static_codegen/route_guide/ --grpc_out=../node/static_codegen/route_guide/ --plugin=protoc-gen-grpc=grpc_node_plugin route_guide.proto
+cd ../../protos
+npm install -g grpc-tools
+grpc_tools_node_protoc --js_out=import_style=commonjs,binary:../node/static_codegen/ --grpc_out=../node/static_codegen --plugin=protoc-gen-grpc=`which grpc_tools_node_protoc_plugin` helloworld.proto
+grpc_tools_node_protoc --js_out=import_style=commonjs,binary:../node/static_codegen/route_guide/ --grpc_out=../node/static_codegen/route_guide/ --plugin=protoc-gen-grpc=`which grpc_tools_node_protoc_plugin` route_guide.proto
 ```
diff --git a/examples/node/static_codegen/route_guide/README.md b/examples/node/static_codegen/route_guide/README.md
index 22bcf789863df05d58b03b5cc1cf19ed3a32bf7e..7ec519c76bbeefdf8a69a2f6c4f1e30e0d6c9051 100644
--- a/examples/node/static_codegen/route_guide/README.md
+++ b/examples/node/static_codegen/route_guide/README.md
@@ -1,4 +1,4 @@
-#gRPC Basics: Node.js sample code
+# gRPC Basics: Node.js sample code
 
 The files in this folder are the samples used in [gRPC Basics: Node.js][], a detailed tutorial for using gRPC in Node.js.
 
diff --git a/examples/objective-c/auth_sample/README.md b/examples/objective-c/auth_sample/README.md
index c560b7af65bc7055dde078842da46d9ba0b52a91..b75dcab2de42f8bada45155a974903082de1fd2d 100644
--- a/examples/objective-c/auth_sample/README.md
+++ b/examples/objective-c/auth_sample/README.md
@@ -1,3 +1,3 @@
-#OAuth2 on gRPC: Objective-C
+# OAuth2 on gRPC: Objective-C
 
 This is the supporting code for the tutorial "[OAuth2 on gRPC: Objective-C](http://www.grpc.io/docs/tutorials/auth/oauth2-objective-c.html)."
diff --git a/examples/objective-c/helloworld/README.md b/examples/objective-c/helloworld/README.md
index fdff938a9784ff617e9c4b167b2fe450f1a80f97..365bea1422823e0180fd7631c0868908145b5f84 100644
--- a/examples/objective-c/helloworld/README.md
+++ b/examples/objective-c/helloworld/README.md
@@ -1,4 +1,4 @@
-#gRPC in 3 minutes (Objective-C)
+# gRPC in 3 minutes (Objective-C)
 
 ## Installation
 
diff --git a/examples/objective-c/route_guide/README.md b/examples/objective-c/route_guide/README.md
index 6a6f7c0d3388fbb9f149058774efcf28f82fef2c..b99bf546fb72f7e555ecb5f48260074a39695c30 100644
--- a/examples/objective-c/route_guide/README.md
+++ b/examples/objective-c/route_guide/README.md
@@ -1,4 +1,4 @@
-#gRPC Basics: Objective-C
+# gRPC Basics: Objective-C
 
 This is the supporting code for the tutorial "[gRPC Basics: Objective-C](http://www.grpc.io/docs/tutorials/basic/objective-c.html)."
 
diff --git a/examples/php/route_guide/README.md b/examples/php/route_guide/README.md
index 26f1704f122cc1a9b8488d3a88130060c0e861e6..5b2cc05efc7c8db660023b744dd058c9ec1494bf 100644
--- a/examples/php/route_guide/README.md
+++ b/examples/php/route_guide/README.md
@@ -1,4 +1,4 @@
-#gRPC Basics: PHP sample code
+# gRPC Basics: PHP sample code
 
 The files in this folder are the samples used in [gRPC Basics: PHP][],
 a detailed tutorial for using gRPC in PHP.
diff --git a/examples/ruby/errors_and_cancellation/README.md b/examples/ruby/errors_and_cancellation/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..661bd84792f625c50cd2bd2e4ad482c1ae0b611b
--- /dev/null
+++ b/examples/ruby/errors_and_cancellation/README.md
@@ -0,0 +1,25 @@
+# Errors and Cancelletion code samples for grpc-ruby
+
+The examples in this directory show use of grpc errors.
+
+On the server side, errors are returned from service
+implementations by raising a certain `GRPC::BadStatus` exception.
+
+On the client side, GRPC errors get raised when either:
+ * the call completes (unary and client-streaming call types)
+ * the response `Enumerable` is iterated through (server-streaming and
+   bidi call types).
+
+## To run the examples here:
+
+Start the server:
+
+```
+> ruby error_examples_server.rb
+```
+
+Then run the client:
+
+```
+> ruby error_examples_client.rb
+```
diff --git a/examples/ruby/errors_and_cancellation/error_examples_client.rb b/examples/ruby/errors_and_cancellation/error_examples_client.rb
new file mode 100755
index 0000000000000000000000000000000000000000..90456d066d7b347bb341b3e78d5ef7c4cb3ff049
--- /dev/null
+++ b/examples/ruby/errors_and_cancellation/error_examples_client.rb
@@ -0,0 +1,117 @@
+#!/usr/bin/env ruby
+
+# 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.
+
+# Sample app that connects to an error-throwing implementation of
+# Route Guide service.
+#
+# Usage: $ path/to/route_guide_client.rb
+
+this_dir = File.expand_path(File.dirname(__FILE__))
+lib_dir = File.join(File.dirname(this_dir), 'lib')
+$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
+
+require 'grpc'
+require 'route_guide_services_pb'
+
+include Routeguide
+
+def run_get_feature_expect_error(stub)
+  resp = stub.get_feature(Point.new)
+end
+
+def run_list_features_expect_error(stub)
+  resps = stub.list_features(Rectangle.new)
+
+  # NOOP iteration to pick up error
+  resps.each { }
+end
+
+def run_record_route_expect_error(stub)
+  stub.record_route([])
+end
+
+def run_route_chat_expect_error(stub)
+  resps = stub.route_chat([])
+
+  # NOOP iteration to pick up error
+  resps.each { }
+end
+
+def main
+  stub = RouteGuide::Stub.new('localhost:50051', :this_channel_is_insecure)
+
+  begin
+    run_get_feature_expect_error(stub)
+  rescue GRPC::BadStatus => e
+    puts "===== GetFeature exception: ====="
+    puts e.inspect
+    puts "e.code: #{e.code}"
+    puts "e.details: #{e.details}"
+    puts "e.metadata: #{e.metadata}"
+    puts "================================="
+  end
+
+  begin
+    run_list_features_expect_error(stub)
+  rescue GRPC::BadStatus => e
+    error = true
+    puts "===== ListFeatures exception: ====="
+    puts e.inspect
+    puts "e.code: #{e.code}"
+    puts "e.details: #{e.details}"
+    puts "e.metadata: #{e.metadata}"
+    puts "================================="
+  end
+
+  begin
+    run_route_chat_expect_error(stub)
+  rescue GRPC::BadStatus => e
+    puts "==== RouteChat exception: ===="
+    puts e.inspect
+    puts "e.code: #{e.code}"
+    puts "e.details: #{e.details}"
+    puts "e.metadata: #{e.metadata}"
+    puts "================================="
+  end
+
+  begin
+    run_record_route_expect_error(stub)
+  rescue GRPC::BadStatus => e
+    puts "==== RecordRoute exception: ===="
+    puts e.inspect
+    puts "e.code: #{e.code}"
+    puts "e.details: #{e.details}"
+    puts "e.metadata: #{e.metadata}"
+    puts "================================="
+  end
+end
+
+main
diff --git a/examples/ruby/errors_and_cancellation/error_examples_server.rb b/examples/ruby/errors_and_cancellation/error_examples_server.rb
new file mode 100755
index 0000000000000000000000000000000000000000..66751882d91fd4ca545fbc889ba4528ef9f0231d
--- /dev/null
+++ b/examples/ruby/errors_and_cancellation/error_examples_server.rb
@@ -0,0 +1,76 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+
+# 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.
+
+# Error-throwing implementation of Route Guide service.
+#
+# Usage: $ path/to/route_guide_server.rb
+
+this_dir = File.expand_path(File.dirname(__FILE__))
+lib_dir = File.join(File.dirname(this_dir), 'lib')
+$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
+
+require 'grpc'
+require 'route_guide_services_pb'
+
+include Routeguide
+
+include GRPC::Core::StatusCodes
+
+# CanellingandErrorReturningServiceImpl provides an implementation of the RouteGuide service.
+class CancellingAndErrorReturningServerImpl < RouteGuide::Service
+  # def get_feature
+  #   Note get_feature isn't implemented in this subclass, so the server
+  #   will get a gRPC UNIMPLEMENTED error when it's called.
+
+  def list_features(rectangle, _call)
+    raise "string appears on the client in the 'details' field of a 'GRPC::Unknown' exception"
+  end
+
+  def record_route(call)
+    raise GRPC::BadStatus.new_status_exception(CANCELLED)
+  end
+
+  def route_chat(notes)
+    raise GRPC::BadStatus.new_status_exception(ABORTED, details = 'arbitrary', metadata = {somekey: 'val'})
+  end
+end
+
+def main
+  port = '0.0.0.0:50051'
+  s = GRPC::RpcServer.new
+  s.add_http2_port(port, :this_port_is_insecure)
+  GRPC.logger.info("... running insecurely on #{port}")
+  s.handle(CancellingAndErrorReturningServerImpl.new)
+  s.run_till_terminated
+end
+
+main
diff --git a/examples/ruby/route_guide/README.md b/examples/ruby/route_guide/README.md
index 3c353d1d976a200e3e5de686781289ebe869b12c..b2514630a966e92959182261bea568f3b31cb14b 100644
--- a/examples/ruby/route_guide/README.md
+++ b/examples/ruby/route_guide/README.md
@@ -1,4 +1,4 @@
-#gRPC Basics: Ruby sample code
+# gRPC Basics: Ruby sample code
 
 The files in this folder are the samples used in [gRPC Basics: Ruby][],
 a detailed tutorial for using gRPC in Ruby.
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 909ea5af96727411767020e141f9e5f88532d3cd..241eba01dd2fca36cbca4c14268f369196079dae 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -37,7 +37,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-Core'
-  version = '1.2.0-dev'
+  version = '1.4.0-dev'
   s.version  = version
   s.summary  = 'Core cross-platform gRPC library, written in C'
   s.homepage = 'http://www.grpc.io'
@@ -51,7 +51,7 @@ Pod::Spec.new do |s|
     :submodules => true,
   }
 
-  s.ios.deployment_target = '7.1'
+  s.ios.deployment_target = '7.0'
   s.osx.deployment_target = '10.9'
   s.requires_arc = false
 
@@ -104,6 +104,7 @@ Pod::Spec.new do |s|
   }
 
   s.default_subspecs = 'Interface', 'Implementation'
+  s.compiler_flags = '-DGRPC_ARES=0'
 
   # Like many other C libraries, gRPC-Core has its public headers under `include/<libname>/` and its
   # sources and private headers in other directories outside `include/`. Cocoapods' linter doesn't
@@ -151,7 +152,6 @@ Pod::Spec.new do |s|
                       'include/grpc/impl/codegen/gpr_slice.h',
                       'include/grpc/impl/codegen/gpr_types.h',
                       'include/grpc/impl/codegen/port_platform.h',
-                      'include/grpc/impl/codegen/slice.h',
                       'include/grpc/impl/codegen/sync.h',
                       'include/grpc/impl/codegen/sync_generic.h',
                       'include/grpc/impl/codegen/sync_posix.h',
@@ -172,6 +172,7 @@ Pod::Spec.new do |s|
                       'include/grpc/impl/codegen/exec_ctx_fwd.h',
                       'include/grpc/impl/codegen/grpc_types.h',
                       'include/grpc/impl/codegen/propagation_bits.h',
+                      'include/grpc/impl/codegen/slice.h',
                       'include/grpc/impl/codegen/status.h',
                       'include/grpc/impl/codegen/atm.h',
                       'include/grpc/impl/codegen/atm_gcc_atomic.h',
@@ -180,7 +181,6 @@ Pod::Spec.new do |s|
                       'include/grpc/impl/codegen/gpr_slice.h',
                       'include/grpc/impl/codegen/gpr_types.h',
                       'include/grpc/impl/codegen/port_platform.h',
-                      'include/grpc/impl/codegen/slice.h',
                       'include/grpc/impl/codegen/sync.h',
                       'include/grpc/impl/codegen/sync_generic.h',
                       'include/grpc/impl/codegen/sync_posix.h',
@@ -196,9 +196,14 @@ Pod::Spec.new do |s|
 
     # To save you from scrolling, this is the last part of the podspec.
     ss.source_files = 'src/core/lib/profiling/timers.h',
+                      'src/core/lib/support/arena.h',
+                      'src/core/lib/support/atomic.h',
+                      'src/core/lib/support/atomic_with_atm.h',
+                      'src/core/lib/support/atomic_with_std.h',
                       'src/core/lib/support/backoff.h',
                       'src/core/lib/support/block_annotate.h',
                       'src/core/lib/support/env.h',
+                      'src/core/lib/support/memory.h',
                       'src/core/lib/support/mpscq.h',
                       'src/core/lib/support/murmur_hash.h',
                       'src/core/lib/support/spinlock.h',
@@ -211,6 +216,8 @@ Pod::Spec.new do |s|
                       'src/core/lib/profiling/basic_timers.c',
                       'src/core/lib/profiling/stap_timers.c',
                       'src/core/lib/support/alloc.c',
+                      'src/core/lib/support/arena.c',
+                      'src/core/lib/support/atm.c',
                       'src/core/lib/support/avl.c',
                       'src/core/lib/support/backoff.c',
                       'src/core/lib/support/cmdline.c',
@@ -255,16 +262,11 @@ Pod::Spec.new do |s|
                       'src/core/lib/channel/channel_args.h',
                       'src/core/lib/channel/channel_stack.h',
                       'src/core/lib/channel/channel_stack_builder.h',
-                      'src/core/lib/channel/compress_filter.h',
                       'src/core/lib/channel/connected_channel.h',
                       'src/core/lib/channel/context.h',
-                      'src/core/lib/channel/deadline_filter.h',
                       'src/core/lib/channel/handshaker.h',
                       'src/core/lib/channel/handshaker_factory.h',
                       'src/core/lib/channel/handshaker_registry.h',
-                      'src/core/lib/channel/http_client_filter.h',
-                      'src/core/lib/channel/http_server_filter.h',
-                      'src/core/lib/channel/message_size_filter.h',
                       'src/core/lib/compression/algorithm_metadata.h',
                       'src/core/lib/compression/message_compress.h',
                       'src/core/lib/debug/trace.h',
@@ -287,6 +289,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/iomgr/iomgr_internal.h',
                       'src/core/lib/iomgr/iomgr_posix.h',
                       'src/core/lib/iomgr/load_file.h',
+                      'src/core/lib/iomgr/lockfree_event.h',
                       'src/core/lib/iomgr/network_status_tracker.h',
                       'src/core/lib/iomgr/polling_entity.h',
                       'src/core/lib/iomgr/pollset.h',
@@ -301,6 +304,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/iomgr/sockaddr_posix.h',
                       'src/core/lib/iomgr/sockaddr_utils.h',
                       'src/core/lib/iomgr/sockaddr_windows.h',
+                      'src/core/lib/iomgr/socket_factory_posix.h',
                       'src/core/lib/iomgr/socket_mutator.h',
                       'src/core/lib/iomgr/socket_utils.h',
                       'src/core/lib/iomgr/socket_utils_posix.h',
@@ -309,6 +313,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/iomgr/tcp_client_posix.h',
                       'src/core/lib/iomgr/tcp_posix.h',
                       'src/core/lib/iomgr/tcp_server.h',
+                      'src/core/lib/iomgr/tcp_server_utils_posix.h',
                       'src/core/lib/iomgr/tcp_uv.h',
                       'src/core/lib/iomgr/tcp_windows.h',
                       'src/core/lib/iomgr/time_averaged_stats.h',
@@ -328,6 +333,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/json/json_common.h',
                       'src/core/lib/json/json_reader.h',
                       'src/core/lib/json/json_writer.h',
+                      'src/core/lib/slice/b64.h',
                       'src/core/lib/slice/percent_encoding.h',
                       'src/core/lib/slice/slice_hash_table.h',
                       'src/core/lib/slice/slice_internal.h',
@@ -339,6 +345,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/surface/channel_init.h',
                       'src/core/lib/surface/channel_stack_type.h',
                       'src/core/lib/surface/completion_queue.h',
+                      'src/core/lib/surface/completion_queue_factory.h',
                       'src/core/lib/surface/event_string.h',
                       'src/core/lib/surface/init.h',
                       'src/core/lib/surface/lame_client.h',
@@ -371,12 +378,16 @@ Pod::Spec.new do |s|
                       'src/core/ext/transport/chttp2/transport/hpack_encoder.h',
                       'src/core/ext/transport/chttp2/transport/hpack_parser.h',
                       'src/core/ext/transport/chttp2/transport/hpack_table.h',
+                      'src/core/ext/transport/chttp2/transport/http2_settings.h',
                       'src/core/ext/transport/chttp2/transport/huffsyms.h',
                       'src/core/ext/transport/chttp2/transport/incoming_metadata.h',
                       'src/core/ext/transport/chttp2/transport/internal.h',
                       'src/core/ext/transport/chttp2/transport/stream_map.h',
                       'src/core/ext/transport/chttp2/transport/varint.h',
                       'src/core/ext/transport/chttp2/alpn/alpn.h',
+                      'src/core/ext/filters/http/client/http_client_filter.h',
+                      'src/core/ext/filters/http/message_compress/message_compress_filter.h',
+                      'src/core/ext/filters/http/server/http_server_filter.h',
                       'src/core/lib/security/context/security_context.h',
                       'src/core/lib/security/credentials/composite/composite_credentials.h',
                       'src/core/lib/security/credentials/credentials.h',
@@ -395,43 +406,48 @@ Pod::Spec.new do |s|
                       'src/core/lib/security/transport/security_connector.h',
                       'src/core/lib/security/transport/security_handshaker.h',
                       'src/core/lib/security/transport/tsi_error.h',
-                      'src/core/lib/security/util/b64.h',
                       'src/core/lib/security/util/json_util.h',
-                      'src/core/lib/tsi/fake_transport_security.h',
-                      'src/core/lib/tsi/ssl_transport_security.h',
-                      'src/core/lib/tsi/ssl_types.h',
-                      'src/core/lib/tsi/transport_security.h',
-                      'src/core/lib/tsi/transport_security_interface.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_adapter.h',
+                      'src/core/tsi/transport_security_interface.h',
                       'src/core/ext/transport/chttp2/server/chttp2_server.h',
-                      'src/core/ext/client_channel/client_channel.h',
-                      'src/core/ext/client_channel/client_channel_factory.h',
-                      'src/core/ext/client_channel/connector.h',
-                      'src/core/ext/client_channel/http_connect_handshaker.h',
-                      'src/core/ext/client_channel/http_proxy.h',
-                      'src/core/ext/client_channel/initial_connect_string.h',
-                      'src/core/ext/client_channel/lb_policy.h',
-                      'src/core/ext/client_channel/lb_policy_factory.h',
-                      'src/core/ext/client_channel/lb_policy_registry.h',
-                      'src/core/ext/client_channel/parse_address.h',
-                      'src/core/ext/client_channel/proxy_mapper.h',
-                      'src/core/ext/client_channel/proxy_mapper_registry.h',
-                      'src/core/ext/client_channel/resolver.h',
-                      'src/core/ext/client_channel/resolver_factory.h',
-                      'src/core/ext/client_channel/resolver_registry.h',
-                      'src/core/ext/client_channel/subchannel.h',
-                      'src/core/ext/client_channel/subchannel_index.h',
-                      'src/core/ext/client_channel/uri_parser.h',
+                      'src/core/ext/filters/client_channel/client_channel.h',
+                      'src/core/ext/filters/client_channel/client_channel_factory.h',
+                      'src/core/ext/filters/client_channel/connector.h',
+                      'src/core/ext/filters/client_channel/http_connect_handshaker.h',
+                      'src/core/ext/filters/client_channel/http_proxy.h',
+                      'src/core/ext/filters/client_channel/lb_policy.h',
+                      'src/core/ext/filters/client_channel/lb_policy_factory.h',
+                      'src/core/ext/filters/client_channel/lb_policy_registry.h',
+                      'src/core/ext/filters/client_channel/parse_address.h',
+                      'src/core/ext/filters/client_channel/proxy_mapper.h',
+                      'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
+                      'src/core/ext/filters/client_channel/resolver.h',
+                      'src/core/ext/filters/client_channel/resolver_factory.h',
+                      'src/core/ext/filters/client_channel/resolver_registry.h',
+                      'src/core/ext/filters/client_channel/retry_throttle.h',
+                      'src/core/ext/filters/client_channel/subchannel.h',
+                      'src/core/ext/filters/client_channel/subchannel_index.h',
+                      'src/core/ext/filters/client_channel/uri_parser.h',
+                      'src/core/ext/filters/deadline/deadline_filter.h',
                       'src/core/ext/transport/chttp2/client/chttp2_connector.h',
-                      'src/core/ext/lb_policy/grpclb/grpclb.h',
-                      'src/core/ext/lb_policy/grpclb/grpclb_channel.h',
-                      'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
-                      'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.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/ext/load_reporting/load_reporting.h',
-                      'src/core/ext/load_reporting/load_reporting_filter.h',
+                      'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
+                      'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
+                      'src/core/ext/filters/load_reporting/load_reporting.h',
+                      'src/core/ext/filters/load_reporting/load_reporting_filter.h',
                       'src/core/ext/census/aggregation.h',
                       'src/core/ext/census/base_resources.h',
                       'src/core/ext/census/census_interface.h',
@@ -448,19 +464,16 @@ Pod::Spec.new do |s|
                       'src/core/ext/census/trace_status.h',
                       'src/core/ext/census/trace_string.h',
                       'src/core/ext/census/tracing.h',
+                      'src/core/ext/filters/max_age/max_age_filter.h',
+                      'src/core/ext/filters/message_size/message_size_filter.h',
                       'src/core/lib/surface/init.c',
                       'src/core/lib/channel/channel_args.c',
                       'src/core/lib/channel/channel_stack.c',
                       'src/core/lib/channel/channel_stack_builder.c',
-                      'src/core/lib/channel/compress_filter.c',
                       'src/core/lib/channel/connected_channel.c',
-                      'src/core/lib/channel/deadline_filter.c',
                       'src/core/lib/channel/handshaker.c',
                       'src/core/lib/channel/handshaker_factory.c',
                       'src/core/lib/channel/handshaker_registry.c',
-                      'src/core/lib/channel/http_client_filter.c',
-                      'src/core/lib/channel/http_server_filter.c',
-                      'src/core/lib/channel/message_size_filter.c',
                       'src/core/lib/compression/compression.c',
                       'src/core/lib/compression/message_compress.c',
                       'src/core/lib/debug/trace.c',
@@ -485,6 +498,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/iomgr/iomgr_uv.c',
                       'src/core/lib/iomgr/iomgr_windows.c',
                       'src/core/lib/iomgr/load_file.c',
+                      'src/core/lib/iomgr/lockfree_event.c',
                       'src/core/lib/iomgr/network_status_tracker.c',
                       'src/core/lib/iomgr/polling_entity.c',
                       'src/core/lib/iomgr/pollset_set_uv.c',
@@ -496,6 +510,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/iomgr/resolve_address_windows.c',
                       'src/core/lib/iomgr/resource_quota.c',
                       'src/core/lib/iomgr/sockaddr_utils.c',
+                      'src/core/lib/iomgr/socket_factory_posix.c',
                       'src/core/lib/iomgr/socket_mutator.c',
                       'src/core/lib/iomgr/socket_utils_common_posix.c',
                       'src/core/lib/iomgr/socket_utils_linux.c',
@@ -508,6 +523,9 @@ Pod::Spec.new do |s|
                       'src/core/lib/iomgr/tcp_client_windows.c',
                       'src/core/lib/iomgr/tcp_posix.c',
                       'src/core/lib/iomgr/tcp_server_posix.c',
+                      'src/core/lib/iomgr/tcp_server_utils_posix_common.c',
+                      'src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c',
+                      'src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c',
                       'src/core/lib/iomgr/tcp_server_uv.c',
                       'src/core/lib/iomgr/tcp_server_windows.c',
                       'src/core/lib/iomgr/tcp_uv.c',
@@ -530,6 +548,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/json/json_reader.c',
                       'src/core/lib/json/json_string.c',
                       'src/core/lib/json/json_writer.c',
+                      'src/core/lib/slice/b64.c',
                       'src/core/lib/slice/percent_encoding.c',
                       'src/core/lib/slice/slice.c',
                       'src/core/lib/slice/slice_buffer.c',
@@ -548,8 +567,9 @@ Pod::Spec.new do |s|
                       'src/core/lib/surface/channel_ping.c',
                       'src/core/lib/surface/channel_stack_type.c',
                       'src/core/lib/surface/completion_queue.c',
+                      'src/core/lib/surface/completion_queue_factory.c',
                       'src/core/lib/surface/event_string.c',
-                      'src/core/lib/surface/lame_client.c',
+                      'src/core/lib/surface/lame_client.cc',
                       'src/core/lib/surface/metadata_array.c',
                       'src/core/lib/surface/server.c',
                       'src/core/lib/surface/validate_metadata.c',
@@ -581,6 +601,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/transport/chttp2/transport/hpack_encoder.c',
                       'src/core/ext/transport/chttp2/transport/hpack_parser.c',
                       'src/core/ext/transport/chttp2/transport/hpack_table.c',
+                      'src/core/ext/transport/chttp2/transport/http2_settings.c',
                       'src/core/ext/transport/chttp2/transport/huffsyms.c',
                       'src/core/ext/transport/chttp2/transport/incoming_metadata.c',
                       'src/core/ext/transport/chttp2/transport/parsing.c',
@@ -589,6 +610,10 @@ Pod::Spec.new do |s|
                       'src/core/ext/transport/chttp2/transport/varint.c',
                       'src/core/ext/transport/chttp2/transport/writing.c',
                       'src/core/ext/transport/chttp2/alpn/alpn.c',
+                      'src/core/ext/filters/http/client/http_client_filter.c',
+                      'src/core/ext/filters/http/http_filters_plugin.c',
+                      'src/core/ext/filters/http/message_compress/message_compress_filter.c',
+                      'src/core/ext/filters/http/server/http_server_filter.c',
                       'src/core/lib/http/httpcli_security_connector.c',
                       'src/core/lib/security/context/security_context.c',
                       'src/core/lib/security/credentials/composite/composite_credentials.c',
@@ -611,53 +636,58 @@ Pod::Spec.new do |s|
                       'src/core/lib/security/transport/security_handshaker.c',
                       'src/core/lib/security/transport/server_auth_filter.c',
                       'src/core/lib/security/transport/tsi_error.c',
-                      'src/core/lib/security/util/b64.c',
                       'src/core/lib/security/util/json_util.c',
                       'src/core/lib/surface/init_secure.c',
-                      'src/core/lib/tsi/fake_transport_security.c',
-                      'src/core/lib/tsi/ssl_transport_security.c',
-                      'src/core/lib/tsi/transport_security.c',
+                      'src/core/tsi/fake_transport_security.c',
+                      'src/core/tsi/ssl_transport_security.c',
+                      'src/core/tsi/transport_security.c',
+                      'src/core/tsi/transport_security_adapter.c',
                       'src/core/ext/transport/chttp2/server/chttp2_server.c',
                       'src/core/ext/transport/chttp2/client/secure/secure_channel_create.c',
-                      'src/core/ext/client_channel/channel_connectivity.c',
-                      'src/core/ext/client_channel/client_channel.c',
-                      'src/core/ext/client_channel/client_channel_factory.c',
-                      'src/core/ext/client_channel/client_channel_plugin.c',
-                      'src/core/ext/client_channel/connector.c',
-                      'src/core/ext/client_channel/default_initial_connect_string.c',
-                      'src/core/ext/client_channel/http_connect_handshaker.c',
-                      'src/core/ext/client_channel/http_proxy.c',
-                      'src/core/ext/client_channel/initial_connect_string.c',
-                      'src/core/ext/client_channel/lb_policy.c',
-                      'src/core/ext/client_channel/lb_policy_factory.c',
-                      'src/core/ext/client_channel/lb_policy_registry.c',
-                      'src/core/ext/client_channel/parse_address.c',
-                      'src/core/ext/client_channel/proxy_mapper.c',
-                      'src/core/ext/client_channel/proxy_mapper_registry.c',
-                      'src/core/ext/client_channel/resolver.c',
-                      'src/core/ext/client_channel/resolver_factory.c',
-                      'src/core/ext/client_channel/resolver_registry.c',
-                      'src/core/ext/client_channel/subchannel.c',
-                      'src/core/ext/client_channel/subchannel_index.c',
-                      'src/core/ext/client_channel/uri_parser.c',
+                      'src/core/ext/filters/client_channel/channel_connectivity.c',
+                      'src/core/ext/filters/client_channel/client_channel.c',
+                      'src/core/ext/filters/client_channel/client_channel_factory.c',
+                      'src/core/ext/filters/client_channel/client_channel_plugin.c',
+                      'src/core/ext/filters/client_channel/connector.c',
+                      'src/core/ext/filters/client_channel/http_connect_handshaker.c',
+                      'src/core/ext/filters/client_channel/http_proxy.c',
+                      'src/core/ext/filters/client_channel/lb_policy.c',
+                      'src/core/ext/filters/client_channel/lb_policy_factory.c',
+                      'src/core/ext/filters/client_channel/lb_policy_registry.c',
+                      'src/core/ext/filters/client_channel/parse_address.c',
+                      'src/core/ext/filters/client_channel/proxy_mapper.c',
+                      'src/core/ext/filters/client_channel/proxy_mapper_registry.c',
+                      'src/core/ext/filters/client_channel/resolver.c',
+                      'src/core/ext/filters/client_channel/resolver_factory.c',
+                      'src/core/ext/filters/client_channel/resolver_registry.c',
+                      'src/core/ext/filters/client_channel/retry_throttle.c',
+                      'src/core/ext/filters/client_channel/subchannel.c',
+                      'src/core/ext/filters/client_channel/subchannel_index.c',
+                      'src/core/ext/filters/client_channel/uri_parser.c',
+                      'src/core/ext/filters/deadline/deadline_filter.c',
                       'src/core/ext/transport/chttp2/client/chttp2_connector.c',
                       'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
                       'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c',
                       'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
                       'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c',
-                      'src/core/ext/lb_policy/grpclb/grpclb.c',
-                      'src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c',
-                      'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
-                      'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c',
+                      'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
                       'third_party/nanopb/pb_common.c',
                       'third_party/nanopb/pb_decode.c',
                       'third_party/nanopb/pb_encode.c',
-                      'src/core/ext/lb_policy/pick_first/pick_first.c',
-                      'src/core/ext/lb_policy/round_robin/round_robin.c',
-                      'src/core/ext/resolver/dns/native/dns_resolver.c',
-                      'src/core/ext/resolver/sockaddr/sockaddr_resolver.c',
-                      'src/core/ext/load_reporting/load_reporting.c',
-                      'src/core/ext/load_reporting/load_reporting_filter.c',
+                      'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c',
+                      'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c',
+                      'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c',
+                      'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c',
+                      'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c',
+                      'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c',
+                      'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c',
+                      'src/core/ext/filters/load_reporting/load_reporting.c',
+                      'src/core/ext/filters/load_reporting/load_reporting_filter.c',
                       'src/core/ext/census/base_resources.c',
                       'src/core/ext/census/context.c',
                       'src/core/ext/census/gen/census.pb.c',
@@ -672,12 +702,19 @@ Pod::Spec.new do |s|
                       'src/core/ext/census/resource.c',
                       'src/core/ext/census/trace_context.c',
                       'src/core/ext/census/tracing.c',
+                      'src/core/ext/filters/max_age/max_age_filter.c',
+                      'src/core/ext/filters/message_size/message_size_filter.c',
                       'src/core/plugin_registry/grpc_plugin_registry.c'
 
     ss.private_header_files = 'src/core/lib/profiling/timers.h',
+                              'src/core/lib/support/arena.h',
+                              'src/core/lib/support/atomic.h',
+                              'src/core/lib/support/atomic_with_atm.h',
+                              'src/core/lib/support/atomic_with_std.h',
                               'src/core/lib/support/backoff.h',
                               'src/core/lib/support/block_annotate.h',
                               'src/core/lib/support/env.h',
+                              'src/core/lib/support/memory.h',
                               'src/core/lib/support/mpscq.h',
                               'src/core/lib/support/murmur_hash.h',
                               'src/core/lib/support/spinlock.h',
@@ -690,16 +727,11 @@ Pod::Spec.new do |s|
                               'src/core/lib/channel/channel_args.h',
                               'src/core/lib/channel/channel_stack.h',
                               'src/core/lib/channel/channel_stack_builder.h',
-                              'src/core/lib/channel/compress_filter.h',
                               'src/core/lib/channel/connected_channel.h',
                               'src/core/lib/channel/context.h',
-                              'src/core/lib/channel/deadline_filter.h',
                               'src/core/lib/channel/handshaker.h',
                               'src/core/lib/channel/handshaker_factory.h',
                               'src/core/lib/channel/handshaker_registry.h',
-                              'src/core/lib/channel/http_client_filter.h',
-                              'src/core/lib/channel/http_server_filter.h',
-                              'src/core/lib/channel/message_size_filter.h',
                               'src/core/lib/compression/algorithm_metadata.h',
                               'src/core/lib/compression/message_compress.h',
                               'src/core/lib/debug/trace.h',
@@ -722,6 +754,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/iomgr/iomgr_internal.h',
                               'src/core/lib/iomgr/iomgr_posix.h',
                               'src/core/lib/iomgr/load_file.h',
+                              'src/core/lib/iomgr/lockfree_event.h',
                               'src/core/lib/iomgr/network_status_tracker.h',
                               'src/core/lib/iomgr/polling_entity.h',
                               'src/core/lib/iomgr/pollset.h',
@@ -736,6 +769,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/iomgr/sockaddr_posix.h',
                               'src/core/lib/iomgr/sockaddr_utils.h',
                               'src/core/lib/iomgr/sockaddr_windows.h',
+                              'src/core/lib/iomgr/socket_factory_posix.h',
                               'src/core/lib/iomgr/socket_mutator.h',
                               'src/core/lib/iomgr/socket_utils.h',
                               'src/core/lib/iomgr/socket_utils_posix.h',
@@ -744,6 +778,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/iomgr/tcp_client_posix.h',
                               'src/core/lib/iomgr/tcp_posix.h',
                               'src/core/lib/iomgr/tcp_server.h',
+                              'src/core/lib/iomgr/tcp_server_utils_posix.h',
                               'src/core/lib/iomgr/tcp_uv.h',
                               'src/core/lib/iomgr/tcp_windows.h',
                               'src/core/lib/iomgr/time_averaged_stats.h',
@@ -763,6 +798,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/json/json_common.h',
                               'src/core/lib/json/json_reader.h',
                               'src/core/lib/json/json_writer.h',
+                              'src/core/lib/slice/b64.h',
                               'src/core/lib/slice/percent_encoding.h',
                               'src/core/lib/slice/slice_hash_table.h',
                               'src/core/lib/slice/slice_internal.h',
@@ -774,6 +810,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/surface/channel_init.h',
                               'src/core/lib/surface/channel_stack_type.h',
                               'src/core/lib/surface/completion_queue.h',
+                              'src/core/lib/surface/completion_queue_factory.h',
                               'src/core/lib/surface/event_string.h',
                               'src/core/lib/surface/init.h',
                               'src/core/lib/surface/lame_client.h',
@@ -806,12 +843,16 @@ Pod::Spec.new do |s|
                               'src/core/ext/transport/chttp2/transport/hpack_encoder.h',
                               'src/core/ext/transport/chttp2/transport/hpack_parser.h',
                               'src/core/ext/transport/chttp2/transport/hpack_table.h',
+                              'src/core/ext/transport/chttp2/transport/http2_settings.h',
                               'src/core/ext/transport/chttp2/transport/huffsyms.h',
                               'src/core/ext/transport/chttp2/transport/incoming_metadata.h',
                               'src/core/ext/transport/chttp2/transport/internal.h',
                               'src/core/ext/transport/chttp2/transport/stream_map.h',
                               'src/core/ext/transport/chttp2/transport/varint.h',
                               'src/core/ext/transport/chttp2/alpn/alpn.h',
+                              'src/core/ext/filters/http/client/http_client_filter.h',
+                              'src/core/ext/filters/http/message_compress/message_compress_filter.h',
+                              'src/core/ext/filters/http/server/http_server_filter.h',
                               'src/core/lib/security/context/security_context.h',
                               'src/core/lib/security/credentials/composite/composite_credentials.h',
                               'src/core/lib/security/credentials/credentials.h',
@@ -830,43 +871,48 @@ Pod::Spec.new do |s|
                               'src/core/lib/security/transport/security_connector.h',
                               'src/core/lib/security/transport/security_handshaker.h',
                               'src/core/lib/security/transport/tsi_error.h',
-                              'src/core/lib/security/util/b64.h',
                               'src/core/lib/security/util/json_util.h',
-                              'src/core/lib/tsi/fake_transport_security.h',
-                              'src/core/lib/tsi/ssl_transport_security.h',
-                              'src/core/lib/tsi/ssl_types.h',
-                              'src/core/lib/tsi/transport_security.h',
-                              'src/core/lib/tsi/transport_security_interface.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_adapter.h',
+                              'src/core/tsi/transport_security_interface.h',
                               'src/core/ext/transport/chttp2/server/chttp2_server.h',
-                              'src/core/ext/client_channel/client_channel.h',
-                              'src/core/ext/client_channel/client_channel_factory.h',
-                              'src/core/ext/client_channel/connector.h',
-                              'src/core/ext/client_channel/http_connect_handshaker.h',
-                              'src/core/ext/client_channel/http_proxy.h',
-                              'src/core/ext/client_channel/initial_connect_string.h',
-                              'src/core/ext/client_channel/lb_policy.h',
-                              'src/core/ext/client_channel/lb_policy_factory.h',
-                              'src/core/ext/client_channel/lb_policy_registry.h',
-                              'src/core/ext/client_channel/parse_address.h',
-                              'src/core/ext/client_channel/proxy_mapper.h',
-                              'src/core/ext/client_channel/proxy_mapper_registry.h',
-                              'src/core/ext/client_channel/resolver.h',
-                              'src/core/ext/client_channel/resolver_factory.h',
-                              'src/core/ext/client_channel/resolver_registry.h',
-                              'src/core/ext/client_channel/subchannel.h',
-                              'src/core/ext/client_channel/subchannel_index.h',
-                              'src/core/ext/client_channel/uri_parser.h',
+                              'src/core/ext/filters/client_channel/client_channel.h',
+                              'src/core/ext/filters/client_channel/client_channel_factory.h',
+                              'src/core/ext/filters/client_channel/connector.h',
+                              'src/core/ext/filters/client_channel/http_connect_handshaker.h',
+                              'src/core/ext/filters/client_channel/http_proxy.h',
+                              'src/core/ext/filters/client_channel/lb_policy.h',
+                              'src/core/ext/filters/client_channel/lb_policy_factory.h',
+                              'src/core/ext/filters/client_channel/lb_policy_registry.h',
+                              'src/core/ext/filters/client_channel/parse_address.h',
+                              'src/core/ext/filters/client_channel/proxy_mapper.h',
+                              'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
+                              'src/core/ext/filters/client_channel/resolver.h',
+                              'src/core/ext/filters/client_channel/resolver_factory.h',
+                              'src/core/ext/filters/client_channel/resolver_registry.h',
+                              'src/core/ext/filters/client_channel/retry_throttle.h',
+                              'src/core/ext/filters/client_channel/subchannel.h',
+                              'src/core/ext/filters/client_channel/subchannel_index.h',
+                              'src/core/ext/filters/client_channel/uri_parser.h',
+                              'src/core/ext/filters/deadline/deadline_filter.h',
                               'src/core/ext/transport/chttp2/client/chttp2_connector.h',
-                              'src/core/ext/lb_policy/grpclb/grpclb.h',
-                              'src/core/ext/lb_policy/grpclb/grpclb_channel.h',
-                              'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
-                              'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
+                              'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h',
+                              'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h',
+                              'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
+                              'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
+                              'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
+                              'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.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/ext/load_reporting/load_reporting.h',
-                              'src/core/ext/load_reporting/load_reporting_filter.h',
+                              'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
+                              'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
+                              'src/core/ext/filters/load_reporting/load_reporting.h',
+                              'src/core/ext/filters/load_reporting/load_reporting_filter.h',
                               'src/core/ext/census/aggregation.h',
                               'src/core/ext/census/base_resources.h',
                               'src/core/ext/census/census_interface.h',
@@ -882,13 +928,14 @@ Pod::Spec.new do |s|
                               'src/core/ext/census/trace_propagation.h',
                               'src/core/ext/census/trace_status.h',
                               'src/core/ext/census/trace_string.h',
-                              'src/core/ext/census/tracing.h'
+                              'src/core/ext/census/tracing.h',
+                              'src/core/ext/filters/max_age/max_age_filter.h',
+                              'src/core/ext/filters/message_size/message_size_filter.h'
   end
 
   s.subspec 'Cronet-Interface' do |ss|
     ss.header_mappings_dir = 'include/grpc'
-    ss.source_files = 'include/grpc/grpc_cronet.h',
-                      'src/core/ext/transport/cronet/transport/cronet_transport.h'
+    ss.source_files = 'include/grpc/grpc_cronet.h'
   end
 
   s.subspec 'Cronet-Implementation' do |ss|
@@ -899,7 +946,7 @@ Pod::Spec.new do |s|
     ss.dependency "#{s.name}/Cronet-Interface", version
 
     ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c',
-                      'src/core/ext/transport/cronet/transport/cronet_transport.c',
+                      'src/core/ext/transport/cronet/transport/cronet_transport.{c,h}',
                       'third_party/objective_c/Cronet/bidirectional_stream_c.h'
   end
 
@@ -914,7 +961,7 @@ Pod::Spec.new do |s|
                       'test/core/end2end/end2end_test_utils.c',
                       'test/core/end2end/tests/*.{c,h}',
                       'test/core/end2end/data/*.{c,h}',
-                      'test/core/util/debugger_macros.c',
+                      'test/core/util/debugger_macros.{c,h}',
                       'test/core/util/test_config.{c,h}',
                       'test/core/util/port.h',
                       'test/core/util/port.c',
diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec
index 33ad74d2dfcf2ca132cdaa418bb2c680ceff0aea..62cb0d11a1c9e8c55980f296153973dd32775fb7 100644
--- a/gRPC-ProtoRPC.podspec
+++ b/gRPC-ProtoRPC.podspec
@@ -36,7 +36,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-ProtoRPC'
-  version = '1.2.0-dev'
+  version = '1.4.0-dev'
   s.version  = version
   s.summary  = 'RPC library for Protocol Buffers, based on gRPC'
   s.homepage = 'http://www.grpc.io'
@@ -48,7 +48,7 @@ Pod::Spec.new do |s|
     :tag => "v#{version}",
   }
 
-  s.ios.deployment_target = '7.1'
+  s.ios.deployment_target = '7.0'
   s.osx.deployment_target = '10.9'
 
   name = 'ProtoRPC'
diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec
index 35eb5587c85514ac0acaeeecf980b41517a88fd6..77ceb22123c5746df403ea3bcf233ec4ccb2c0ef 100644
--- a/gRPC-RxLibrary.podspec
+++ b/gRPC-RxLibrary.podspec
@@ -36,7 +36,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-RxLibrary'
-  version = '1.2.0-dev'
+  version = '1.4.0-dev'
   s.version  = version
   s.summary  = 'Reactive Extensions library for iOS/OSX.'
   s.homepage = 'http://www.grpc.io'
@@ -48,7 +48,7 @@ Pod::Spec.new do |s|
     :tag => "v#{version}",
   }
 
-  s.ios.deployment_target = '7.1'
+  s.ios.deployment_target = '7.0'
   s.osx.deployment_target = '10.9'
 
   name = 'RxLibrary'
diff --git a/gRPC.podspec b/gRPC.podspec
index 6ba0c01d39f4771564b4e508dd4005579cfe63cf..10520bd3880edb2e05e9397d04f63f26c0bc62d2 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -35,7 +35,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC'
-  version = '1.2.0-dev'
+  version = '1.4.0-dev'
   s.version  = version
   s.summary  = 'gRPC client library for iOS/OSX'
   s.homepage = 'http://www.grpc.io'
@@ -47,7 +47,7 @@ Pod::Spec.new do |s|
     :tag => "v#{version}",
   }
 
-  s.ios.deployment_target = '7.1'
+  s.ios.deployment_target = '7.0'
   s.osx.deployment_target = '10.9'
 
   name = 'GRPCClient'
diff --git a/grpc.def b/grpc.def
index c660d361b1c33906d2d708f595d5761a6b3fb9ce..293f2d892ae4779449e9b73a39ea6ae41d76fae1 100644
--- a/grpc.def
+++ b/grpc.def
@@ -53,6 +53,9 @@ EXPORTS
     grpc_shutdown
     grpc_version_string
     grpc_g_stands_for
+    grpc_completion_queue_factory_lookup
+    grpc_completion_queue_create_for_next
+    grpc_completion_queue_create_for_pluck
     grpc_completion_queue_create
     grpc_completion_queue_next
     grpc_completion_queue_pluck
@@ -67,9 +70,9 @@ EXPORTS
     grpc_channel_ping
     grpc_channel_register_call
     grpc_channel_create_registered_call
+    grpc_call_arena_alloc
     grpc_call_start_batch
     grpc_call_get_peer
-    grpc_call_set_load_reporting_cost_context
     grpc_census_call_set_context
     grpc_census_call_get_context
     grpc_channel_get_target
@@ -79,13 +82,13 @@ EXPORTS
     grpc_channel_destroy
     grpc_call_cancel
     grpc_call_cancel_with_status
-    grpc_call_destroy
+    grpc_call_ref
+    grpc_call_unref
     grpc_server_request_call
     grpc_server_register_method
     grpc_server_request_registered_call
     grpc_server_create
     grpc_server_register_completion_queue
-    grpc_server_register_non_listening_completion_queue
     grpc_server_add_insecure_http2_port
     grpc_server_start
     grpc_server_shutdown_and_notify
@@ -138,10 +141,12 @@ EXPORTS
     grpc_server_credentials_set_auth_metadata_processor
     grpc_slice_ref
     grpc_slice_unref
+    grpc_slice_copy
     grpc_slice_new
     grpc_slice_new_with_user_data
     grpc_slice_new_with_len
     grpc_slice_malloc
+    grpc_slice_malloc_large
     grpc_slice_intern
     grpc_slice_from_copied_string
     grpc_slice_from_copied_buffer
@@ -150,6 +155,7 @@ EXPORTS
     grpc_slice_sub
     grpc_slice_sub_no_ref
     grpc_slice_split_tail
+    grpc_slice_split_tail_maybe_ref
     grpc_slice_split_head
     grpc_empty_slice
     grpc_slice_default_hash_impl
@@ -178,6 +184,7 @@ EXPORTS
     grpc_slice_buffer_move_into
     grpc_slice_buffer_trim_end
     grpc_slice_buffer_move_first
+    grpc_slice_buffer_move_first_no_ref
     grpc_slice_buffer_move_first_into_buffer
     grpc_slice_buffer_take_first
     grpc_slice_buffer_undo_take_first
@@ -258,6 +265,7 @@ EXPORTS
     gpr_ref_non_zero
     gpr_refn
     gpr_unref
+    gpr_ref_is_unique
     gpr_stats_init
     gpr_stats_inc
     gpr_stats_read
diff --git a/grpc.gemspec b/grpc.gemspec
index 8d5b7b2ab1c299bfa0de49726750bd8ad77b263f..b96f3cbab548e1d2a06a9352e9a532e98e948e1e 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
   s.files += Dir.glob('include/grpc/**/*')
   s.test_files = Dir.glob('src/ruby/spec/**/*')
   s.bindir = 'src/ruby/bin'
-  s.require_paths = %w( src/ruby/bin src/ruby/lib src/ruby/pb )
+  s.require_paths = %w( src/ruby/lib src/ruby/bin src/ruby/pb )
   s.platform      = Gem::Platform::RUBY
 
   s.add_dependency 'google-protobuf', '~> 3.1'
@@ -76,15 +76,19 @@ Gem::Specification.new do |s|
   s.files += %w( include/grpc/impl/codegen/gpr_slice.h )
   s.files += %w( include/grpc/impl/codegen/gpr_types.h )
   s.files += %w( include/grpc/impl/codegen/port_platform.h )
-  s.files += %w( include/grpc/impl/codegen/slice.h )
   s.files += %w( include/grpc/impl/codegen/sync.h )
   s.files += %w( include/grpc/impl/codegen/sync_generic.h )
   s.files += %w( include/grpc/impl/codegen/sync_posix.h )
   s.files += %w( include/grpc/impl/codegen/sync_windows.h )
   s.files += %w( src/core/lib/profiling/timers.h )
+  s.files += %w( src/core/lib/support/arena.h )
+  s.files += %w( src/core/lib/support/atomic.h )
+  s.files += %w( src/core/lib/support/atomic_with_atm.h )
+  s.files += %w( src/core/lib/support/atomic_with_std.h )
   s.files += %w( src/core/lib/support/backoff.h )
   s.files += %w( src/core/lib/support/block_annotate.h )
   s.files += %w( src/core/lib/support/env.h )
+  s.files += %w( src/core/lib/support/memory.h )
   s.files += %w( src/core/lib/support/mpscq.h )
   s.files += %w( src/core/lib/support/murmur_hash.h )
   s.files += %w( src/core/lib/support/spinlock.h )
@@ -97,6 +101,8 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/profiling/basic_timers.c )
   s.files += %w( src/core/lib/profiling/stap_timers.c )
   s.files += %w( src/core/lib/support/alloc.c )
+  s.files += %w( src/core/lib/support/arena.c )
+  s.files += %w( src/core/lib/support/atm.c )
   s.files += %w( src/core/lib/support/avl.c )
   s.files += %w( src/core/lib/support/backoff.c )
   s.files += %w( src/core/lib/support/cmdline.c )
@@ -154,6 +160,7 @@ Gem::Specification.new do |s|
   s.files += %w( include/grpc/impl/codegen/exec_ctx_fwd.h )
   s.files += %w( include/grpc/impl/codegen/grpc_types.h )
   s.files += %w( include/grpc/impl/codegen/propagation_bits.h )
+  s.files += %w( include/grpc/impl/codegen/slice.h )
   s.files += %w( include/grpc/impl/codegen/status.h )
   s.files += %w( include/grpc/impl/codegen/atm.h )
   s.files += %w( include/grpc/impl/codegen/atm_gcc_atomic.h )
@@ -162,7 +169,6 @@ Gem::Specification.new do |s|
   s.files += %w( include/grpc/impl/codegen/gpr_slice.h )
   s.files += %w( include/grpc/impl/codegen/gpr_types.h )
   s.files += %w( include/grpc/impl/codegen/port_platform.h )
-  s.files += %w( include/grpc/impl/codegen/slice.h )
   s.files += %w( include/grpc/impl/codegen/sync.h )
   s.files += %w( include/grpc/impl/codegen/sync_generic.h )
   s.files += %w( include/grpc/impl/codegen/sync_posix.h )
@@ -172,16 +178,11 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/channel/channel_args.h )
   s.files += %w( src/core/lib/channel/channel_stack.h )
   s.files += %w( src/core/lib/channel/channel_stack_builder.h )
-  s.files += %w( src/core/lib/channel/compress_filter.h )
   s.files += %w( src/core/lib/channel/connected_channel.h )
   s.files += %w( src/core/lib/channel/context.h )
-  s.files += %w( src/core/lib/channel/deadline_filter.h )
   s.files += %w( src/core/lib/channel/handshaker.h )
   s.files += %w( src/core/lib/channel/handshaker_factory.h )
   s.files += %w( src/core/lib/channel/handshaker_registry.h )
-  s.files += %w( src/core/lib/channel/http_client_filter.h )
-  s.files += %w( src/core/lib/channel/http_server_filter.h )
-  s.files += %w( src/core/lib/channel/message_size_filter.h )
   s.files += %w( src/core/lib/compression/algorithm_metadata.h )
   s.files += %w( src/core/lib/compression/message_compress.h )
   s.files += %w( src/core/lib/debug/trace.h )
@@ -204,6 +205,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/iomgr/iomgr_internal.h )
   s.files += %w( src/core/lib/iomgr/iomgr_posix.h )
   s.files += %w( src/core/lib/iomgr/load_file.h )
+  s.files += %w( src/core/lib/iomgr/lockfree_event.h )
   s.files += %w( src/core/lib/iomgr/network_status_tracker.h )
   s.files += %w( src/core/lib/iomgr/polling_entity.h )
   s.files += %w( src/core/lib/iomgr/pollset.h )
@@ -218,6 +220,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/iomgr/sockaddr_posix.h )
   s.files += %w( src/core/lib/iomgr/sockaddr_utils.h )
   s.files += %w( src/core/lib/iomgr/sockaddr_windows.h )
+  s.files += %w( src/core/lib/iomgr/socket_factory_posix.h )
   s.files += %w( src/core/lib/iomgr/socket_mutator.h )
   s.files += %w( src/core/lib/iomgr/socket_utils.h )
   s.files += %w( src/core/lib/iomgr/socket_utils_posix.h )
@@ -226,6 +229,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/iomgr/tcp_client_posix.h )
   s.files += %w( src/core/lib/iomgr/tcp_posix.h )
   s.files += %w( src/core/lib/iomgr/tcp_server.h )
+  s.files += %w( src/core/lib/iomgr/tcp_server_utils_posix.h )
   s.files += %w( src/core/lib/iomgr/tcp_uv.h )
   s.files += %w( src/core/lib/iomgr/tcp_windows.h )
   s.files += %w( src/core/lib/iomgr/time_averaged_stats.h )
@@ -245,6 +249,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/json/json_common.h )
   s.files += %w( src/core/lib/json/json_reader.h )
   s.files += %w( src/core/lib/json/json_writer.h )
+  s.files += %w( src/core/lib/slice/b64.h )
   s.files += %w( src/core/lib/slice/percent_encoding.h )
   s.files += %w( src/core/lib/slice/slice_hash_table.h )
   s.files += %w( src/core/lib/slice/slice_internal.h )
@@ -256,6 +261,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/surface/channel_init.h )
   s.files += %w( src/core/lib/surface/channel_stack_type.h )
   s.files += %w( src/core/lib/surface/completion_queue.h )
+  s.files += %w( src/core/lib/surface/completion_queue_factory.h )
   s.files += %w( src/core/lib/surface/event_string.h )
   s.files += %w( src/core/lib/surface/init.h )
   s.files += %w( src/core/lib/surface/lame_client.h )
@@ -288,12 +294,16 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/transport/chttp2/transport/hpack_encoder.h )
   s.files += %w( src/core/ext/transport/chttp2/transport/hpack_parser.h )
   s.files += %w( src/core/ext/transport/chttp2/transport/hpack_table.h )
+  s.files += %w( src/core/ext/transport/chttp2/transport/http2_settings.h )
   s.files += %w( src/core/ext/transport/chttp2/transport/huffsyms.h )
   s.files += %w( src/core/ext/transport/chttp2/transport/incoming_metadata.h )
   s.files += %w( src/core/ext/transport/chttp2/transport/internal.h )
   s.files += %w( src/core/ext/transport/chttp2/transport/stream_map.h )
   s.files += %w( src/core/ext/transport/chttp2/transport/varint.h )
   s.files += %w( src/core/ext/transport/chttp2/alpn/alpn.h )
+  s.files += %w( src/core/ext/filters/http/client/http_client_filter.h )
+  s.files += %w( src/core/ext/filters/http/message_compress/message_compress_filter.h )
+  s.files += %w( src/core/ext/filters/http/server/http_server_filter.h )
   s.files += %w( src/core/lib/security/context/security_context.h )
   s.files += %w( src/core/lib/security/credentials/composite/composite_credentials.h )
   s.files += %w( src/core/lib/security/credentials/credentials.h )
@@ -312,43 +322,48 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/security/transport/security_connector.h )
   s.files += %w( src/core/lib/security/transport/security_handshaker.h )
   s.files += %w( src/core/lib/security/transport/tsi_error.h )
-  s.files += %w( src/core/lib/security/util/b64.h )
   s.files += %w( src/core/lib/security/util/json_util.h )
-  s.files += %w( src/core/lib/tsi/fake_transport_security.h )
-  s.files += %w( src/core/lib/tsi/ssl_transport_security.h )
-  s.files += %w( src/core/lib/tsi/ssl_types.h )
-  s.files += %w( src/core/lib/tsi/transport_security.h )
-  s.files += %w( src/core/lib/tsi/transport_security_interface.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_adapter.h )
+  s.files += %w( src/core/tsi/transport_security_interface.h )
   s.files += %w( src/core/ext/transport/chttp2/server/chttp2_server.h )
-  s.files += %w( src/core/ext/client_channel/client_channel.h )
-  s.files += %w( src/core/ext/client_channel/client_channel_factory.h )
-  s.files += %w( src/core/ext/client_channel/connector.h )
-  s.files += %w( src/core/ext/client_channel/http_connect_handshaker.h )
-  s.files += %w( src/core/ext/client_channel/http_proxy.h )
-  s.files += %w( src/core/ext/client_channel/initial_connect_string.h )
-  s.files += %w( src/core/ext/client_channel/lb_policy.h )
-  s.files += %w( src/core/ext/client_channel/lb_policy_factory.h )
-  s.files += %w( src/core/ext/client_channel/lb_policy_registry.h )
-  s.files += %w( src/core/ext/client_channel/parse_address.h )
-  s.files += %w( src/core/ext/client_channel/proxy_mapper.h )
-  s.files += %w( src/core/ext/client_channel/proxy_mapper_registry.h )
-  s.files += %w( src/core/ext/client_channel/resolver.h )
-  s.files += %w( src/core/ext/client_channel/resolver_factory.h )
-  s.files += %w( src/core/ext/client_channel/resolver_registry.h )
-  s.files += %w( src/core/ext/client_channel/subchannel.h )
-  s.files += %w( src/core/ext/client_channel/subchannel_index.h )
-  s.files += %w( src/core/ext/client_channel/uri_parser.h )
+  s.files += %w( src/core/ext/filters/client_channel/client_channel.h )
+  s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.h )
+  s.files += %w( src/core/ext/filters/client_channel/connector.h )
+  s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.h )
+  s.files += %w( src/core/ext/filters/client_channel/http_proxy.h )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy.h )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.h )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.h )
+  s.files += %w( src/core/ext/filters/client_channel/parse_address.h )
+  s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.h )
+  s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.h )
+  s.files += %w( src/core/ext/filters/client_channel/resolver.h )
+  s.files += %w( src/core/ext/filters/client_channel/resolver_factory.h )
+  s.files += %w( src/core/ext/filters/client_channel/resolver_registry.h )
+  s.files += %w( src/core/ext/filters/client_channel/retry_throttle.h )
+  s.files += %w( src/core/ext/filters/client_channel/subchannel.h )
+  s.files += %w( src/core/ext/filters/client_channel/subchannel_index.h )
+  s.files += %w( src/core/ext/filters/client_channel/uri_parser.h )
+  s.files += %w( src/core/ext/filters/deadline/deadline_filter.h )
   s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.h )
-  s.files += %w( src/core/ext/lb_policy/grpclb/grpclb.h )
-  s.files += %w( src/core/ext/lb_policy/grpclb/grpclb_channel.h )
-  s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.h )
-  s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h )
   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/ext/load_reporting/load_reporting.h )
-  s.files += %w( src/core/ext/load_reporting/load_reporting_filter.h )
+  s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h )
+  s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h )
+  s.files += %w( src/core/ext/filters/load_reporting/load_reporting.h )
+  s.files += %w( src/core/ext/filters/load_reporting/load_reporting_filter.h )
   s.files += %w( src/core/ext/census/aggregation.h )
   s.files += %w( src/core/ext/census/base_resources.h )
   s.files += %w( src/core/ext/census/census_interface.h )
@@ -365,19 +380,16 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/census/trace_status.h )
   s.files += %w( src/core/ext/census/trace_string.h )
   s.files += %w( src/core/ext/census/tracing.h )
+  s.files += %w( src/core/ext/filters/max_age/max_age_filter.h )
+  s.files += %w( src/core/ext/filters/message_size/message_size_filter.h )
   s.files += %w( src/core/lib/surface/init.c )
   s.files += %w( src/core/lib/channel/channel_args.c )
   s.files += %w( src/core/lib/channel/channel_stack.c )
   s.files += %w( src/core/lib/channel/channel_stack_builder.c )
-  s.files += %w( src/core/lib/channel/compress_filter.c )
   s.files += %w( src/core/lib/channel/connected_channel.c )
-  s.files += %w( src/core/lib/channel/deadline_filter.c )
   s.files += %w( src/core/lib/channel/handshaker.c )
   s.files += %w( src/core/lib/channel/handshaker_factory.c )
   s.files += %w( src/core/lib/channel/handshaker_registry.c )
-  s.files += %w( src/core/lib/channel/http_client_filter.c )
-  s.files += %w( src/core/lib/channel/http_server_filter.c )
-  s.files += %w( src/core/lib/channel/message_size_filter.c )
   s.files += %w( src/core/lib/compression/compression.c )
   s.files += %w( src/core/lib/compression/message_compress.c )
   s.files += %w( src/core/lib/debug/trace.c )
@@ -402,6 +414,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/iomgr/iomgr_uv.c )
   s.files += %w( src/core/lib/iomgr/iomgr_windows.c )
   s.files += %w( src/core/lib/iomgr/load_file.c )
+  s.files += %w( src/core/lib/iomgr/lockfree_event.c )
   s.files += %w( src/core/lib/iomgr/network_status_tracker.c )
   s.files += %w( src/core/lib/iomgr/polling_entity.c )
   s.files += %w( src/core/lib/iomgr/pollset_set_uv.c )
@@ -413,6 +426,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/iomgr/resolve_address_windows.c )
   s.files += %w( src/core/lib/iomgr/resource_quota.c )
   s.files += %w( src/core/lib/iomgr/sockaddr_utils.c )
+  s.files += %w( src/core/lib/iomgr/socket_factory_posix.c )
   s.files += %w( src/core/lib/iomgr/socket_mutator.c )
   s.files += %w( src/core/lib/iomgr/socket_utils_common_posix.c )
   s.files += %w( src/core/lib/iomgr/socket_utils_linux.c )
@@ -425,6 +439,9 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/iomgr/tcp_client_windows.c )
   s.files += %w( src/core/lib/iomgr/tcp_posix.c )
   s.files += %w( src/core/lib/iomgr/tcp_server_posix.c )
+  s.files += %w( src/core/lib/iomgr/tcp_server_utils_posix_common.c )
+  s.files += %w( src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c )
+  s.files += %w( src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c )
   s.files += %w( src/core/lib/iomgr/tcp_server_uv.c )
   s.files += %w( src/core/lib/iomgr/tcp_server_windows.c )
   s.files += %w( src/core/lib/iomgr/tcp_uv.c )
@@ -447,6 +464,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/json/json_reader.c )
   s.files += %w( src/core/lib/json/json_string.c )
   s.files += %w( src/core/lib/json/json_writer.c )
+  s.files += %w( src/core/lib/slice/b64.c )
   s.files += %w( src/core/lib/slice/percent_encoding.c )
   s.files += %w( src/core/lib/slice/slice.c )
   s.files += %w( src/core/lib/slice/slice_buffer.c )
@@ -465,8 +483,9 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/surface/channel_ping.c )
   s.files += %w( src/core/lib/surface/channel_stack_type.c )
   s.files += %w( src/core/lib/surface/completion_queue.c )
+  s.files += %w( src/core/lib/surface/completion_queue_factory.c )
   s.files += %w( src/core/lib/surface/event_string.c )
-  s.files += %w( src/core/lib/surface/lame_client.c )
+  s.files += %w( src/core/lib/surface/lame_client.cc )
   s.files += %w( src/core/lib/surface/metadata_array.c )
   s.files += %w( src/core/lib/surface/server.c )
   s.files += %w( src/core/lib/surface/validate_metadata.c )
@@ -498,6 +517,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/transport/chttp2/transport/hpack_encoder.c )
   s.files += %w( src/core/ext/transport/chttp2/transport/hpack_parser.c )
   s.files += %w( src/core/ext/transport/chttp2/transport/hpack_table.c )
+  s.files += %w( src/core/ext/transport/chttp2/transport/http2_settings.c )
   s.files += %w( src/core/ext/transport/chttp2/transport/huffsyms.c )
   s.files += %w( src/core/ext/transport/chttp2/transport/incoming_metadata.c )
   s.files += %w( src/core/ext/transport/chttp2/transport/parsing.c )
@@ -506,6 +526,10 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/transport/chttp2/transport/varint.c )
   s.files += %w( src/core/ext/transport/chttp2/transport/writing.c )
   s.files += %w( src/core/ext/transport/chttp2/alpn/alpn.c )
+  s.files += %w( src/core/ext/filters/http/client/http_client_filter.c )
+  s.files += %w( src/core/ext/filters/http/http_filters_plugin.c )
+  s.files += %w( src/core/ext/filters/http/message_compress/message_compress_filter.c )
+  s.files += %w( src/core/ext/filters/http/server/http_server_filter.c )
   s.files += %w( src/core/lib/http/httpcli_security_connector.c )
   s.files += %w( src/core/lib/security/context/security_context.c )
   s.files += %w( src/core/lib/security/credentials/composite/composite_credentials.c )
@@ -528,53 +552,58 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/security/transport/security_handshaker.c )
   s.files += %w( src/core/lib/security/transport/server_auth_filter.c )
   s.files += %w( src/core/lib/security/transport/tsi_error.c )
-  s.files += %w( src/core/lib/security/util/b64.c )
   s.files += %w( src/core/lib/security/util/json_util.c )
   s.files += %w( src/core/lib/surface/init_secure.c )
-  s.files += %w( src/core/lib/tsi/fake_transport_security.c )
-  s.files += %w( src/core/lib/tsi/ssl_transport_security.c )
-  s.files += %w( src/core/lib/tsi/transport_security.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/tsi/transport_security_adapter.c )
   s.files += %w( src/core/ext/transport/chttp2/server/chttp2_server.c )
   s.files += %w( src/core/ext/transport/chttp2/client/secure/secure_channel_create.c )
-  s.files += %w( src/core/ext/client_channel/channel_connectivity.c )
-  s.files += %w( src/core/ext/client_channel/client_channel.c )
-  s.files += %w( src/core/ext/client_channel/client_channel_factory.c )
-  s.files += %w( src/core/ext/client_channel/client_channel_plugin.c )
-  s.files += %w( src/core/ext/client_channel/connector.c )
-  s.files += %w( src/core/ext/client_channel/default_initial_connect_string.c )
-  s.files += %w( src/core/ext/client_channel/http_connect_handshaker.c )
-  s.files += %w( src/core/ext/client_channel/http_proxy.c )
-  s.files += %w( src/core/ext/client_channel/initial_connect_string.c )
-  s.files += %w( src/core/ext/client_channel/lb_policy.c )
-  s.files += %w( src/core/ext/client_channel/lb_policy_factory.c )
-  s.files += %w( src/core/ext/client_channel/lb_policy_registry.c )
-  s.files += %w( src/core/ext/client_channel/parse_address.c )
-  s.files += %w( src/core/ext/client_channel/proxy_mapper.c )
-  s.files += %w( src/core/ext/client_channel/proxy_mapper_registry.c )
-  s.files += %w( src/core/ext/client_channel/resolver.c )
-  s.files += %w( src/core/ext/client_channel/resolver_factory.c )
-  s.files += %w( src/core/ext/client_channel/resolver_registry.c )
-  s.files += %w( src/core/ext/client_channel/subchannel.c )
-  s.files += %w( src/core/ext/client_channel/subchannel_index.c )
-  s.files += %w( src/core/ext/client_channel/uri_parser.c )
+  s.files += %w( src/core/ext/filters/client_channel/channel_connectivity.c )
+  s.files += %w( src/core/ext/filters/client_channel/client_channel.c )
+  s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.c )
+  s.files += %w( src/core/ext/filters/client_channel/client_channel_plugin.c )
+  s.files += %w( src/core/ext/filters/client_channel/connector.c )
+  s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.c )
+  s.files += %w( src/core/ext/filters/client_channel/http_proxy.c )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy.c )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.c )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.c )
+  s.files += %w( src/core/ext/filters/client_channel/parse_address.c )
+  s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.c )
+  s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.c )
+  s.files += %w( src/core/ext/filters/client_channel/resolver.c )
+  s.files += %w( src/core/ext/filters/client_channel/resolver_factory.c )
+  s.files += %w( src/core/ext/filters/client_channel/resolver_registry.c )
+  s.files += %w( src/core/ext/filters/client_channel/retry_throttle.c )
+  s.files += %w( src/core/ext/filters/client_channel/subchannel.c )
+  s.files += %w( src/core/ext/filters/client_channel/subchannel_index.c )
+  s.files += %w( src/core/ext/filters/client_channel/uri_parser.c )
+  s.files += %w( src/core/ext/filters/deadline/deadline_filter.c )
   s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.c )
   s.files += %w( src/core/ext/transport/chttp2/server/insecure/server_chttp2.c )
   s.files += %w( src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c )
   s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create.c )
   s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c )
-  s.files += %w( src/core/ext/lb_policy/grpclb/grpclb.c )
-  s.files += %w( src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c )
-  s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.c )
-  s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.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( src/core/ext/lb_policy/pick_first/pick_first.c )
-  s.files += %w( src/core/ext/lb_policy/round_robin/round_robin.c )
-  s.files += %w( src/core/ext/resolver/dns/native/dns_resolver.c )
-  s.files += %w( src/core/ext/resolver/sockaddr/sockaddr_resolver.c )
-  s.files += %w( src/core/ext/load_reporting/load_reporting.c )
-  s.files += %w( src/core/ext/load_reporting/load_reporting_filter.c )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c )
+  s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c )
+  s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c )
+  s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c )
+  s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c )
+  s.files += %w( src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c )
+  s.files += %w( src/core/ext/filters/load_reporting/load_reporting.c )
+  s.files += %w( src/core/ext/filters/load_reporting/load_reporting_filter.c )
   s.files += %w( src/core/ext/census/base_resources.c )
   s.files += %w( src/core/ext/census/context.c )
   s.files += %w( src/core/ext/census/gen/census.pb.c )
@@ -589,6 +618,8 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/census/resource.c )
   s.files += %w( src/core/ext/census/trace_context.c )
   s.files += %w( src/core/ext/census/tracing.c )
+  s.files += %w( src/core/ext/filters/max_age/max_age_filter.c )
+  s.files += %w( src/core/ext/filters/message_size/message_size_filter.c )
   s.files += %w( src/core/plugin_registry/grpc_plugin_registry.c )
   s.files += %w( third_party/boringssl/crypto/aes/internal.h )
   s.files += %w( third_party/boringssl/crypto/asn1/asn1_locl.h )
@@ -1024,4 +1055,77 @@ Gem::Specification.new do |s|
   s.files += %w( third_party/zlib/trees.c )
   s.files += %w( third_party/zlib/uncompr.c )
   s.files += %w( third_party/zlib/zutil.c )
+  s.files += %w( third_party/cares/cares/ares.h )
+  s.files += %w( third_party/cares/cares/ares_data.h )
+  s.files += %w( third_party/cares/cares/ares_dns.h )
+  s.files += %w( third_party/cares/cares/ares_getenv.h )
+  s.files += %w( third_party/cares/cares/ares_getopt.h )
+  s.files += %w( third_party/cares/cares/ares_inet_net_pton.h )
+  s.files += %w( third_party/cares/cares/ares_iphlpapi.h )
+  s.files += %w( third_party/cares/cares/ares_ipv6.h )
+  s.files += %w( third_party/cares/cares/ares_library_init.h )
+  s.files += %w( third_party/cares/cares/ares_llist.h )
+  s.files += %w( third_party/cares/cares/ares_nowarn.h )
+  s.files += %w( third_party/cares/cares/ares_platform.h )
+  s.files += %w( third_party/cares/cares/ares_private.h )
+  s.files += %w( third_party/cares/cares/ares_rules.h )
+  s.files += %w( third_party/cares/cares/ares_setup.h )
+  s.files += %w( third_party/cares/cares/ares_strcasecmp.h )
+  s.files += %w( third_party/cares/cares/ares_strdup.h )
+  s.files += %w( third_party/cares/cares/ares_version.h )
+  s.files += %w( third_party/cares/cares/bitncmp.h )
+  s.files += %w( third_party/cares/cares/config-win32.h )
+  s.files += %w( third_party/cares/cares/setup_once.h )
+  s.files += %w( third_party/cares/ares_build.h )
+  s.files += %w( third_party/cares/config_linux/ares_config.h )
+  s.files += %w( third_party/cares/config_darwin/ares_config.h )
+  s.files += %w( third_party/cares/cares/ares__close_sockets.c )
+  s.files += %w( third_party/cares/cares/ares__get_hostent.c )
+  s.files += %w( third_party/cares/cares/ares__read_line.c )
+  s.files += %w( third_party/cares/cares/ares__timeval.c )
+  s.files += %w( third_party/cares/cares/ares_cancel.c )
+  s.files += %w( third_party/cares/cares/ares_create_query.c )
+  s.files += %w( third_party/cares/cares/ares_data.c )
+  s.files += %w( third_party/cares/cares/ares_destroy.c )
+  s.files += %w( third_party/cares/cares/ares_expand_name.c )
+  s.files += %w( third_party/cares/cares/ares_expand_string.c )
+  s.files += %w( third_party/cares/cares/ares_fds.c )
+  s.files += %w( third_party/cares/cares/ares_free_hostent.c )
+  s.files += %w( third_party/cares/cares/ares_free_string.c )
+  s.files += %w( third_party/cares/cares/ares_getenv.c )
+  s.files += %w( third_party/cares/cares/ares_gethostbyaddr.c )
+  s.files += %w( third_party/cares/cares/ares_gethostbyname.c )
+  s.files += %w( third_party/cares/cares/ares_getnameinfo.c )
+  s.files += %w( third_party/cares/cares/ares_getopt.c )
+  s.files += %w( third_party/cares/cares/ares_getsock.c )
+  s.files += %w( third_party/cares/cares/ares_init.c )
+  s.files += %w( third_party/cares/cares/ares_library_init.c )
+  s.files += %w( third_party/cares/cares/ares_llist.c )
+  s.files += %w( third_party/cares/cares/ares_mkquery.c )
+  s.files += %w( third_party/cares/cares/ares_nowarn.c )
+  s.files += %w( third_party/cares/cares/ares_options.c )
+  s.files += %w( third_party/cares/cares/ares_parse_a_reply.c )
+  s.files += %w( third_party/cares/cares/ares_parse_aaaa_reply.c )
+  s.files += %w( third_party/cares/cares/ares_parse_mx_reply.c )
+  s.files += %w( third_party/cares/cares/ares_parse_naptr_reply.c )
+  s.files += %w( third_party/cares/cares/ares_parse_ns_reply.c )
+  s.files += %w( third_party/cares/cares/ares_parse_ptr_reply.c )
+  s.files += %w( third_party/cares/cares/ares_parse_soa_reply.c )
+  s.files += %w( third_party/cares/cares/ares_parse_srv_reply.c )
+  s.files += %w( third_party/cares/cares/ares_parse_txt_reply.c )
+  s.files += %w( third_party/cares/cares/ares_platform.c )
+  s.files += %w( third_party/cares/cares/ares_process.c )
+  s.files += %w( third_party/cares/cares/ares_query.c )
+  s.files += %w( third_party/cares/cares/ares_search.c )
+  s.files += %w( third_party/cares/cares/ares_send.c )
+  s.files += %w( third_party/cares/cares/ares_strcasecmp.c )
+  s.files += %w( third_party/cares/cares/ares_strdup.c )
+  s.files += %w( third_party/cares/cares/ares_strerror.c )
+  s.files += %w( third_party/cares/cares/ares_timeout.c )
+  s.files += %w( third_party/cares/cares/ares_version.c )
+  s.files += %w( third_party/cares/cares/ares_writev.c )
+  s.files += %w( third_party/cares/cares/bitncmp.c )
+  s.files += %w( third_party/cares/cares/inet_net_pton.c )
+  s.files += %w( third_party/cares/cares/inet_ntop.c )
+  s.files += %w( third_party/cares/cares/windows_port.c )
 end
diff --git a/src/core/ext/client_channel/initial_connect_string.h b/include/grpc++/impl/channel_argument_option.h
similarity index 68%
rename from src/core/ext/client_channel/initial_connect_string.h
rename to include/grpc++/impl/channel_argument_option.h
index 876abea40e4b55c0a46b87e2674923e3d2870752..057acc2cebf40570ece63a9ff90150b30b221822 100644
--- a/src/core/ext/client_channel/initial_connect_string.h
+++ b/include/grpc++/impl/channel_argument_option.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2017, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,20 +31,22 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_INITIAL_CONNECT_STRING_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_INITIAL_CONNECT_STRING_H
+#ifndef GRPCXX_IMPL_CHANNEL_ARGUMENT_OPTION_H
+#define GRPCXX_IMPL_CHANNEL_ARGUMENT_OPTION_H
 
-#include <grpc/slice.h>
-#include "src/core/lib/iomgr/resolve_address.h"
+#include <map>
+#include <memory>
 
-typedef void (*grpc_set_initial_connect_string_func)(
-    grpc_resolved_address **addr, grpc_slice *initial_str);
+#include <grpc++/impl/server_builder_option.h>
+#include <grpc++/support/channel_arguments.h>
 
-void grpc_test_set_initial_connect_string_function(
-    grpc_set_initial_connect_string_func func);
+namespace grpc {
 
-/** Set a string to be sent once connected. Optionally reset addr. */
-void grpc_set_initial_connect_string(grpc_resolved_address **addr,
-                                     grpc_slice *connect_string);
+std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
+    const grpc::string &name, const grpc::string &value);
+std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
+    const grpc::string &name, int value);
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_INITIAL_CONNECT_STRING_H */
+}  // namespace grpc
+
+#endif  // GRPCXX_IMPL_CHANNEL_ARGUMENT_OPTION_H
diff --git a/include/grpc++/impl/codegen/async_stream.h b/include/grpc++/impl/codegen/async_stream.h
index 1a5cbbd45daf37a27967f2692760cb48bd2e65f6..f97d824bafe32552803c2c40a9e5f9dbbfbb8369 100644
--- a/include/grpc++/impl/codegen/async_stream.h
+++ b/include/grpc++/impl/codegen/async_stream.h
@@ -101,6 +101,39 @@ class AsyncWriterInterface {
   /// \param[in] msg The message to be written.
   /// \param[in] tag The tag identifying the operation.
   virtual void Write(const W& msg, void* tag) = 0;
+
+  /// Request the writing of \a msg using WriteOptions \a options with
+  /// identifying tag \a tag.
+  ///
+  /// Only one write may be outstanding at any given time. This means that
+  /// after calling Write, one must wait to receive \a tag from the completion
+  /// queue BEFORE calling Write again.
+  /// WriteOptions \a options is used to set the write options of this message.
+  /// This is thread-safe with respect to \a Read
+  ///
+  /// \param[in] msg The message to be written.
+  /// \param[in] options The WriteOptions to be used to write this message.
+  /// \param[in] tag The tag identifying the operation.
+  virtual void Write(const W& msg, WriteOptions options, void* tag) = 0;
+
+  /// Request the writing of \a msg and coalesce it with the writing
+  /// of trailing metadata, using WriteOptions \a options with identifying tag
+  /// \a tag.
+  ///
+  /// For client, WriteLast is equivalent of performing Write and WritesDone in
+  /// a single step.
+  /// For server, WriteLast buffers the \a msg. The writing of \a msg is held
+  /// until Finish is called, where \a msg and trailing metadata are coalesced
+  /// and write is initiated. Note that WriteLast can only buffer \a msg up to
+  /// the flow control window size. If \a msg size is larger than the window
+  /// size, it will be sent on wire without buffering.
+  ///
+  /// \param[in] msg The message to be written.
+  /// \param[in] options The WriteOptions to be used to write this message.
+  /// \param[in] tag The tag identifying the operation.
+  void WriteLast(const W& msg, WriteOptions options, void* tag) {
+    Write(msg, options.set_last_message(), tag);
+  }
 };
 
 template <class R>
@@ -112,17 +145,19 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface<R> {
  public:
   /// Create a stream and write the first request out.
   template <class W>
-  ClientAsyncReader(ChannelInterface* channel, CompletionQueue* cq,
-                    const RpcMethod& method, ClientContext* context,
-                    const W& request, void* tag)
-      : context_(context), call_(channel->CreateCall(method, context, cq)) {
-    init_ops_.set_output_tag(tag);
-    init_ops_.SendInitialMetadata(context->send_initial_metadata_,
-                                  context->initial_metadata_flags());
-    // TODO(ctiller): don't assert
-    GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok());
-    init_ops_.ClientSendClose();
-    call_.PerformOps(&init_ops_);
+  static ClientAsyncReader* Create(ChannelInterface* channel,
+                                   CompletionQueue* cq, const RpcMethod& method,
+                                   ClientContext* context, const W& request,
+                                   void* tag) {
+    Call call = channel->CreateCall(method, context, cq);
+    return new (g_core_codegen_interface->grpc_call_arena_alloc(
+        call.call(), sizeof(ClientAsyncReader)))
+        ClientAsyncReader(call, context, request, tag);
+  }
+
+  // always allocated against a call arena, no memory free required
+  static void operator delete(void* ptr, std::size_t size) {
+    assert(size == sizeof(ClientAsyncReader));
   }
 
   void ReadInitialMetadata(void* tag) override {
@@ -152,6 +187,19 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface<R> {
   }
 
  private:
+  template <class W>
+  ClientAsyncReader(Call call, ClientContext* context, const W& request,
+                    void* tag)
+      : context_(context), call_(call) {
+    init_ops_.set_output_tag(tag);
+    init_ops_.SendInitialMetadata(context->send_initial_metadata_,
+                                  context->initial_metadata_flags());
+    // TODO(ctiller): don't assert
+    GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok());
+    init_ops_.ClientSendClose();
+    call_.PerformOps(&init_ops_);
+  }
+
   ClientContext* context_;
   Call call_;
   CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose>
@@ -177,17 +225,19 @@ template <class W>
 class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> {
  public:
   template <class R>
-  ClientAsyncWriter(ChannelInterface* channel, CompletionQueue* cq,
-                    const RpcMethod& method, ClientContext* context,
-                    R* response, void* tag)
-      : context_(context), call_(channel->CreateCall(method, context, cq)) {
-    finish_ops_.RecvMessage(response);
-    finish_ops_.AllowNoMessage();
+  static ClientAsyncWriter* Create(ChannelInterface* channel,
+                                   CompletionQueue* cq, const RpcMethod& method,
+                                   ClientContext* context, R* response,
+                                   void* tag) {
+    Call call = channel->CreateCall(method, context, cq);
+    return new (g_core_codegen_interface->grpc_call_arena_alloc(
+        call.call(), sizeof(ClientAsyncWriter)))
+        ClientAsyncWriter(call, context, response, tag);
+  }
 
-    init_ops_.set_output_tag(tag);
-    init_ops_.SendInitialMetadata(context->send_initial_metadata_,
-                                  context->initial_metadata_flags());
-    call_.PerformOps(&init_ops_);
+  // always allocated against a call arena, no memory free required
+  static void operator delete(void* ptr, std::size_t size) {
+    assert(size == sizeof(ClientAsyncWriter));
   }
 
   void ReadInitialMetadata(void* tag) override {
@@ -205,10 +255,21 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> {
     call_.PerformOps(&write_ops_);
   }
 
+  void Write(const W& msg, WriteOptions options, void* tag) override {
+    write_ops_.set_output_tag(tag);
+    if (options.is_last_message()) {
+      options.set_buffer_hint();
+      write_ops_.ClientSendClose();
+    }
+    // TODO(ctiller): don't assert
+    GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
+    call_.PerformOps(&write_ops_);
+  }
+
   void WritesDone(void* tag) override {
-    writes_done_ops_.set_output_tag(tag);
-    writes_done_ops_.ClientSendClose();
-    call_.PerformOps(&writes_done_ops_);
+    write_ops_.set_output_tag(tag);
+    write_ops_.ClientSendClose();
+    call_.PerformOps(&write_ops_);
   }
 
   void Finish(Status* status, void* tag) override {
@@ -221,12 +282,29 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> {
   }
 
  private:
+  template <class R>
+  ClientAsyncWriter(Call call, ClientContext* context, R* response, void* tag)
+      : context_(context), call_(call) {
+    finish_ops_.RecvMessage(response);
+    finish_ops_.AllowNoMessage();
+    // if corked bit is set in context, we buffer up the initial metadata to
+    // coalesce with later message to be sent. No op is performed.
+    if (context_->initial_metadata_corked_) {
+      write_ops_.SendInitialMetadata(context->send_initial_metadata_,
+                                     context->initial_metadata_flags());
+    } else {
+      write_ops_.set_output_tag(tag);
+      write_ops_.SendInitialMetadata(context->send_initial_metadata_,
+                                     context->initial_metadata_flags());
+      call_.PerformOps(&write_ops_);
+    }
+  }
+
   ClientContext* context_;
   Call call_;
-  CallOpSet<CallOpSendInitialMetadata> init_ops_;
   CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
-  CallOpSet<CallOpSendMessage> write_ops_;
-  CallOpSet<CallOpClientSendClose> writes_done_ops_;
+  CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose>
+      write_ops_;
   CallOpSet<CallOpRecvInitialMetadata, CallOpGenericRecvMessage,
             CallOpClientRecvStatus>
       finish_ops_;
@@ -249,14 +327,20 @@ template <class W, class R>
 class ClientAsyncReaderWriter final
     : public ClientAsyncReaderWriterInterface<W, R> {
  public:
-  ClientAsyncReaderWriter(ChannelInterface* channel, CompletionQueue* cq,
-                          const RpcMethod& method, ClientContext* context,
-                          void* tag)
-      : context_(context), call_(channel->CreateCall(method, context, cq)) {
-    init_ops_.set_output_tag(tag);
-    init_ops_.SendInitialMetadata(context->send_initial_metadata_,
-                                  context->initial_metadata_flags());
-    call_.PerformOps(&init_ops_);
+  static ClientAsyncReaderWriter* Create(ChannelInterface* channel,
+                                         CompletionQueue* cq,
+                                         const RpcMethod& method,
+                                         ClientContext* context, void* tag) {
+    Call call = channel->CreateCall(method, context, cq);
+
+    return new (g_core_codegen_interface->grpc_call_arena_alloc(
+        call.call(), sizeof(ClientAsyncReaderWriter)))
+        ClientAsyncReaderWriter(call, context, tag);
+  }
+
+  // always allocated against a call arena, no memory free required
+  static void operator delete(void* ptr, std::size_t size) {
+    assert(size == sizeof(ClientAsyncReaderWriter));
   }
 
   void ReadInitialMetadata(void* tag) override {
@@ -283,10 +367,21 @@ class ClientAsyncReaderWriter final
     call_.PerformOps(&write_ops_);
   }
 
+  void Write(const W& msg, WriteOptions options, void* tag) override {
+    write_ops_.set_output_tag(tag);
+    if (options.is_last_message()) {
+      options.set_buffer_hint();
+      write_ops_.ClientSendClose();
+    }
+    // TODO(ctiller): don't assert
+    GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
+    call_.PerformOps(&write_ops_);
+  }
+
   void WritesDone(void* tag) override {
-    writes_done_ops_.set_output_tag(tag);
-    writes_done_ops_.ClientSendClose();
-    call_.PerformOps(&writes_done_ops_);
+    write_ops_.set_output_tag(tag);
+    write_ops_.ClientSendClose();
+    call_.PerformOps(&write_ops_);
   }
 
   void Finish(Status* status, void* tag) override {
@@ -299,13 +394,27 @@ class ClientAsyncReaderWriter final
   }
 
  private:
+  ClientAsyncReaderWriter(Call call, ClientContext* context, void* tag)
+      : context_(context), call_(call) {
+    if (context_->initial_metadata_corked_) {
+      // if corked bit is set in context, we buffer up the initial metadata to
+      // coalesce with later message to be sent. No op is performed.
+      write_ops_.SendInitialMetadata(context->send_initial_metadata_,
+                                     context->initial_metadata_flags());
+    } else {
+      write_ops_.set_output_tag(tag);
+      write_ops_.SendInitialMetadata(context->send_initial_metadata_,
+                                     context->initial_metadata_flags());
+      call_.PerformOps(&write_ops_);
+    }
+  }
+
   ClientContext* context_;
   Call call_;
-  CallOpSet<CallOpSendInitialMetadata> init_ops_;
   CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
   CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> read_ops_;
-  CallOpSet<CallOpSendMessage> write_ops_;
-  CallOpSet<CallOpClientSendClose> writes_done_ops_;
+  CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose>
+      write_ops_;
   CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> finish_ops_;
 };
 
@@ -395,6 +504,20 @@ class ServerAsyncWriterInterface : public ServerAsyncStreamingInterface,
                                    public AsyncWriterInterface<W> {
  public:
   virtual void Finish(const Status& status, void* tag) = 0;
+
+  /// Request the writing of \a msg and coalesce it with trailing metadata which
+  /// contains \a status, using WriteOptions options with identifying tag \a
+  /// tag.
+  ///
+  /// WriteAndFinish is equivalent of performing WriteLast and Finish in a
+  /// single step.
+  ///
+  /// \param[in] msg The message to be written.
+  /// \param[in] options The WriteOptions to be used to write this message.
+  /// \param[in] status The Status that server returns to client.
+  /// \param[in] tag The tag identifying the operation.
+  virtual void WriteAndFinish(const W& msg, WriteOptions options,
+                              const Status& status, void* tag) = 0;
 };
 
 template <class W>
@@ -418,29 +541,37 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface<W> {
 
   void Write(const W& msg, void* tag) override {
     write_ops_.set_output_tag(tag);
-    if (!ctx_->sent_initial_metadata_) {
-      write_ops_.SendInitialMetadata(ctx_->initial_metadata_,
-                                     ctx_->initial_metadata_flags());
-      if (ctx_->compression_level_set()) {
-        write_ops_.set_compression_level(ctx_->compression_level());
-      }
-      ctx_->sent_initial_metadata_ = true;
-    }
+    EnsureInitialMetadataSent(&write_ops_);
     // TODO(ctiller): don't assert
     GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
     call_.PerformOps(&write_ops_);
   }
 
+  void Write(const W& msg, WriteOptions options, void* tag) override {
+    write_ops_.set_output_tag(tag);
+    if (options.is_last_message()) {
+      options.set_buffer_hint();
+    }
+
+    EnsureInitialMetadataSent(&write_ops_);
+    // TODO(ctiller): don't assert
+    GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
+    call_.PerformOps(&write_ops_);
+  }
+
+  void WriteAndFinish(const W& msg, WriteOptions options, const Status& status,
+                      void* tag) override {
+    write_ops_.set_output_tag(tag);
+    EnsureInitialMetadataSent(&write_ops_);
+    options.set_buffer_hint();
+    GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
+    write_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
+    call_.PerformOps(&write_ops_);
+  }
+
   void Finish(const Status& status, void* tag) override {
     finish_ops_.set_output_tag(tag);
-    if (!ctx_->sent_initial_metadata_) {
-      finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
-                                      ctx_->initial_metadata_flags());
-      if (ctx_->compression_level_set()) {
-        finish_ops_.set_compression_level(ctx_->compression_level());
-      }
-      ctx_->sent_initial_metadata_ = true;
-    }
+    EnsureInitialMetadataSent(&finish_ops_);
     finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
     call_.PerformOps(&finish_ops_);
   }
@@ -448,10 +579,24 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface<W> {
  private:
   void BindCall(Call* call) override { call_ = *call; }
 
+  template <class T>
+  void EnsureInitialMetadataSent(T* ops) {
+    if (!ctx_->sent_initial_metadata_) {
+      ops->SendInitialMetadata(ctx_->initial_metadata_,
+                               ctx_->initial_metadata_flags());
+      if (ctx_->compression_level_set()) {
+        ops->set_compression_level(ctx_->compression_level());
+      }
+      ctx_->sent_initial_metadata_ = true;
+    }
+  }
+
   Call call_;
   ServerContext* ctx_;
   CallOpSet<CallOpSendInitialMetadata> meta_ops_;
-  CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> write_ops_;
+  CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+            CallOpServerSendStatus>
+      write_ops_;
   CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> finish_ops_;
 };
 
@@ -462,6 +607,20 @@ class ServerAsyncReaderWriterInterface : public ServerAsyncStreamingInterface,
                                          public AsyncReaderInterface<R> {
  public:
   virtual void Finish(const Status& status, void* tag) = 0;
+
+  /// Request the writing of \a msg and coalesce it with trailing metadata which
+  /// contains \a status, using WriteOptions options with identifying tag \a
+  /// tag.
+  ///
+  /// WriteAndFinish is equivalent of performing WriteLast and Finish in a
+  /// single step.
+  ///
+  /// \param[in] msg The message to be written.
+  /// \param[in] options The WriteOptions to be used to write this message.
+  /// \param[in] status The Status that server returns to client.
+  /// \param[in] tag The tag identifying the operation.
+  virtual void WriteAndFinish(const W& msg, WriteOptions options,
+                              const Status& status, void* tag) = 0;
 };
 
 template <class W, class R>
@@ -492,29 +651,36 @@ class ServerAsyncReaderWriter final
 
   void Write(const W& msg, void* tag) override {
     write_ops_.set_output_tag(tag);
-    if (!ctx_->sent_initial_metadata_) {
-      write_ops_.SendInitialMetadata(ctx_->initial_metadata_,
-                                     ctx_->initial_metadata_flags());
-      if (ctx_->compression_level_set()) {
-        write_ops_.set_compression_level(ctx_->compression_level());
-      }
-      ctx_->sent_initial_metadata_ = true;
-    }
+    EnsureInitialMetadataSent(&write_ops_);
     // TODO(ctiller): don't assert
     GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
     call_.PerformOps(&write_ops_);
   }
 
+  void Write(const W& msg, WriteOptions options, void* tag) override {
+    write_ops_.set_output_tag(tag);
+    if (options.is_last_message()) {
+      options.set_buffer_hint();
+    }
+    EnsureInitialMetadataSent(&write_ops_);
+    GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
+    call_.PerformOps(&write_ops_);
+  }
+
+  void WriteAndFinish(const W& msg, WriteOptions options, const Status& status,
+                      void* tag) override {
+    write_ops_.set_output_tag(tag);
+    EnsureInitialMetadataSent(&write_ops_);
+    options.set_buffer_hint();
+    GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
+    write_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
+    call_.PerformOps(&write_ops_);
+  }
+
   void Finish(const Status& status, void* tag) override {
     finish_ops_.set_output_tag(tag);
-    if (!ctx_->sent_initial_metadata_) {
-      finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
-                                      ctx_->initial_metadata_flags());
-      if (ctx_->compression_level_set()) {
-        finish_ops_.set_compression_level(ctx_->compression_level());
-      }
-      ctx_->sent_initial_metadata_ = true;
-    }
+    EnsureInitialMetadataSent(&finish_ops_);
+
     finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
     call_.PerformOps(&finish_ops_);
   }
@@ -524,11 +690,25 @@ class ServerAsyncReaderWriter final
 
   void BindCall(Call* call) override { call_ = *call; }
 
+  template <class T>
+  void EnsureInitialMetadataSent(T* ops) {
+    if (!ctx_->sent_initial_metadata_) {
+      ops->SendInitialMetadata(ctx_->initial_metadata_,
+                               ctx_->initial_metadata_flags());
+      if (ctx_->compression_level_set()) {
+        ops->set_compression_level(ctx_->compression_level());
+      }
+      ctx_->sent_initial_metadata_ = true;
+    }
+  }
+
   Call call_;
   ServerContext* ctx_;
   CallOpSet<CallOpSendInitialMetadata> meta_ops_;
   CallOpSet<CallOpRecvMessage<R>> read_ops_;
-  CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> write_ops_;
+  CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+            CallOpServerSendStatus>
+      write_ops_;
   CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> finish_ops_;
 };
 
diff --git a/include/grpc++/impl/codegen/async_unary_call.h b/include/grpc++/impl/codegen/async_unary_call.h
index b77a16b699f9254ed17a4d93c7b0d0d617652fc6..a147a6acbf80acb9af455d7bb8a9ac9b76859b03 100644
--- a/include/grpc++/impl/codegen/async_unary_call.h
+++ b/include/grpc++/impl/codegen/async_unary_call.h
@@ -34,6 +34,7 @@
 #ifndef GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
 #define GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
 
+#include <assert.h>
 #include <grpc++/impl/codegen/call.h>
 #include <grpc++/impl/codegen/channel_interface.h>
 #include <grpc++/impl/codegen/client_context.h>
@@ -59,57 +60,67 @@ class ClientAsyncResponseReader final
     : public ClientAsyncResponseReaderInterface<R> {
  public:
   template <class W>
-  ClientAsyncResponseReader(ChannelInterface* channel, CompletionQueue* cq,
-                            const RpcMethod& method, ClientContext* context,
-                            const W& request)
-      : context_(context),
-        call_(channel->CreateCall(method, context, cq)),
-        collection_(std::make_shared<CallOpSetCollection>()) {
-    collection_->init_buf_.SetCollection(collection_);
-    collection_->init_buf_.SendInitialMetadata(
-        context->send_initial_metadata_, context->initial_metadata_flags());
-    // TODO(ctiller): don't assert
-    GPR_CODEGEN_ASSERT(collection_->init_buf_.SendMessage(request).ok());
-    collection_->init_buf_.ClientSendClose();
-    call_.PerformOps(&collection_->init_buf_);
+  static ClientAsyncResponseReader* Create(ChannelInterface* channel,
+                                           CompletionQueue* cq,
+                                           const RpcMethod& method,
+                                           ClientContext* context,
+                                           const W& request) {
+    Call call = channel->CreateCall(method, context, cq);
+    return new (g_core_codegen_interface->grpc_call_arena_alloc(
+        call.call(), sizeof(ClientAsyncResponseReader)))
+        ClientAsyncResponseReader(call, context, request);
+  }
+
+  // always allocated against a call arena, no memory free required
+  static void operator delete(void* ptr, std::size_t size) {
+    assert(size == sizeof(ClientAsyncResponseReader));
   }
 
   void ReadInitialMetadata(void* tag) {
     GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
 
-    collection_->meta_buf_.SetCollection(collection_);
-    collection_->meta_buf_.set_output_tag(tag);
-    collection_->meta_buf_.RecvInitialMetadata(context_);
-    call_.PerformOps(&collection_->meta_buf_);
+    meta_buf_.set_output_tag(tag);
+    meta_buf_.RecvInitialMetadata(context_);
+    call_.PerformOps(&meta_buf_);
   }
 
   void Finish(R* msg, Status* status, void* tag) {
-    collection_->finish_buf_.SetCollection(collection_);
-    collection_->finish_buf_.set_output_tag(tag);
+    finish_buf_.set_output_tag(tag);
     if (!context_->initial_metadata_received_) {
-      collection_->finish_buf_.RecvInitialMetadata(context_);
+      finish_buf_.RecvInitialMetadata(context_);
     }
-    collection_->finish_buf_.RecvMessage(msg);
-    collection_->finish_buf_.AllowNoMessage();
-    collection_->finish_buf_.ClientRecvStatus(context_, status);
-    call_.PerformOps(&collection_->finish_buf_);
+    finish_buf_.RecvMessage(msg);
+    finish_buf_.AllowNoMessage();
+    finish_buf_.ClientRecvStatus(context_, status);
+    call_.PerformOps(&finish_buf_);
   }
 
  private:
-  ClientContext* context_;
+  ClientContext* const context_;
   Call call_;
 
-  class CallOpSetCollection : public CallOpSetCollectionInterface {
-   public:
-    SneakyCallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
-                    CallOpClientSendClose>
-        init_buf_;
-    CallOpSet<CallOpRecvInitialMetadata> meta_buf_;
-    CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>,
-              CallOpClientRecvStatus>
-        finish_buf_;
-  };
-  std::shared_ptr<CallOpSetCollection> collection_;
+  template <class W>
+  ClientAsyncResponseReader(Call call, ClientContext* context, const W& request)
+      : context_(context), call_(call) {
+    init_buf_.SendInitialMetadata(context->send_initial_metadata_,
+                                  context->initial_metadata_flags());
+    // TODO(ctiller): don't assert
+    GPR_CODEGEN_ASSERT(init_buf_.SendMessage(request).ok());
+    init_buf_.ClientSendClose();
+    call_.PerformOps(&init_buf_);
+  }
+
+  // disable operator new
+  static void* operator new(std::size_t size);
+  static void* operator new(std::size_t size, void* p) { return p; };
+
+  SneakyCallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+                  CallOpClientSendClose>
+      init_buf_;
+  CallOpSet<CallOpRecvInitialMetadata> meta_buf_;
+  CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>,
+            CallOpClientRecvStatus>
+      finish_buf_;
 };
 
 template <class W>
@@ -179,4 +190,12 @@ class ServerAsyncResponseWriter final : public ServerAsyncStreamingInterface {
 
 }  // namespace grpc
 
+namespace std {
+template <class R>
+class default_delete<grpc::ClientAsyncResponseReader<R>> {
+ public:
+  void operator()(void* p) {}
+};
+}
+
 #endif  // GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h
index 19a5ca2b2eead03e22543717fb7ea36812c57610..9fe2bbb75e7de5f57f0db4cb2d46d1777e1d2c56 100644
--- a/include/grpc++/impl/codegen/call.h
+++ b/include/grpc++/impl/codegen/call.h
@@ -34,6 +34,7 @@
 #ifndef GRPCXX_IMPL_CODEGEN_CALL_H
 #define GRPCXX_IMPL_CODEGEN_CALL_H
 
+#include <assert.h>
 #include <cstring>
 #include <functional>
 #include <map>
@@ -47,9 +48,9 @@
 #include <grpc++/impl/codegen/serialization_traits.h>
 #include <grpc++/impl/codegen/slice.h>
 #include <grpc++/impl/codegen/status.h>
-#include <grpc++/impl/codegen/status_helper.h>
 #include <grpc++/impl/codegen/string_ref.h>
 
+#include <grpc/impl/codegen/atm.h>
 #include <grpc/impl/codegen/compression_types.h>
 #include <grpc/impl/codegen/grpc_types.h>
 
@@ -63,29 +64,40 @@ class CallHook;
 class CompletionQueue;
 extern CoreCodegenInterface* g_core_codegen_interface;
 
+const char kBinaryErrorDetailsKey[] = "grpc-status-details-bin";
+
 // TODO(yangg) if the map is changed before we send, the pointers will be a
 // mess. Make sure it does not happen.
 inline grpc_metadata* FillMetadataArray(
-    const std::multimap<grpc::string, grpc::string>& metadata) {
-  if (metadata.empty()) {
+    const std::multimap<grpc::string, grpc::string>& metadata,
+    size_t* metadata_count, const grpc::string& optional_error_details) {
+  *metadata_count = metadata.size() + (optional_error_details.empty() ? 0 : 1);
+  if (*metadata_count == 0) {
     return nullptr;
   }
   grpc_metadata* metadata_array =
       (grpc_metadata*)(g_core_codegen_interface->gpr_malloc(
-          metadata.size() * sizeof(grpc_metadata)));
+          (*metadata_count) * sizeof(grpc_metadata)));
   size_t i = 0;
   for (auto iter = metadata.cbegin(); iter != metadata.cend(); ++iter, ++i) {
     metadata_array[i].key = SliceReferencingString(iter->first);
     metadata_array[i].value = SliceReferencingString(iter->second);
   }
+  if (!optional_error_details.empty()) {
+    metadata_array[i].key =
+        g_core_codegen_interface->grpc_slice_from_static_buffer(
+            kBinaryErrorDetailsKey, sizeof(kBinaryErrorDetailsKey) - 1);
+    metadata_array[i].value = SliceReferencingString(optional_error_details);
+  }
   return metadata_array;
 }
 
 /// Per-message write options.
 class WriteOptions {
  public:
-  WriteOptions() : flags_(0) {}
-  WriteOptions(const WriteOptions& other) : flags_(other.flags_) {}
+  WriteOptions() : flags_(0), last_message_(false) {}
+  WriteOptions(const WriteOptions& other)
+      : flags_(other.flags_), last_message_(other.last_message_) {}
 
   /// Clear all flags.
   inline void Clear() { flags_ = 0; }
@@ -141,6 +153,43 @@ class WriteOptions {
   /// \sa GRPC_WRITE_BUFFER_HINT
   inline bool get_buffer_hint() const { return GetBit(GRPC_WRITE_BUFFER_HINT); }
 
+  /// corked bit: aliases set_buffer_hint currently, with the intent that
+  /// set_buffer_hint will be removed in the future
+  inline WriteOptions& set_corked() {
+    SetBit(GRPC_WRITE_BUFFER_HINT);
+    return *this;
+  }
+
+  inline WriteOptions& clear_corked() {
+    ClearBit(GRPC_WRITE_BUFFER_HINT);
+    return *this;
+  }
+
+  inline bool is_corked() const { return GetBit(GRPC_WRITE_BUFFER_HINT); }
+
+  /// last-message bit: indicates this is the last message in a stream
+  /// client-side:  makes Write the equivalent of performing Write, WritesDone
+  /// in a single step
+  /// server-side:  hold the Write until the service handler returns (sync api)
+  /// or until Finish is called (async api)
+  inline WriteOptions& set_last_message() {
+    last_message_ = true;
+    return *this;
+  }
+
+  /// Clears flag indicating that this is the last message in a stream,
+  /// disabling coalescing.
+  inline WriteOptions& clear_last_messsage() {
+    last_message_ = false;
+    return *this;
+  }
+
+  /// Get value for the flag indicating that this is the last message, and
+  /// should be coalesced with trailing metadata.
+  ///
+  /// \sa GRPC_WRITE_LAST_MESSAGE
+  bool is_last_message() const { return last_message_; }
+
   WriteOptions& operator=(const WriteOptions& rhs) {
     flags_ = rhs.flags_;
     return *this;
@@ -154,6 +203,7 @@ class WriteOptions {
   bool GetBit(const uint32_t mask) const { return (flags_ & mask) != 0; }
 
   uint32_t flags_;
+  bool last_message_;
 };
 
 /// Default argument for CallOpSet. I is unused by the class, but can be
@@ -177,8 +227,8 @@ class CallOpSendInitialMetadata {
     maybe_compression_level_.is_set = false;
     send_ = true;
     flags_ = flags;
-    initial_metadata_count_ = metadata.size();
-    initial_metadata_ = FillMetadataArray(metadata);
+    initial_metadata_ =
+        FillMetadataArray(metadata, &initial_metadata_count_, "");
   }
 
   void set_compression_level(grpc_compression_level level) {
@@ -197,8 +247,10 @@ class CallOpSendInitialMetadata {
     op->data.send_initial_metadata.metadata = initial_metadata_;
     op->data.send_initial_metadata.maybe_compression_level.is_set =
         maybe_compression_level_.is_set;
-    op->data.send_initial_metadata.maybe_compression_level.level =
-        maybe_compression_level_.level;
+    if (maybe_compression_level_.is_set) {
+      op->data.send_initial_metadata.maybe_compression_level.level =
+          maybe_compression_level_.level;
+    }
   }
   void FinishOp(bool* status) {
     if (!send_) return;
@@ -224,7 +276,7 @@ class CallOpSendMessage {
   /// after use.
   template <class M>
   Status SendMessage(const M& message,
-                     const WriteOptions& options) GRPC_MUST_USE_RESULT;
+                     WriteOptions options) GRPC_MUST_USE_RESULT;
 
   template <class M>
   Status SendMessage(const M& message) GRPC_MUST_USE_RESULT;
@@ -252,8 +304,7 @@ class CallOpSendMessage {
 };
 
 template <class M>
-Status CallOpSendMessage::SendMessage(const M& message,
-                                      const WriteOptions& options) {
+Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) {
   write_options_ = options;
   return SerializationTraits<M>::Serialize(message, &send_buf_, &own_buf_);
 }
@@ -313,28 +364,6 @@ class CallOpRecvMessage {
   bool allow_not_getting_message_;
 };
 
-namespace CallOpGenericRecvMessageHelper {
-class DeserializeFunc {
- public:
-  virtual Status Deserialize(grpc_byte_buffer* buf) = 0;
-  virtual ~DeserializeFunc() {}
-};
-
-template <class R>
-class DeserializeFuncType final : public DeserializeFunc {
- public:
-  DeserializeFuncType(R* message) : message_(message) {}
-  Status Deserialize(grpc_byte_buffer* buf) override {
-    return SerializationTraits<R>::Deserialize(buf, message_);
-  }
-
-  ~DeserializeFuncType() override {}
-
- private:
-  R* message_;  // Not a managed pointer because management is external to this
-};
-}  // namespace CallOpGenericRecvMessageHelper
-
 class CallOpGenericRecvMessage {
  public:
   CallOpGenericRecvMessage()
@@ -342,11 +371,9 @@ class CallOpGenericRecvMessage {
 
   template <class R>
   void RecvMessage(R* message) {
-    // Use an explicit base class pointer to avoid resolution error in the
-    // following unique_ptr::reset for some old implementations.
-    CallOpGenericRecvMessageHelper::DeserializeFunc* func =
-        new CallOpGenericRecvMessageHelper::DeserializeFuncType<R>(message);
-    deserialize_.reset(func);
+    deserialize_ = [message](grpc_byte_buffer* buf) -> Status {
+      return SerializationTraits<R>::Deserialize(buf, message);
+    };
   }
 
   // Do not change status if no message is received.
@@ -369,7 +396,7 @@ class CallOpGenericRecvMessage {
     if (recv_buf_) {
       if (*status) {
         got_message = true;
-        *status = deserialize_->Deserialize(recv_buf_).ok();
+        *status = deserialize_(recv_buf_).ok();
       } else {
         got_message = false;
         g_core_codegen_interface->grpc_byte_buffer_destroy(recv_buf_);
@@ -380,11 +407,12 @@ class CallOpGenericRecvMessage {
         *status = false;
       }
     }
-    deserialize_.reset();
+    deserialize_ = DeserializeFunc();
   }
 
  private:
-  std::unique_ptr<CallOpGenericRecvMessageHelper::DeserializeFunc> deserialize_;
+  typedef std::function<Status(grpc_byte_buffer*)> DeserializeFunc;
+  DeserializeFunc deserialize_;
   grpc_byte_buffer* recv_buf_;
   bool allow_not_getting_message_;
 };
@@ -416,11 +444,12 @@ class CallOpServerSendStatus {
   void ServerSendStatus(
       const std::multimap<grpc::string, grpc::string>& trailing_metadata,
       const Status& status) {
-    trailing_metadata_count_ = trailing_metadata.size();
-    trailing_metadata_ = FillMetadataArray(trailing_metadata);
+    send_error_details_ = status.error_details();
+    trailing_metadata_ = FillMetadataArray(
+        trailing_metadata, &trailing_metadata_count_, send_error_details_);
     send_status_available_ = true;
-    send_status_code_ = static_cast<grpc_status_code>(GetCanonicalCode(status));
-    send_status_details_ = status.error_message();
+    send_status_code_ = static_cast<grpc_status_code>(status.error_code());
+    send_error_message_ = status.error_message();
   }
 
  protected:
@@ -432,9 +461,9 @@ class CallOpServerSendStatus {
         trailing_metadata_count_;
     op->data.send_status_from_server.trailing_metadata = trailing_metadata_;
     op->data.send_status_from_server.status = send_status_code_;
-    status_details_slice_ = SliceReferencingString(send_status_details_);
+    error_message_slice_ = SliceReferencingString(send_error_message_);
     op->data.send_status_from_server.status_details =
-        send_status_details_.empty() ? nullptr : &status_details_slice_;
+        send_error_message_.empty() ? nullptr : &error_message_slice_;
     op->flags = 0;
     op->reserved = NULL;
   }
@@ -448,10 +477,11 @@ class CallOpServerSendStatus {
  private:
   bool send_status_available_;
   grpc_status_code send_status_code_;
-  grpc::string send_status_details_;
+  grpc::string send_error_details_;
+  grpc::string send_error_message_;
   size_t trailing_metadata_count_;
   grpc_metadata* trailing_metadata_;
-  grpc_slice status_details_slice_;
+  grpc_slice error_message_slice_;
 };
 
 class CallOpRecvInitialMetadata {
@@ -490,6 +520,7 @@ class CallOpClientRecvStatus {
   void ClientRecvStatus(ClientContext* context, Status* status) {
     metadata_map_ = &context->trailing_metadata_;
     recv_status_ = status;
+    error_message_ = g_core_codegen_interface->grpc_empty_slice();
   }
 
  protected:
@@ -499,7 +530,7 @@ class CallOpClientRecvStatus {
     op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
     op->data.recv_status_on_client.trailing_metadata = metadata_map_->arr();
     op->data.recv_status_on_client.status = &status_code_;
-    op->data.recv_status_on_client.status_details = &status_details_;
+    op->data.recv_status_on_client.status_details = &error_message_;
     op->flags = 0;
     op->reserved = NULL;
   }
@@ -507,10 +538,17 @@ class CallOpClientRecvStatus {
   void FinishOp(bool* status) {
     if (recv_status_ == nullptr) return;
     metadata_map_->FillMap();
+    grpc::string binary_error_details;
+    auto iter = metadata_map_->map()->find(kBinaryErrorDetailsKey);
+    if (iter != metadata_map_->map()->end()) {
+      binary_error_details =
+          grpc::string(iter->second.begin(), iter->second.length());
+    }
     *recv_status_ = Status(static_cast<StatusCode>(status_code_),
-                           grpc::string(GRPC_SLICE_START_PTR(status_details_),
-                                        GRPC_SLICE_END_PTR(status_details_)));
-    g_core_codegen_interface->grpc_slice_unref(status_details_);
+                           grpc::string(GRPC_SLICE_START_PTR(error_message_),
+                                        GRPC_SLICE_END_PTR(error_message_)),
+                           binary_error_details);
+    g_core_codegen_interface->grpc_slice_unref(error_message_);
     recv_status_ = nullptr;
   }
 
@@ -518,20 +556,9 @@ class CallOpClientRecvStatus {
   MetadataMap* metadata_map_;
   Status* recv_status_;
   grpc_status_code status_code_;
-  grpc_slice status_details_;
+  grpc_slice error_message_;
 };
 
-/// An abstract collection of CallOpSet's, to be used whenever
-/// CallOpSet objects must be thought of as a group. Each member
-/// of the group should have a shared_ptr back to the collection,
-/// as will the object that instantiates the collection, allowing
-/// for automatic ref-counting. In practice, any actual use should
-/// derive from this base class. This is specifically necessary if
-/// some of the CallOpSet's in the collection are "Sneaky" and don't
-/// report back to the C++ layer CQ operations
-class CallOpSetCollectionInterface
-    : public std::enable_shared_from_this<CallOpSetCollectionInterface> {};
-
 /// An abstract collection of call ops, used to generate the
 /// grpc_call_op structure to pass down to the lower layers,
 /// and as it is-a CompletionQueueTag, also massages the final
@@ -539,18 +566,9 @@ class CallOpSetCollectionInterface
 /// API.
 class CallOpSetInterface : public CompletionQueueTag {
  public:
-  CallOpSetInterface() {}
   /// Fills in grpc_op, starting from ops[*nops] and moving
   /// upwards.
-  virtual void FillOps(grpc_op* ops, size_t* nops) = 0;
-
-  /// Mark this as belonging to a collection if needed
-  void SetCollection(std::shared_ptr<CallOpSetCollectionInterface> collection) {
-    collection_ = collection;
-  }
-
- protected:
-  std::shared_ptr<CallOpSetCollectionInterface> collection_;
+  virtual void FillOps(grpc_call* call, grpc_op* ops, size_t* nops) = 0;
 };
 
 /// Primary implementaiton of CallOpSetInterface.
@@ -571,13 +589,15 @@ class CallOpSet : public CallOpSetInterface,
                   public Op6 {
  public:
   CallOpSet() : return_tag_(this) {}
-  void FillOps(grpc_op* ops, size_t* nops) override {
+  void FillOps(grpc_call* call, grpc_op* ops, size_t* nops) override {
     this->Op1::AddOp(ops, nops);
     this->Op2::AddOp(ops, nops);
     this->Op3::AddOp(ops, nops);
     this->Op4::AddOp(ops, nops);
     this->Op5::AddOp(ops, nops);
     this->Op6::AddOp(ops, nops);
+    g_core_codegen_interface->grpc_call_ref(call);
+    call_ = call;
   }
 
   bool FinalizeResult(void** tag, bool* status) override {
@@ -588,7 +608,7 @@ class CallOpSet : public CallOpSetInterface,
     this->Op5::FinishOp(status);
     this->Op6::FinishOp(status);
     *tag = return_tag_;
-    collection_.reset();  // drop the ref at this point
+    g_core_codegen_interface->grpc_call_unref(call_);
     return true;
   }
 
@@ -596,6 +616,7 @@ class CallOpSet : public CallOpSetInterface,
 
  private:
   void* return_tag_;
+  grpc_call* call_;
 };
 
 /// A CallOpSet that does not post completions to the completion queue.
diff --git a/include/grpc++/impl/codegen/client_context.h b/include/grpc++/impl/codegen/client_context.h
index b91c7f65d434749447ee5fcca10d622f59925ef5..3c50e6ba9d4bddd4de822ced0e74e25b30914927 100644
--- a/include/grpc++/impl/codegen/client_context.h
+++ b/include/grpc++/impl/codegen/client_context.h
@@ -281,6 +281,17 @@ class ClientContext {
   /// \param algorithm The compression algorithm used for the client call.
   void set_compression_algorithm(grpc_compression_algorithm algorithm);
 
+  /// Flag whether the initial metadata should be \a corked
+  ///
+  /// If \a corked is true, then the initial metadata will be colasced with the
+  /// write of first message in the stream.
+  ///
+  /// \param corked The flag indicating whether the initial metadata is to be
+  /// corked or not.
+  void set_initial_metadata_corked(bool corked) {
+    initial_metadata_corked_ = corked;
+  }
+
   /// Return the peer uri in a string.
   ///
   /// \warning This value is never authenticated or subject to any security
@@ -357,7 +368,8 @@ class ClientContext {
            (cacheable_ ? GRPC_INITIAL_METADATA_CACHEABLE_REQUEST : 0) |
            (wait_for_ready_explicitly_set_
                 ? GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET
-                : 0);
+                : 0) |
+           (initial_metadata_corked_ ? GRPC_INITIAL_METADATA_CORKED : 0);
   }
 
   grpc::string authority() { return authority_; }
@@ -384,6 +396,7 @@ class ClientContext {
   PropagationOptions propagation_options_;
 
   grpc_compression_algorithm compression_algorithm_;
+  bool initial_metadata_corked_;
 };
 
 }  // namespace grpc
diff --git a/include/grpc++/impl/codegen/client_unary_call.h b/include/grpc++/impl/codegen/client_unary_call.h
index 201e52ae07376ff7467816aed3c12e07e1111af8..4bf35ae77854abea50c99b657e95a67a422bb34d 100644
--- a/include/grpc++/impl/codegen/client_unary_call.h
+++ b/include/grpc++/impl/codegen/client_unary_call.h
@@ -52,7 +52,9 @@ template <class InputMessage, class OutputMessage>
 Status BlockingUnaryCall(ChannelInterface* channel, const RpcMethod& method,
                          ClientContext* context, const InputMessage& request,
                          OutputMessage* result) {
-  CompletionQueue cq;
+  CompletionQueue cq(grpc_completion_queue_attributes{
+      GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
+      GRPC_CQ_DEFAULT_POLLING});  // Pluckable completion queue
   Call call(channel->CreateCall(method, context, &cq));
   CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
             CallOpRecvInitialMetadata, CallOpRecvMessage<OutputMessage>,
diff --git a/include/grpc++/impl/codegen/completion_queue.h b/include/grpc++/impl/codegen/completion_queue.h
index 03cecdc21c61e0c51b9fceacc38e1715b3c78c21..c8ab726b0f41183d725b6301dbd77ad6eab3eded 100644
--- a/include/grpc++/impl/codegen/completion_queue.h
+++ b/include/grpc++/impl/codegen/completion_queue.h
@@ -102,10 +102,9 @@ class CompletionQueue : private GrpcLibraryCodegen {
  public:
   /// Default constructor. Implicitly creates a \a grpc_completion_queue
   /// instance.
-  CompletionQueue() {
-    cq_ = g_core_codegen_interface->grpc_completion_queue_create(nullptr);
-    InitialAvalanching();  // reserve this for the future shutdown
-  }
+  CompletionQueue()
+      : CompletionQueue(grpc_completion_queue_attributes{
+            GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING}) {}
 
   /// Wrap \a take, taking ownership of the instance.
   ///
@@ -185,6 +184,16 @@ class CompletionQueue : private GrpcLibraryCodegen {
   };
   void CompleteAvalanching();
 
+ protected:
+  /// Private constructor of CompletionQueue only visible to friend classes
+  CompletionQueue(const grpc_completion_queue_attributes& attributes) {
+    cq_ = g_core_codegen_interface->grpc_completion_queue_create(
+        g_core_codegen_interface->grpc_completion_queue_factory_lookup(
+            &attributes),
+        &attributes, NULL);
+    InitialAvalanching();  // reserve this for the future shutdown
+  }
+
  private:
   // Friend synchronous wrappers so that they can access Pluck(), which is
   // a semi-private API geared towards the synchronous implementation.
@@ -237,6 +246,12 @@ class CompletionQueue : private GrpcLibraryCodegen {
 
   /// Performs a single polling pluck on \a tag.
   /// \warning Must not be mixed with calls to \a Next.
+  ///
+  /// TODO: sreek - This calls tag->FinalizeResult() even if the cq_ is already
+  /// shutdown. This is most likely a bug and if it is a bug, then change this
+  /// implementation to simple call the other TryPluck function with a zero
+  /// timeout. i.e:
+  ///      TryPluck(tag, gpr_time_0(GPR_CLOCK_REALTIME))
   void TryPluck(CompletionQueueTag* tag) {
     auto deadline = g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME);
     auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
@@ -248,6 +263,23 @@ class CompletionQueue : private GrpcLibraryCodegen {
     GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok));
   }
 
+  /// Performs a single polling pluck on \a tag. Calls tag->FinalizeResult if
+  /// the pluck() was successful and returned the tag.
+  ///
+  /// This exects tag->FinalizeResult (if called) to return 'false' i.e expects
+  /// that the tag is internal not something that is returned to the user.
+  void TryPluck(CompletionQueueTag* tag, gpr_timespec deadline) {
+    auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
+        cq_, tag, deadline, nullptr);
+    if (ev.type == GRPC_QUEUE_TIMEOUT || ev.type == GRPC_QUEUE_SHUTDOWN) {
+      return;
+    }
+
+    bool ok = ev.success != 0;
+    void* ignored = tag;
+    GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok));
+  }
+
   grpc_completion_queue* cq_;  // owned
 
   gpr_atm avalanches_in_flight_;
@@ -257,17 +289,19 @@ class CompletionQueue : private GrpcLibraryCodegen {
 /// by servers. Instantiated by \a ServerBuilder.
 class ServerCompletionQueue : public CompletionQueue {
  public:
-  bool IsFrequentlyPolled() { return is_frequently_polled_; }
+  bool IsFrequentlyPolled() { return polling_type_ != GRPC_CQ_NON_LISTENING; }
 
  private:
-  bool is_frequently_polled_;
+  grpc_cq_polling_type polling_type_;
   friend class ServerBuilder;
   /// \param is_frequently_polled Informs the GRPC library about whether the
   /// server completion queue would be actively polled (by calling Next() or
   /// AsyncNext()). By default all server completion queues are assumed to be
   /// frequently polled.
-  ServerCompletionQueue(bool is_frequently_polled = true)
-      : is_frequently_polled_(is_frequently_polled) {}
+  ServerCompletionQueue(grpc_cq_polling_type polling_type)
+      : CompletionQueue(grpc_completion_queue_attributes{
+            GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, polling_type}),
+        polling_type_(polling_type) {}
 };
 
 }  // namespace grpc
diff --git a/include/grpc++/impl/codegen/core_codegen.h b/include/grpc++/impl/codegen/core_codegen.h
index 754bf14b2592c2eb7b203ea7490a4ac206ad3246..a1593729ebc81368deaeaee4b35f2c26cbc79714 100644
--- a/include/grpc++/impl/codegen/core_codegen.h
+++ b/include/grpc++/impl/codegen/core_codegen.h
@@ -38,14 +38,25 @@
 
 #include <grpc++/impl/codegen/core_codegen_interface.h>
 #include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
 #include <grpc/impl/codegen/grpc_types.h>
 
 namespace grpc {
 
 /// Implementation of the core codegen interface.
-class CoreCodegen : public CoreCodegenInterface {
+class CoreCodegen final : public CoreCodegenInterface {
  private:
-  grpc_completion_queue* grpc_completion_queue_create(void* reserved) override;
+  virtual const grpc_completion_queue_factory*
+  grpc_completion_queue_factory_lookup(
+      const grpc_completion_queue_attributes* attributes) override;
+  virtual grpc_completion_queue* grpc_completion_queue_create(
+      const grpc_completion_queue_factory* factory,
+      const grpc_completion_queue_attributes* attributes,
+      void* reserved) override;
+  grpc_completion_queue* grpc_completion_queue_create_for_next(
+      void* reserved) override;
+  grpc_completion_queue* grpc_completion_queue_create_for_pluck(
+      void* reserved) override;
   void grpc_completion_queue_destroy(grpc_completion_queue* cq) override;
   grpc_event grpc_completion_queue_pluck(grpc_completion_queue* cq, void* tag,
                                          gpr_timespec deadline,
@@ -64,6 +75,10 @@ class CoreCodegen : public CoreCodegenInterface {
   void gpr_cv_signal(gpr_cv* cv) override;
   void gpr_cv_broadcast(gpr_cv* cv) override;
 
+  void grpc_call_ref(grpc_call* call) override;
+  void grpc_call_unref(grpc_call* call) override;
+  virtual void* grpc_call_arena_alloc(grpc_call* call, size_t length) override;
+
   void grpc_byte_buffer_destroy(grpc_byte_buffer* bb) override;
 
   int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
@@ -76,6 +91,7 @@ class CoreCodegen : public CoreCodegenInterface {
   grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slice,
                                                 size_t nslices) override;
 
+  grpc_slice grpc_empty_slice() override;
   grpc_slice grpc_slice_malloc(size_t length) override;
   void grpc_slice_unref(grpc_slice slice) override;
   grpc_slice grpc_slice_split_tail(grpc_slice* s, size_t split) override;
diff --git a/include/grpc++/impl/codegen/core_codegen_interface.h b/include/grpc++/impl/codegen/core_codegen_interface.h
index 45ea0403031b9c2dd1186a8c5d1386cd5221f50e..7cc3a824761cb26be1677fa6c11adb52b6f7b07e 100644
--- a/include/grpc++/impl/codegen/core_codegen_interface.h
+++ b/include/grpc++/impl/codegen/core_codegen_interface.h
@@ -59,7 +59,15 @@ class CoreCodegenInterface {
   virtual void assert_fail(const char* failed_assertion, const char* file,
                            int line) = 0;
 
+  virtual const grpc_completion_queue_factory*
+  grpc_completion_queue_factory_lookup(
+      const grpc_completion_queue_attributes* attributes) = 0;
   virtual grpc_completion_queue* grpc_completion_queue_create(
+      const grpc_completion_queue_factory* factory,
+      const grpc_completion_queue_attributes* attributes, void* reserved) = 0;
+  virtual grpc_completion_queue* grpc_completion_queue_create_for_next(
+      void* reserved) = 0;
+  virtual grpc_completion_queue* grpc_completion_queue_create_for_pluck(
       void* reserved) = 0;
   virtual void grpc_completion_queue_destroy(grpc_completion_queue* cq) = 0;
   virtual grpc_event grpc_completion_queue_pluck(grpc_completion_queue* cq,
@@ -94,6 +102,11 @@ class CoreCodegenInterface {
   virtual grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slice,
                                                         size_t nslices) = 0;
 
+  virtual void grpc_call_ref(grpc_call* call) = 0;
+  virtual void grpc_call_unref(grpc_call* call) = 0;
+  virtual void* grpc_call_arena_alloc(grpc_call* call, size_t length) = 0;
+
+  virtual grpc_slice grpc_empty_slice() = 0;
   virtual grpc_slice grpc_slice_malloc(size_t length) = 0;
   virtual void grpc_slice_unref(grpc_slice slice) = 0;
   virtual grpc_slice grpc_slice_split_tail(grpc_slice* s, size_t split) = 0;
diff --git a/include/grpc++/impl/codegen/grpc_library.h b/include/grpc++/impl/codegen/grpc_library.h
index 2b11aff2149b02ecc301ba1059e9fa09b7621e3c..3735d04e8c17a3f2ff87f30ec5cd0edaba69dfaf 100644
--- a/include/grpc++/impl/codegen/grpc_library.h
+++ b/include/grpc++/impl/codegen/grpc_library.h
@@ -51,18 +51,26 @@ extern GrpcLibraryInterface* g_glip;
 /// Classes that require gRPC to be initialized should inherit from this class.
 class GrpcLibraryCodegen {
  public:
-  GrpcLibraryCodegen() {
-    GPR_CODEGEN_ASSERT(g_glip &&
-                       "gRPC library not initialized. See "
-                       "grpc::internal::GrpcLibraryInitializer.");
-    g_glip->init();
+  GrpcLibraryCodegen(bool call_grpc_init = true) : grpc_init_called_(false) {
+    if (call_grpc_init) {
+      GPR_CODEGEN_ASSERT(g_glip &&
+                         "gRPC library not initialized. See "
+                         "grpc::internal::GrpcLibraryInitializer.");
+      g_glip->init();
+      grpc_init_called_ = true;
+    }
   }
   virtual ~GrpcLibraryCodegen() {
-    GPR_CODEGEN_ASSERT(g_glip &&
-                       "gRPC library not initialized. See "
-                       "grpc::internal::GrpcLibraryInitializer.");
-    g_glip->shutdown();
+    if (grpc_init_called_) {
+      GPR_CODEGEN_ASSERT(g_glip &&
+                         "gRPC library not initialized. See "
+                         "grpc::internal::GrpcLibraryInitializer.");
+      g_glip->shutdown();
+    }
   }
+
+ private:
+  bool grpc_init_called_;
 };
 
 }  // namespace grpc
diff --git a/include/grpc++/impl/codegen/proto_utils.h b/include/grpc++/impl/codegen/proto_utils.h
index 6df9de4fd223d1907fc39571cc222771b32df8d8..8c0c32bfc5d9bf757f769851d471a6f2f051c5c3 100644
--- a/include/grpc++/impl/codegen/proto_utils.h
+++ b/include/grpc++/impl/codegen/proto_utils.h
@@ -52,7 +52,7 @@ namespace internal {
 
 class GrpcBufferWriterPeer;
 
-const int kGrpcBufferWriterMaxBufferLength = 8192;
+const int kGrpcBufferWriterMaxBufferLength = 1024 * 1024;
 
 class GrpcBufferWriter final
     : public ::grpc::protobuf::io::ZeroCopyOutputStream {
diff --git a/include/grpc++/impl/codegen/server_context.h b/include/grpc++/impl/codegen/server_context.h
index bf9a9b6f1a52b52eb4bf3262cd6e7334cba1e4ce..ada304d5719c118210e24fd8554f305b60d8286e 100644
--- a/include/grpc++/impl/codegen/server_context.h
+++ b/include/grpc++/impl/codegen/server_context.h
@@ -39,8 +39,8 @@
 #include <vector>
 
 #include <grpc/impl/codegen/compression_types.h>
-#include <grpc/load_reporting.h>
 
+#include <grpc++/impl/codegen/completion_queue_tag.h>
 #include <grpc++/impl/codegen/config.h>
 #include <grpc++/impl/codegen/create_auth_context.h>
 #include <grpc++/impl/codegen/metadata_map.h>
@@ -212,6 +212,8 @@ class ServerContext {
   class CompletionOp;
 
   void BeginCompletionOp(Call* call);
+  // Return the tag queued by BeginCompletionOp()
+  CompletionQueueTag* GetCompletionOpTag();
 
   ServerContext(gpr_timespec deadline, grpc_metadata_array* arr);
 
diff --git a/include/grpc++/impl/codegen/server_interface.h b/include/grpc++/impl/codegen/server_interface.h
index bd1b36e8839399a2c4a48df44ca45e14df34ab28..31d55529efc9d28ed758de1478860e3a2352ca56 100644
--- a/include/grpc++/impl/codegen/server_interface.h
+++ b/include/grpc++/impl/codegen/server_interface.h
@@ -122,9 +122,7 @@ class ServerInterface : public CallHook {
   /// caller is required to keep all completion queues live until the server is
   /// destroyed.
   /// \param num_cqs How many completion queues does \a cqs hold.
-  ///
-  /// \return true on a successful shutdown.
-  virtual bool Start(ServerCompletionQueue** cqs, size_t num_cqs) = 0;
+  virtual void Start(ServerCompletionQueue** cqs, size_t num_cqs) = 0;
 
   virtual void ShutdownInternal(gpr_timespec deadline) = 0;
 
diff --git a/include/grpc++/impl/codegen/status.h b/include/grpc++/impl/codegen/status.h
index a509d311d4250e29b4826b322c04aa2982b57bce..31fd6cdbe78f68a1ad4f3854770231dc9920b5e5 100644
--- a/include/grpc++/impl/codegen/status.h
+++ b/include/grpc++/impl/codegen/status.h
@@ -47,10 +47,16 @@ class Status {
   /// Construct an OK instance.
   Status() : code_(StatusCode::OK) {}
 
-  /// Construct an instance with associated \a code and \a details (also
-  // referred to as "error_message").
-  Status(StatusCode code, const grpc::string& details)
-      : code_(code), details_(details) {}
+  /// Construct an instance with associated \a code and \a error_message
+  Status(StatusCode code, const grpc::string& error_message)
+      : code_(code), error_message_(error_message) {}
+
+  /// Construct an instance with \a code,  \a error_message and \a error_details
+  Status(StatusCode code, const grpc::string& error_message,
+         const grpc::string& error_details)
+      : code_(code),
+        error_message_(error_message),
+        binary_error_details_(error_details) {}
 
   // Pre-defined special status objects.
   /// An OK pre-defined instance.
@@ -61,14 +67,18 @@ class Status {
   /// Return the instance's error code.
   StatusCode error_code() const { return code_; }
   /// Return the instance's error message.
-  grpc::string error_message() const { return details_; }
+  grpc::string error_message() const { return error_message_; }
+  /// Return the (binary) error details.
+  // Usually it contains a serialized google.rpc.Status proto.
+  grpc::string error_details() const { return binary_error_details_; }
 
   /// Is the status OK?
   bool ok() const { return code_ == StatusCode::OK; }
 
  private:
   StatusCode code_;
-  grpc::string details_;
+  grpc::string error_message_;
+  grpc::string binary_error_details_;
 };
 
 }  // namespace grpc
diff --git a/include/grpc++/impl/codegen/sync_stream.h b/include/grpc++/impl/codegen/sync_stream.h
index 4d9b074e95f92b8db5a7641b277813056cf5dfd1..a010924cefee9406eb82e42eecb58cbd40791638 100644
--- a/include/grpc++/impl/codegen/sync_stream.h
+++ b/include/grpc++/impl/codegen/sync_stream.h
@@ -100,22 +100,40 @@ class WriterInterface {
  public:
   virtual ~WriterInterface() {}
 
-  /// Blocking write \a msg to the stream with options.
+  /// Blocking write \a msg to the stream with WriteOptions \a options.
   /// This is thread-safe with respect to \a Read
   ///
   /// \param msg The message to be written to the stream.
-  /// \param options Options affecting the write operation.
+  /// \param options The WriteOptions affecting the write operation.
   ///
   /// \return \a true on success, \a false when the stream has been closed.
-  virtual bool Write(const W& msg, const WriteOptions& options) = 0;
+  virtual bool Write(const W& msg, WriteOptions options) = 0;
 
-  /// Blocking write \a msg to the stream with default options.
+  /// Blocking write \a msg to the stream with default write options.
   /// This is thread-safe with respect to \a Read
   ///
   /// \param msg The message to be written to the stream.
   ///
   /// \return \a true on success, \a false when the stream has been closed.
   inline bool Write(const W& msg) { return Write(msg, WriteOptions()); }
+
+  /// Write \a msg and coalesce it with the writing of trailing metadata, using
+  /// WriteOptions \a options.
+  ///
+  /// For client, WriteLast is equivalent of performing Write and WritesDone in
+  /// a single step. \a msg and trailing metadata are coalesced and sent on wire
+  /// by calling this function.
+  /// For server, WriteLast buffers the \a msg. The writing of \a msg is held
+  /// until the service handler returns, where \a msg and trailing metadata are
+  /// coalesced and sent on wire. Note that WriteLast can only buffer \a msg up
+  /// to the flow control window size. If \a msg size is larger than the window
+  /// size, it will be sent on wire without buffering.
+  ///
+  /// \param[in] msg The message to be written to the stream.
+  /// \param[in] options The WriteOptions to be used to write this message.
+  void WriteLast(const W& msg, WriteOptions options) {
+    Write(msg, options.set_last_message());
+  }
 };
 
 /// Client-side interface for streaming reads of message of type \a R.
@@ -137,7 +155,11 @@ class ClientReader final : public ClientReaderInterface<R> {
   template <class W>
   ClientReader(ChannelInterface* channel, const RpcMethod& method,
                ClientContext* context, const W& request)
-      : context_(context), call_(channel->CreateCall(method, context, &cq_)) {
+      : context_(context),
+        cq_(grpc_completion_queue_attributes{
+            GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
+            GRPC_CQ_DEFAULT_POLLING}),  // Pluckable cq
+        call_(channel->CreateCall(method, context, &cq_)) {
     CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
               CallOpClientSendClose>
         ops;
@@ -209,15 +231,21 @@ class ClientWriter : public ClientWriterInterface<W> {
   template <class R>
   ClientWriter(ChannelInterface* channel, const RpcMethod& method,
                ClientContext* context, R* response)
-      : context_(context), call_(channel->CreateCall(method, context, &cq_)) {
+      : context_(context),
+        cq_(grpc_completion_queue_attributes{
+            GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
+            GRPC_CQ_DEFAULT_POLLING}),  // Pluckable cq
+        call_(channel->CreateCall(method, context, &cq_)) {
     finish_ops_.RecvMessage(response);
     finish_ops_.AllowNoMessage();
 
-    CallOpSet<CallOpSendInitialMetadata> ops;
-    ops.SendInitialMetadata(context->send_initial_metadata_,
-                            context->initial_metadata_flags());
-    call_.PerformOps(&ops);
-    cq_.Pluck(&ops);
+    if (!context_->initial_metadata_corked_) {
+      CallOpSet<CallOpSendInitialMetadata> ops;
+      ops.SendInitialMetadata(context->send_initial_metadata_,
+                              context->initial_metadata_flags());
+      call_.PerformOps(&ops);
+      cq_.Pluck(&ops);
+    }
   }
 
   void WaitForInitialMetadata() {
@@ -230,11 +258,24 @@ class ClientWriter : public ClientWriterInterface<W> {
   }
 
   using WriterInterface<W>::Write;
-  bool Write(const W& msg, const WriteOptions& options) override {
-    CallOpSet<CallOpSendMessage> ops;
+  bool Write(const W& msg, WriteOptions options) override {
+    CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+              CallOpClientSendClose>
+        ops;
+
+    if (options.is_last_message()) {
+      options.set_buffer_hint();
+      ops.ClientSendClose();
+    }
+    if (context_->initial_metadata_corked_) {
+      ops.SendInitialMetadata(context_->send_initial_metadata_,
+                              context_->initial_metadata_flags());
+      context_->set_initial_metadata_corked(false);
+    }
     if (!ops.SendMessage(msg, options).ok()) {
       return false;
     }
+
     call_.PerformOps(&ops);
     return cq_.Pluck(&ops);
   }
@@ -292,12 +333,18 @@ class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
   /// Blocking create a stream.
   ClientReaderWriter(ChannelInterface* channel, const RpcMethod& method,
                      ClientContext* context)
-      : context_(context), call_(channel->CreateCall(method, context, &cq_)) {
-    CallOpSet<CallOpSendInitialMetadata> ops;
-    ops.SendInitialMetadata(context->send_initial_metadata_,
-                            context->initial_metadata_flags());
-    call_.PerformOps(&ops);
-    cq_.Pluck(&ops);
+      : context_(context),
+        cq_(grpc_completion_queue_attributes{
+            GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
+            GRPC_CQ_DEFAULT_POLLING}),  // Pluckable cq
+        call_(channel->CreateCall(method, context, &cq_)) {
+    if (!context_->initial_metadata_corked_) {
+      CallOpSet<CallOpSendInitialMetadata> ops;
+      ops.SendInitialMetadata(context->send_initial_metadata_,
+                              context->initial_metadata_flags());
+      call_.PerformOps(&ops);
+      cq_.Pluck(&ops);
+    }
   }
 
   void WaitForInitialMetadata() override {
@@ -325,9 +372,24 @@ class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
   }
 
   using WriterInterface<W>::Write;
-  bool Write(const W& msg, const WriteOptions& options) override {
-    CallOpSet<CallOpSendMessage> ops;
-    if (!ops.SendMessage(msg, options).ok()) return false;
+  bool Write(const W& msg, WriteOptions options) override {
+    CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+              CallOpClientSendClose>
+        ops;
+
+    if (options.is_last_message()) {
+      options.set_buffer_hint();
+      ops.ClientSendClose();
+    }
+    if (context_->initial_metadata_corked_) {
+      ops.SendInitialMetadata(context_->send_initial_metadata_,
+                              context_->initial_metadata_flags());
+      context_->set_initial_metadata_corked(false);
+    }
+    if (!ops.SendMessage(msg, options).ok()) {
+      return false;
+    }
+
     call_.PerformOps(&ops);
     return cq_.Pluck(&ops);
   }
@@ -423,7 +485,10 @@ class ServerWriter final : public ServerWriterInterface<W> {
   }
 
   using WriterInterface<W>::Write;
-  bool Write(const W& msg, const WriteOptions& options) override {
+  bool Write(const W& msg, WriteOptions options) override {
+    if (options.is_last_message()) {
+      options.set_buffer_hint();
+    }
     CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> ops;
     if (!ops.SendMessage(msg, options).ok()) {
       return false;
@@ -485,7 +550,10 @@ class ServerReaderWriterBody final {
     return call_->cq()->Pluck(&ops) && ops.got_message;
   }
 
-  bool Write(const W& msg, const WriteOptions& options) {
+  bool Write(const W& msg, WriteOptions options) {
+    if (options.is_last_message()) {
+      options.set_buffer_hint();
+    }
     CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> ops;
     if (!ops.SendMessage(msg, options).ok()) {
       return false;
@@ -506,7 +574,7 @@ class ServerReaderWriterBody final {
   Call* const call_;
   ServerContext* const ctx_;
 };
-}
+}  // namespace internal
 
 // class to represent the user API for a bidirectional streaming call
 template <class W, class R>
@@ -523,7 +591,7 @@ class ServerReaderWriter final : public ServerReaderWriterInterface<W, R> {
   bool Read(R* msg) override { return body_.Read(msg); }
 
   using WriterInterface<W>::Write;
-  bool Write(const W& msg, const WriteOptions& options) override {
+  bool Write(const W& msg, WriteOptions options) override {
     return body_.Write(msg, options);
   }
 
@@ -562,8 +630,7 @@ class ServerUnaryStreamer final
   }
 
   using WriterInterface<ResponseType>::Write;
-  bool Write(const ResponseType& response,
-             const WriteOptions& options) override {
+  bool Write(const ResponseType& response, WriteOptions options) override {
     if (write_done_ || !read_done_) {
       return false;
     }
@@ -604,8 +671,7 @@ class ServerSplitStreamer final
   }
 
   using WriterInterface<ResponseType>::Write;
-  bool Write(const ResponseType& response,
-             const WriteOptions& options) override {
+  bool Write(const ResponseType& response, WriteOptions options) override {
     return read_done_ && body_.Write(response, options);
   }
 
diff --git a/include/grpc++/impl/codegen/thrift_serializer.h b/include/grpc++/impl/codegen/thrift_serializer.h
deleted file mode 100644
index 86bc7105c0ebe1e0793fbf037ede35d45bfbac8f..0000000000000000000000000000000000000000
--- a/include/grpc++/impl/codegen/thrift_serializer.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- *
- * 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 GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H
-#define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H
-
-#include <grpc/impl/codegen/byte_buffer_reader.h>
-#include <grpc/impl/codegen/slice.h>
-#include <thrift/protocol/TBinaryProtocol.h>
-#include <thrift/protocol/TCompactProtocol.h>
-#include <thrift/protocol/TProtocolException.h>
-#include <thrift/transport/TBufferTransports.h>
-#include <thrift/transport/TTransportUtils.h>
-#include <boost/make_shared.hpp>
-#include <memory>
-#include <stdexcept>
-#include <string>
-
-namespace apache {
-namespace thrift {
-namespace util {
-
-using apache::thrift::protocol::TBinaryProtocolT;
-using apache::thrift::protocol::TCompactProtocolT;
-using apache::thrift::protocol::TMessageType;
-using apache::thrift::protocol::TNetworkBigEndian;
-using apache::thrift::transport::TMemoryBuffer;
-using apache::thrift::transport::TBufferBase;
-using apache::thrift::transport::TTransport;
-
-template <typename Dummy, typename Protocol>
-class ThriftSerializer {
- public:
-  ThriftSerializer()
-      : prepared_(false),
-        last_deserialized_(false),
-        serialize_version_(false) {}
-
-  virtual ~ThriftSerializer() {}
-
-  // Serialize the passed type into the internal buffer
-  // and returns a pointer to internal buffer and its size
-  template <typename T>
-  void Serialize(const T& fields, const uint8_t** serialized_buffer,
-                 size_t* serialized_len) {
-    // prepare or reset buffer
-    if (!prepared_ || last_deserialized_) {
-      prepare();
-    } else {
-      buffer_->resetBuffer();
-    }
-    last_deserialized_ = false;
-
-    // if required serialize protocol version
-    if (serialize_version_) {
-      protocol_->writeMessageBegin("", TMessageType(0), 0);
-    }
-
-    // serialize fields into buffer
-    fields.write(protocol_.get());
-
-    // write the end of message
-    if (serialize_version_) {
-      protocol_->writeMessageEnd();
-    }
-
-    uint8_t* byte_buffer;
-    uint32_t byte_buffer_size;
-    buffer_->getBuffer(&byte_buffer, &byte_buffer_size);
-    *serialized_buffer = byte_buffer;
-    *serialized_len = byte_buffer_size;
-  }
-
-  // Serialize the passed type into the byte buffer
-  template <typename T>
-  void Serialize(const T& fields, grpc_byte_buffer** bp) {
-    const uint8_t* byte_buffer;
-    size_t byte_buffer_size;
-
-    Serialize(fields, &byte_buffer, &byte_buffer_size);
-
-    grpc_slice slice = grpc_slice_from_copied_buffer(
-        reinterpret_cast<const char*>(byte_buffer), byte_buffer_size);
-
-    *bp = grpc_raw_byte_buffer_create(&slice, 1);
-
-    grpc_slice_unref(slice);
-  }
-
-  // Deserialize the passed char array into  the passed type, returns the number
-  // of bytes that have been consumed from the passed string.
-  template <typename T>
-  uint32_t Deserialize(uint8_t* serialized_buffer, size_t length, T* fields) {
-    // prepare buffer if necessary
-    if (!prepared_) {
-      prepare();
-    }
-    last_deserialized_ = true;
-
-    // reset buffer transport
-    buffer_->resetBuffer(serialized_buffer, length);
-
-    // read the protocol version if necessary
-    if (serialize_version_) {
-      std::string name = "";
-      TMessageType mt = static_cast<TMessageType>(0);
-      int32_t seq_id = 0;
-      protocol_->readMessageBegin(name, mt, seq_id);
-    }
-
-    // deserialize buffer into fields
-    uint32_t len = fields->read(protocol_.get());
-
-    // read the end of message
-    if (serialize_version_) {
-      protocol_->readMessageEnd();
-    }
-
-    return len;
-  }
-
-  // Deserialize the passed byte buffer to passed type, returns the number
-  // of bytes consumed from byte buffer
-  template <typename T>
-  uint32_t Deserialize(grpc_byte_buffer* buffer, T* msg) {
-    grpc_byte_buffer_reader reader;
-    grpc_byte_buffer_reader_init(&reader, buffer);
-
-    grpc_slice slice = grpc_byte_buffer_reader_readall(&reader);
-
-    uint32_t len =
-        Deserialize(GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice), msg);
-
-    grpc_slice_unref(slice);
-
-    grpc_byte_buffer_reader_destroy(&reader);
-
-    return len;
-  }
-
-  // set serialization version flag
-  void SetSerializeVersion(bool value) { serialize_version_ = value; }
-
-  // Set the container size limit to deserialize
-  // This function should be called after buffer_ is initialized
-  void SetContainerSizeLimit(int32_t container_limit) {
-    if (!prepared_) {
-      prepare();
-    }
-    protocol_->setContainerSizeLimit(container_limit);
-  }
-
-  // Set the string size limit to deserialize
-  // This function should be called after buffer_ is initialized
-  void SetStringSizeLimit(int32_t string_limit) {
-    if (!prepared_) {
-      prepare();
-    }
-    protocol_->setStringSizeLimit(string_limit);
-  }
-
- private:
-  bool prepared_;
-  bool last_deserialized_;
-  boost::shared_ptr<TMemoryBuffer> buffer_;
-  std::shared_ptr<Protocol> protocol_;
-  bool serialize_version_;
-
-  void prepare() {
-    buffer_ = boost::make_shared<TMemoryBuffer>();
-    // create a protocol for the memory buffer transport
-    protocol_ = std::make_shared<Protocol>(buffer_);
-    prepared_ = true;
-  }
-
-};  // ThriftSerializer
-
-typedef ThriftSerializer<void, TBinaryProtocolT<TBufferBase, TNetworkBigEndian>>
-    ThriftSerializerBinary;
-typedef ThriftSerializer<void, TCompactProtocolT<TBufferBase>>
-    ThriftSerializerCompact;
-
-}  // namespace util
-}  // namespace thrift
-}  // namespace apache
-
-#endif  // GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index 3e544059747291fb3d352d1aaa9d8df5161242c5..2f7018e95bf515542185bf0bc077da724dc042eb 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -88,6 +88,9 @@ class Server final : public ServerInterface, private GrpcLibraryCodegen {
     virtual void PostSynchronousRequest(ServerContext* context) = 0;
     /// Called before server is started.
     virtual void PreServerStart(Server* server) {}
+    /// Called after a server port is added.
+    virtual void AddPort(Server* server, const grpc::string& addr,
+                         ServerCredentials* creds, int port) {}
   };
   /// Set the global callback object. Can only be called once. Does not take
   /// ownership of callbacks, and expects the pointed to object to be alive
@@ -175,9 +178,7 @@ class Server final : public ServerInterface, private GrpcLibraryCodegen {
   /// caller is required to keep all completion queues live until the server is
   /// destroyed.
   /// \param num_cqs How many completion queues does \a cqs hold.
-  ///
-  /// \return true on a successful shutdown.
-  bool Start(ServerCompletionQueue** cqs, size_t num_cqs) override;
+  void Start(ServerCompletionQueue** cqs, size_t num_cqs) override;
 
   void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) override;
 
diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h
index 2ac2f0a1ef485c2a1a6bf6184016407d73f22ac7..7ac23349c8437d3fc9dde1f512b4dd3fc204a966 100644
--- a/include/grpc++/server_builder.h
+++ b/include/grpc++/server_builder.h
@@ -39,6 +39,7 @@
 #include <memory>
 #include <vector>
 
+#include <grpc++/impl/channel_argument_option.h>
 #include <grpc++/impl/server_builder_option.h>
 #include <grpc++/impl/server_builder_plugin.h>
 #include <grpc++/support/config.h>
@@ -130,6 +131,13 @@ class ServerBuilder {
   /// Only useful if this is a Synchronous server.
   ServerBuilder& SetSyncServerOption(SyncServerOption option, int value);
 
+  /// Add a channel argument (an escape hatch to tuning core library parameters
+  /// directly)
+  template <class T>
+  ServerBuilder& AddChannelArgument(const grpc::string& arg, const T& value) {
+    return SetOption(MakeChannelArgumentOption(arg, value));
+  }
+
   /// Tries to bind \a server to the given \a addr.
   ///
   /// It can be invoked multiple times.
@@ -187,10 +195,7 @@ class ServerBuilder {
 
   struct SyncServerSettings {
     SyncServerSettings()
-        : num_cqs(1),
-          min_pollers(1),
-          max_pollers(INT_MAX),
-          cq_timeout_msec(1000) {}
+        : num_cqs(1), min_pollers(1), max_pollers(2), cq_timeout_msec(10000) {}
 
     // Number of server completion queues to create to listen to incoming RPCs.
     int num_cqs;
diff --git a/include/grpc++/support/channel_arguments.h b/include/grpc++/support/channel_arguments.h
index efdf7772ad73bdf479f38cbe1891ae49c2733ccf..61307d61942bd18ce3b0fdd5d6a8139b0530ca5b 100644
--- a/include/grpc++/support/channel_arguments.h
+++ b/include/grpc++/support/channel_arguments.h
@@ -54,7 +54,7 @@ class ResourceQuota;
 class ChannelArguments {
  public:
   ChannelArguments();
-  ~ChannelArguments() {}
+  ~ChannelArguments();
 
   ChannelArguments(const ChannelArguments& other);
   ChannelArguments& operator=(ChannelArguments other) {
@@ -117,10 +117,10 @@ class ChannelArguments {
 
   /// Return (by value) a c grpc_channel_args structure which points to
   /// arguments owned by this ChannelArguments instance
-  grpc_channel_args c_channel_args() {
+  grpc_channel_args c_channel_args() const {
     grpc_channel_args out;
     out.num_args = args_.size();
-    out.args = args_.empty() ? NULL : &args_[0];
+    out.args = args_.empty() ? NULL : const_cast<grpc_arg*>(&args_[0]);
     return out;
   }
 
diff --git a/include/grpc++/support/error_details.h b/include/grpc++/support/error_details.h
new file mode 100644
index 0000000000000000000000000000000000000000..411175fb46cab4cd758b106e6b3c581684989b67
--- /dev/null
+++ b/include/grpc++/support/error_details.h
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright 2017, 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 GRPCXX_SUPPORT_ERROR_DETAILS_H
+#define GRPCXX_SUPPORT_ERROR_DETAILS_H
+
+#include <grpc++/support/status.h>
+
+namespace google {
+namespace rpc {
+class Status;
+}  // namespace rpc
+}  // namespace google
+
+namespace grpc {
+
+// Maps a grpc::Status to a google::rpc::Status.
+// The given \a to object will be cleared.
+// On success, returns status with OK.
+// Returns status with INVALID_ARGUMENT, if failed to deserialize.
+// Returns status with FAILED_PRECONDITION, if \a to is nullptr.
+Status ExtractErrorDetails(const Status& from, ::google::rpc::Status* to);
+
+// Maps google::rpc::Status to a grpc::Status.
+// Returns OK on success.
+// Returns status with FAILED_PRECONDITION if \a to is nullptr.
+Status SetErrorDetails(const ::google::rpc::Status& from, Status* to);
+
+}  // namespace grpc
+
+#endif  // GRPCXX_SUPPORT_ERROR_DETAILS_H
diff --git a/include/grpc++/test/mock_stream.h b/include/grpc++/test/mock_stream.h
new file mode 100644
index 0000000000000000000000000000000000000000..f2de9472d6b957d0ef902da2ff44001e6cd473ff
--- /dev/null
+++ b/include/grpc++/test/mock_stream.h
@@ -0,0 +1,163 @@
+/*
+ *
+ * Copyright 2017, 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 GRPCXX_TEST_MOCK_STREAM_H
+#define GRPCXX_TEST_MOCK_STREAM_H
+
+#include <stdint.h>
+
+#include <gmock/gmock.h>
+#include <grpc++/impl/codegen/call.h>
+#include <grpc++/support/async_stream.h>
+#include <grpc++/support/async_unary_call.h>
+#include <grpc++/support/sync_stream.h>
+
+namespace grpc {
+namespace testing {
+
+template <class R>
+class MockClientReader : public ClientReaderInterface<R> {
+ public:
+  MockClientReader() = default;
+
+  // ClientStreamingInterface
+  MOCK_METHOD0_T(Finish, Status());
+
+  // ReaderInterface
+  MOCK_METHOD1_T(NextMessageSize, bool(uint32_t*));
+  MOCK_METHOD1_T(Read, bool(R*));
+
+  // ClientReaderInterface
+  MOCK_METHOD0_T(WaitForInitialMetadata, void());
+};
+
+template <class W>
+class MockClientWriter : public ClientWriterInterface<W> {
+ public:
+  MockClientWriter() = default;
+
+  // ClientStreamingInterface
+  MOCK_METHOD0_T(Finish, Status());
+
+  // WriterInterface
+  MOCK_METHOD2_T(Write, bool(const W&, const WriteOptions));
+
+  // ClientWriterInterface
+  MOCK_METHOD0_T(WritesDone, bool());
+};
+
+template <class W, class R>
+class MockClientReaderWriter : public ClientReaderWriterInterface<W, R> {
+ public:
+  MockClientReaderWriter() = default;
+
+  // ClientStreamingInterface
+  MOCK_METHOD0_T(Finish, Status());
+
+  // ReaderInterface
+  MOCK_METHOD1_T(NextMessageSize, bool(uint32_t*));
+  MOCK_METHOD1_T(Read, bool(R*));
+
+  // WriterInterface
+  MOCK_METHOD2_T(Write, bool(const W&, const WriteOptions));
+
+  // ClientReaderWriterInterface
+  MOCK_METHOD0_T(WaitForInitialMetadata, void());
+  MOCK_METHOD0_T(WritesDone, bool());
+};
+
+// TODO: We do not support mocking an async RPC for now.
+
+template <class R>
+class MockClientAsyncResponseReader
+    : public ClientAsyncResponseReaderInterface<R> {
+ public:
+  MockClientAsyncResponseReader() = default;
+
+  MOCK_METHOD1_T(ReadInitialMetadata, void(void*));
+  MOCK_METHOD3_T(Finish, void(R*, Status*, void*));
+};
+
+template <class R>
+class MockClientAsyncReader : public ClientAsyncReaderInterface<R> {
+ public:
+  MockClientAsyncReader() = default;
+
+  // ClientAsyncStreamingInterface
+  MOCK_METHOD1_T(ReadInitialMetadata, void(void*));
+  MOCK_METHOD2_T(Finish, void(Status*, void*));
+
+  // AsyncReaderInterface
+  MOCK_METHOD2_T(Read, void(R*, void*));
+};
+
+template <class W>
+class MockClientAsyncWriter : public ClientAsyncWriterInterface<W> {
+ public:
+  MockClientAsyncWriter() = default;
+
+  // ClientAsyncStreamingInterface
+  MOCK_METHOD1_T(ReadInitialMetadata, void(void*));
+  MOCK_METHOD2_T(Finish, void(Status*, void*));
+
+  // AsyncWriterInterface
+  MOCK_METHOD2_T(Write, void(const W&, void*));
+
+  // ClientAsyncWriterInterface
+  MOCK_METHOD1_T(WritesDone, void(void*));
+};
+
+template <class W, class R>
+class MockClientAsyncReaderWriter
+    : public ClientAsyncReaderWriterInterface<W, R> {
+ public:
+  MockClientAsyncReaderWriter() = default;
+
+  // ClientAsyncStreamingInterface
+  MOCK_METHOD1_T(ReadInitialMetadata, void(void*));
+  MOCK_METHOD2_T(Finish, void(Status*, void*));
+
+  // AsyncWriterInterface
+  MOCK_METHOD2_T(Write, void(const W&, void*));
+
+  // AsyncReaderInterface
+  MOCK_METHOD2_T(Read, void(R*, void*));
+
+  // ClientAsyncReaderWriterInterface
+  MOCK_METHOD1_T(WritesDone, void(void*));
+};
+
+}  // namespace testing
+}  // namespace grpc
+
+#endif  // GRPCXX_TEST_MOCK_STREAM_H
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index 1b33d48c02342c140530fb2002d354c7901af988..1eeb075927d372d1bf76b0a7d9187f54e39aae4a 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -93,8 +93,26 @@ GRPCAPI const char *grpc_version_string(void);
 /** Return a string specifying what the 'g' in gRPC stands for */
 GRPCAPI const char *grpc_g_stands_for(void);
 
+/** Returns the completion queue factory based on the attributes. MAY return a
+    NULL if no factory can be found */
+GRPCAPI const grpc_completion_queue_factory *
+grpc_completion_queue_factory_lookup(
+    const grpc_completion_queue_attributes *attributes);
+
+/** Helper function to create a completion queue with grpc_cq_completion_type
+    of GRPC_CQ_NEXT and grpc_cq_polling_type of GRPC_CQ_DEFAULT_POLLING */
+GRPCAPI grpc_completion_queue *grpc_completion_queue_create_for_next(
+    void *reserved);
+
+/** Helper function to create a completion queue with grpc_cq_completion_type
+    of GRPC_CQ_PLUCK and grpc_cq_polling_type of GRPC_CQ_DEFAULT_POLLING */
+GRPCAPI grpc_completion_queue *grpc_completion_queue_create_for_pluck(
+    void *reserved);
+
 /** Create a completion queue */
-GRPCAPI grpc_completion_queue *grpc_completion_queue_create(void *reserved);
+GRPCAPI grpc_completion_queue *grpc_completion_queue_create(
+    const grpc_completion_queue_factory *factory,
+    const grpc_completion_queue_attributes *attributes, void *reserved);
 
 /** Blocks until an event is available, the completion queue is being shut down,
     or deadline is reached.
@@ -198,6 +216,10 @@ GRPCAPI grpc_call *grpc_channel_create_registered_call(
     grpc_completion_queue *completion_queue, void *registered_call_handle,
     gpr_timespec deadline, void *reserved);
 
+/** Allocate memory in the grpc_call arena: this memory is automatically
+    discarded at call completion */
+GRPCAPI void *grpc_call_arena_alloc(grpc_call *call, size_t size);
+
 /** Start a batch of operations defined in the array ops; when complete, post a
     completion of type 'tag' to the completion queue bound to the call.
     The order of ops specified in the batch has no significance.
@@ -229,12 +251,6 @@ GRPCAPI grpc_call_error grpc_call_start_batch(grpc_call *call,
     functionality. Instead, use grpc_auth_context. */
 GRPCAPI char *grpc_call_get_peer(grpc_call *call);
 
-struct grpc_load_reporting_cost_context;
-
-/* Associate costs contained in \a cost_context to \a call. */
-GRPCAPI void grpc_call_set_load_reporting_cost_context(
-    grpc_call *call, struct grpc_load_reporting_cost_context *context);
-
 struct census_context;
 
 /** Set census context for a call; Must be called before first call to
@@ -280,7 +296,7 @@ GRPCAPI void grpc_channel_destroy(grpc_channel *channel);
 /** Called by clients to cancel an RPC on the server.
     Can be called multiple times, from any thread.
     THREAD-SAFETY grpc_call_cancel and grpc_call_cancel_with_status
-    are thread-safe, and can be called at any point before grpc_call_destroy
+    are thread-safe, and can be called at any point before grpc_call_unref
     is called.*/
 GRPCAPI grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved);
 
@@ -295,9 +311,13 @@ GRPCAPI grpc_call_error grpc_call_cancel_with_status(grpc_call *call,
                                                      const char *description,
                                                      void *reserved);
 
-/** Destroy a call.
-    THREAD SAFETY: grpc_call_destroy is thread-compatible */
-GRPCAPI void grpc_call_destroy(grpc_call *call);
+/** Ref a call.
+    THREAD SAFETY: grpc_call_unref is thread-compatible */
+GRPCAPI void grpc_call_ref(grpc_call *call);
+
+/** Unref a call.
+    THREAD SAFETY: grpc_call_unref is thread-compatible */
+GRPCAPI void grpc_call_unref(grpc_call *call);
 
 /** Request notification of a new call.
     Once a call is received, a notification tagged with \a tag_new is added to
@@ -358,15 +378,6 @@ GRPCAPI void grpc_server_register_completion_queue(grpc_server *server,
                                                    grpc_completion_queue *cq,
                                                    void *reserved);
 
-/** Register a non-listening completion queue with the server. This API is
-    similar to grpc_server_register_completion_queue except that the server will
-    not use this completion_queue to listen to any incoming channels.
-
-    Registering a non-listening completion queue will have negative performance
-    impact and hence this API is not recommended for production use cases. */
-GRPCAPI void grpc_server_register_non_listening_completion_queue(
-    grpc_server *server, grpc_completion_queue *q, void *reserved);
-
 /** Add a HTTP2 over plaintext over tcp listener.
     Returns bound port number on success, 0 on failure.
     REQUIRES: server not started */
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index 79199cc5d68fc173359a473461b417fd4a02f637..5d3cc4fd674eb5f4e4dc9dde389745009bbbda05 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -158,7 +158,7 @@ typedef struct {
 } grpc_ssl_pem_key_cert_pair;
 
 /* Creates an SSL credentials object.
-   - pem_roots_cert is the NULL-terminated string containing the PEM encoding
+   - pem_root_certs is the NULL-terminated string containing the PEM encoding
      of the server root certificates. If this parameter is NULL, the
      implementation will first try to dereference the file pointed by the
      GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment variable, and if that fails,
diff --git a/include/grpc/impl/codegen/atm.h b/include/grpc/impl/codegen/atm.h
index ae00fb0f16989565732c1ef669d82ed547f4e6d4..4bd572d6d1841eadaf4c40eac0344ee67b534e68 100644
--- a/include/grpc/impl/codegen/atm.h
+++ b/include/grpc/impl/codegen/atm.h
@@ -92,4 +92,9 @@
 #error could not determine platform for atm
 #endif
 
+/** Adds \a delta to \a *value, clamping the result to the range specified
+    by \a min and \a max.  Returns the new value. */
+gpr_atm gpr_atm_no_barrier_clamped_add(gpr_atm *value, gpr_atm delta,
+                                       gpr_atm min, gpr_atm max);
+
 #endif /* GRPC_IMPL_CODEGEN_ATM_H */
diff --git a/include/grpc/impl/codegen/atm_gcc_atomic.h b/include/grpc/impl/codegen/atm_gcc_atomic.h
index 4bd3b257413831be89dba126b2c2f976f8d40e99..d52975ce976ab259ed865570f7a5eaae9370ed29 100644
--- a/include/grpc/impl/codegen/atm_gcc_atomic.h
+++ b/include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -39,6 +39,7 @@
 #include <grpc/impl/codegen/port_platform.h>
 
 typedef intptr_t gpr_atm;
+#define GPR_ATM_MAX INTPTR_MAX
 
 #ifdef GPR_LOW_LEVEL_COUNTERS
 extern gpr_atm gpr_counter_atm_cas;
@@ -85,6 +86,11 @@ static __inline int gpr_atm_rel_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
       p, &o, n, 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED));
 }
 
+static __inline int gpr_atm_full_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
+  return GPR_ATM_INC_CAS_THEN(__atomic_compare_exchange_n(
+      p, &o, n, 0, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED));
+}
+
 #define gpr_atm_full_xchg(p, n) \
   GPR_ATM_INC_CAS_THEN(__atomic_exchange_n((p), (n), __ATOMIC_ACQ_REL))
 
diff --git a/include/grpc/impl/codegen/atm_gcc_sync.h b/include/grpc/impl/codegen/atm_gcc_sync.h
index 9aa2b43189ffd0bef4c60335b8bfff64a1c10223..b537e48f0f3ba9aada1c38d3823d2844b1d4b539 100644
--- a/include/grpc/impl/codegen/atm_gcc_sync.h
+++ b/include/grpc/impl/codegen/atm_gcc_sync.h
@@ -39,6 +39,7 @@
 #include <grpc/impl/codegen/port_platform.h>
 
 typedef intptr_t gpr_atm;
+#define GPR_ATM_MAX INTPTR_MAX
 
 #define GPR_ATM_COMPILE_BARRIER_() __asm__ __volatile__("" : : : "memory")
 
@@ -83,6 +84,7 @@ static __inline void gpr_atm_no_barrier_store(gpr_atm *p, gpr_atm value) {
 #define gpr_atm_no_barrier_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
 #define gpr_atm_acq_cas(p, o, n) (__sync_bool_compare_and_swap((p), (o), (n)))
 #define gpr_atm_rel_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
+#define gpr_atm_full_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
 
 static __inline gpr_atm gpr_atm_full_xchg(gpr_atm *p, gpr_atm n) {
   gpr_atm cur;
diff --git a/include/grpc/impl/codegen/atm_windows.h b/include/grpc/impl/codegen/atm_windows.h
index 0ab70b95c4a44fc0a541e5238b387d9833083fc8..a533651f6f9bf7aa37f61dea2406fd37b2e9f414 100644
--- a/include/grpc/impl/codegen/atm_windows.h
+++ b/include/grpc/impl/codegen/atm_windows.h
@@ -38,6 +38,7 @@
 #include <grpc/impl/codegen/port_platform.h>
 
 typedef intptr_t gpr_atm;
+#define GPR_ATM_MAX INTPTR_MAX
 
 #define gpr_atm_full_barrier MemoryBarrier
 
@@ -94,6 +95,16 @@ static __inline int gpr_atm_rel_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
 #endif
 }
 
+static __inline int gpr_atm_full_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
+#ifdef GPR_ARCH_64
+  return o == (gpr_atm)InterlockedCompareExchange64((volatile LONGLONG *)p,
+                                                    (LONGLONG)n, (LONGLONG)o);
+#else
+  return o == (gpr_atm)InterlockedCompareExchange((volatile LONG *)p, (LONG)n,
+                                                  (LONG)o);
+#endif
+}
+
 static __inline gpr_atm gpr_atm_no_barrier_fetch_add(gpr_atm *p,
                                                      gpr_atm delta) {
   /* Use the CAS operation to get pointer-sized fetch and add */
diff --git a/include/grpc/impl/codegen/compression_types.h b/include/grpc/impl/codegen/compression_types.h
index 170d99f431bbb5a657f82efddf32f05a35eb8a14..a563711e3269bee3a43a486251b1cc22df3d4e5b 100644
--- a/include/grpc/impl/codegen/compression_types.h
+++ b/include/grpc/impl/codegen/compression_types.h
@@ -34,8 +34,7 @@
 #ifndef GRPC_IMPL_CODEGEN_COMPRESSION_TYPES_H
 #define GRPC_IMPL_CODEGEN_COMPRESSION_TYPES_H
 
-#include <stdbool.h>
-#include <stdint.h>
+#include <grpc/impl/codegen/port_platform.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -101,7 +100,7 @@ typedef struct grpc_compression_options {
    * precedence over \a default_algorithm.
    * TODO(dgq): currently only available for server channels. */
   struct {
-    bool is_set;
+    int is_set;
     grpc_compression_level level;
   } default_level;
 
@@ -109,7 +108,7 @@ typedef struct grpc_compression_options {
    * call specific settings. This option corresponds to the channel argument key
    * behind \a GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM. */
   struct {
-    bool is_set;
+    int is_set;
     grpc_compression_algorithm algorithm;
   } default_algorithm;
 
diff --git a/include/grpc/impl/codegen/gpr_types.h b/include/grpc/impl/codegen/gpr_types.h
index ed9976f4296b5c0a442f407ef87a5fd45161a5e3..34d8156b6158ffed95126f538e1bd572f1b4c0e4 100644
--- a/include/grpc/impl/codegen/gpr_types.h
+++ b/include/grpc/impl/codegen/gpr_types.h
@@ -37,7 +37,6 @@
 #include <grpc/impl/codegen/port_platform.h>
 
 #include <stddef.h>
-#include <stdint.h>
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index e5c731304cd7a98ca99d652413bba7a80114c3f3..4738e02ecba62fbdd7d393733d8f58668cec9a50 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -34,6 +34,8 @@
 #ifndef GRPC_IMPL_CODEGEN_GRPC_TYPES_H
 #define GRPC_IMPL_CODEGEN_GRPC_TYPES_H
 
+#include <grpc/impl/codegen/port_platform.h>
+
 #include <grpc/impl/codegen/compression_types.h>
 #include <grpc/impl/codegen/exec_ctx_fwd.h>
 #include <grpc/impl/codegen/gpr_types.h>
@@ -41,7 +43,6 @@
 #include <grpc/impl/codegen/status.h>
 
 #include <stddef.h>
-#include <stdint.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -87,6 +88,9 @@ typedef struct grpc_call grpc_call;
 /** The Socket Mutator interface allows changes on socket options */
 typedef struct grpc_socket_mutator grpc_socket_mutator;
 
+/** The Socket Factory interface creates and binds sockets */
+typedef struct grpc_socket_factory grpc_socket_factory;
+
 /** Type specifier for grpc_arg */
 typedef enum {
   GRPC_ARG_STRING,
@@ -149,6 +153,9 @@ typedef struct {
 #define GRPC_ARG_ENABLE_CENSUS "grpc.census"
 /** If non-zero, enable load reporting. */
 #define GRPC_ARG_ENABLE_LOAD_REPORTING "grpc.loadreporting"
+/** Request that optional features default to off (regardless of what they
+    usually default to) - to enable tight control over what gets enabled */
+#define GRPC_ARG_MINIMAL_STACK "grpc.minimal_stack"
 /** Maximum number of concurrent incoming streams to allow on a http2
     connection. Int valued. */
 #define GRPC_ARG_MAX_CONCURRENT_STREAMS "grpc.max_concurrent_streams"
@@ -160,6 +167,21 @@ typedef struct {
 /** Maximum message length that the channel can send. Int valued, bytes.
     -1 means unlimited. */
 #define GRPC_ARG_MAX_SEND_MESSAGE_LENGTH "grpc.max_send_message_length"
+/** Maximum time that a channel may have no outstanding rpcs. Int valued,
+    milliseconds. INT_MAX means unlimited. */
+#define GRPC_ARG_MAX_CONNECTION_IDLE_MS "grpc.max_connection_idle_ms"
+/** Maximum time that a channel may exist. Int valued, milliseconds. INT_MAX
+   means unlimited. */
+#define GRPC_ARG_MAX_CONNECTION_AGE_MS "grpc.max_connection_age_ms"
+/** Grace period after the chennel reaches its max age. Int valued,
+   milliseconds. INT_MAX means unlimited. */
+#define GRPC_ARG_MAX_CONNECTION_AGE_GRACE_MS "grpc.max_connection_age_grace_ms"
+/** Enable/disable support for per-message compression. Defaults to 1, unless
+    GRPC_ARG_MINIMAL_STACK is enabled, in which case it defaults to 0. */
+#define GRPC_ARG_ENABLE_PER_MESSAGE_COMPRESSION "grpc.per_message_compression"
+/** Enable/disable support for deadline checking. Defaults to 1, unless
+    GRPC_ARG_MINIMAL_STACK is enabled, in which case it defaults to 0 */
+#define GRPC_ARG_ENABLE_DEADLINE_CHECKS "grpc.enable_deadline_checking"
 /** Initial sequence number for http2 transports. Int valued. */
 #define GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER \
   "grpc.http2.initial_sequence_number"
@@ -184,25 +206,40 @@ typedef struct {
 /** Minimum time (in milliseconds) between successive ping frames being sent */
 #define GRPC_ARG_HTTP2_MIN_TIME_BETWEEN_PINGS_MS \
   "grpc.http2.min_time_between_pings_ms"
+/* Channel arg to override the http2 :scheme header */
+#define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme"
 /** How many pings can we send before needing to send a data frame or header
     frame?
     (0 indicates that an infinite number of pings can be sent without sending
      a data frame or header frame) */
 #define GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA \
   "grpc.http2.max_pings_without_data"
+/** How many misbehaving pings the server can bear before sending goaway and
+    closing the transport?
+    (0 indicates that the server can bear an infinite number of misbehaving
+     pings) */
+#define GRPC_ARG_HTTP2_MAX_PING_STRIKES "grpc.http2.max_ping_strikes"
+/** Minimum allowed time between two pings without sending any data frame. Int
+    valued, seconds */
+#define GRPC_ARG_HTTP2_MIN_PING_INTERVAL_WITHOUT_DATA_MS \
+  "grpc.http2.min_ping_interval_without_data_ms"
 /** How much data are we willing to queue up per stream if
     GRPC_WRITE_BUFFER_HINT is set? This is an upper bound */
 #define GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE "grpc.http2.write_buffer_size"
-/** After a duration of this time the client pings the server to see if the
-    transport is still alive. Int valued, seconds. */
-#define GRPC_ARG_HTTP2_KEEPALIVE_TIME "grpc.http2.keepalive_time"
-/** After waiting for a duration of this time, if the client does not receive
-    the ping ack, it will close the transport. Int valued, seconds. */
-#define GRPC_ARG_HTTP2_KEEPALIVE_TIMEOUT "grpc.http2.keepalive_timeout"
+/** Should we allow receipt of true-binary data on http2 connections?
+    Defaults to on (1) */
+#define GRPC_ARG_HTTP2_ENABLE_TRUE_BINARY "grpc.http2.true_binary"
+/** After a duration of this time the client/server pings its peer to see if the
+    transport is still alive. Int valued, milliseconds. */
+#define GRPC_ARG_KEEPALIVE_TIME_MS "grpc.keepalive_time_ms"
+/** After waiting for a duration of this time, if the keepalive ping sender does
+    not receive the ping ack, it will close the transport. Int valued,
+    milliseconds. */
+#define GRPC_ARG_KEEPALIVE_TIMEOUT_MS "grpc.keepalive_timeout_ms"
 /** Is it permissible to send keepalive pings without any outstanding streams.
     Int valued, 0(false)/1(true). */
-#define GRPC_ARG_HTTP2_KEEPALIVE_PERMIT_WITHOUT_CALLS \
-  "grpc.http2.keepalive_permit_without_calls"
+#define GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS \
+  "grpc.keepalive_permit_without_calls"
 /** Default authority to pass if none specified on call construction. A string.
  * */
 #define GRPC_ARG_DEFAULT_AUTHORITY "grpc.default_authority"
@@ -212,6 +249,8 @@ typedef struct {
 /** Secondary user agent: goes at the end of the user-agent metadata
     sent on each request. A string. */
 #define GRPC_ARG_SECONDARY_USER_AGENT_STRING "grpc.secondary_user_agent"
+/** The minimum time between subsequent connection attempts, in ms */
+#define GRPC_ARG_MIN_RECONNECT_BACKOFF_MS "grpc.min_reconnect_backoff_ms"
 /** The maximum time between subsequent connection attempts, in ms */
 #define GRPC_ARG_MAX_RECONNECT_BACKOFF_MS "grpc.max_reconnect_backoff_ms"
 /** The time between the first and second connection attempts, in ms */
@@ -240,10 +279,23 @@ typedef struct {
 #define GRPC_ARG_LB_POLICY_NAME "grpc.lb_policy_name"
 /** The grpc_socket_mutator instance that set the socket options. A pointer. */
 #define GRPC_ARG_SOCKET_MUTATOR "grpc.socket_mutator"
+/** The grpc_socket_factory instance to create and bind sockets. A pointer. */
+#define GRPC_ARG_SOCKET_FACTORY "grpc.socket_factory"
 /** If non-zero, Cronet transport will coalesce packets to fewer frames when
  * possible. */
 #define GRPC_ARG_USE_CRONET_PACKET_COALESCING \
   "grpc.use_cronet_packet_coalescing"
+/* Channel arg (integer) setting how large a slice to try and read from the wire
+each time recvmsg (or equivalent) is called */
+#define GRPC_ARG_TCP_READ_CHUNK_SIZE "grpc.experimental.tcp_read_chunk_size"
+#define GRPC_TCP_DEFAULT_READ_SLICE_SIZE 8192
+#define GRPC_ARG_TCP_MIN_READ_CHUNK_SIZE \
+  "grpc.experimental.tcp_min_read_chunk_size"
+#define GRPC_ARG_TCP_MAX_READ_CHUNK_SIZE \
+  "grpc.experimental.tcp_max_read_chunk_size"
+/* Timeout in milliseconds to use for calls to the grpclb load balancer.
+   If 0 or unset, the balancer calls will have no deadline. */
+#define GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS "grpc.grpclb_timeout_ms"
 /** \} */
 
 /** Result of a grpc call. If the caller satisfies the prerequisites of a
@@ -311,13 +363,16 @@ typedef enum grpc_call_error {
 /** Signal that GRPC_INITIAL_METADATA_WAIT_FOR_READY was explicitly set
     by the calling application. */
 #define GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET (0x00000080u)
+/** Signal that the initial metadata should be corked */
+#define GRPC_INITIAL_METADATA_CORKED (0x00000100u)
 
 /** Mask of all valid flags */
-#define GRPC_INITIAL_METADATA_USED_MASK       \
-  (GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST | \
-   GRPC_INITIAL_METADATA_WAIT_FOR_READY |     \
-   GRPC_INITIAL_METADATA_CACHEABLE_REQUEST |  \
-   GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET)
+#define GRPC_INITIAL_METADATA_USED_MASK                  \
+  (GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST |            \
+   GRPC_INITIAL_METADATA_WAIT_FOR_READY |                \
+   GRPC_INITIAL_METADATA_CACHEABLE_REQUEST |             \
+   GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET | \
+   GRPC_INITIAL_METADATA_CORKED)
 
 /** A single metadata element */
 typedef struct grpc_metadata {
@@ -352,8 +407,11 @@ typedef enum grpc_completion_type {
 typedef struct grpc_event {
   /** The type of the completion. */
   grpc_completion_type type;
-  /** non-zero if the operation was successful, 0 upon failure.
-      Only GRPC_OP_COMPLETE can succeed or fail. */
+  /** If the grpc_completion_type is GRPC_OP_COMPLETE, this field indicates
+      whether the operation was successful or not; 0 in case of failure and
+      non-zero in case of success.
+      If grpc_completion_type is GRPC_QUEUE_SHUTDOWN or GRPC_QUEUE_TIMEOUT, this
+      field is guaranteed to be 0 */
   int success;
   /** The tag passed to grpc_call_start_batch etc to start this operation.
       Only GRPC_OP_COMPLETE has a tag. */
@@ -502,6 +560,55 @@ typedef struct {
 
 typedef struct grpc_resource_quota grpc_resource_quota;
 
+/** Completion queues internally MAY maintain a set of file descriptors in a
+    structure called 'pollset'. This enum specifies if a completion queue has an
+    associated pollset and any restrictions on the type of file descriptors that
+    can be present in the pollset.
+
+    I/O progress can only be made when grpc_completion_queue_next() or
+    grpc_completion_queue_pluck() are called on the completion queue (unless the
+    grpc_cq_polling_type is GRPC_CQ_NON_POLLING) and hence it is very important
+    to actively call these APIs */
+typedef enum {
+  /** The completion queue will have an associated pollset and there is no
+      restriction on the type of file descriptors the pollset may contain */
+  GRPC_CQ_DEFAULT_POLLING,
+
+  /** Similar to GRPC_CQ_DEFAULT_POLLING except that the completion queues will
+      not contain any 'listening file descriptors' (i.e file descriptors used to
+      listen to incoming channels) */
+  GRPC_CQ_NON_LISTENING,
+
+  /** The completion queue will not have an associated pollset. Note that
+      grpc_completion_queue_next() or grpc_completion_queue_pluck() MUST still
+      be called to pop events from the completion queue; it is not required to
+      call them actively to make I/O progress */
+  GRPC_CQ_NON_POLLING
+} grpc_cq_polling_type;
+
+/** Specifies the type of APIs to use to pop events from the completion queue */
+typedef enum {
+  /** Events are popped out by calling grpc_completion_queue_next() API ONLY */
+  GRPC_CQ_NEXT = 1,
+
+  /** Events are popped out by calling grpc_completion_queue_pluck() API ONLY*/
+  GRPC_CQ_PLUCK
+} grpc_cq_completion_type;
+
+#define GRPC_CQ_CURRENT_VERSION 1
+typedef struct grpc_completion_queue_attributes {
+  /* The version number of this structure. More fields might be added to this
+     structure in future. */
+  int version; /* Set to GRPC_CQ_CURRENT_VERSION */
+
+  grpc_cq_completion_type cq_completion_type;
+
+  grpc_cq_polling_type cq_polling_type;
+} grpc_completion_queue_attributes;
+
+/** The completion queue factory structure is opaque to the callers of grpc */
+typedef struct grpc_completion_queue_factory grpc_completion_queue_factory;
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
index e565cd31d75f6216fe1c3cff90c21352dd5b4c25..14e348fadb2e31616deb5771ef5eafe22843f43a 100644
--- a/include/grpc/impl/codegen/port_platform.h
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -157,7 +157,6 @@
 #define GPR_GETPID_IN_UNISTD_H 1
 #define GPR_SUPPORT_CHANNELS_FROM_FD 1
 #elif defined(__linux__)
-#define GPR_POSIX_CRASH_HANDLER 1
 #define GPR_PLATFORM_STRING "linux"
 #ifndef _BSD_SOURCE
 #define _BSD_SOURCE
@@ -187,6 +186,11 @@
 #else /* _LP64 */
 #define GPR_ARCH_32 1
 #endif /* _LP64 */
+#ifdef __GLIBC__
+#define GPR_POSIX_CRASH_HANDLER 1
+#else /* musl libc */
+#define GPR_MUSL_LIBC_COMPAT 1
+#endif
 #elif defined(__APPLE__)
 #include <Availability.h>
 #include <TargetConditionals.h>
@@ -286,6 +290,12 @@
 #endif
 #endif /* GPR_NO_AUTODETECT_PLATFORM */
 
+#if defined(__has_include)
+#if __has_include(<atomic>)
+#define GRPC_HAS_CXX11_ATOMIC
+#endif /* __has_include(<atomic>) */
+#endif /* defined(__has_include) */
+
 #ifndef GPR_PLATFORM_STRING
 #warning "GPR_PLATFORM_STRING not auto-detected"
 #define GPR_PLATFORM_STRING "unknown"
@@ -364,11 +374,21 @@ typedef unsigned __int64 uint64_t;
    power of two */
 #define GPR_MAX_ALIGNMENT 16
 
+#ifndef GRPC_ARES
+#ifdef GPR_WINDOWS
+#define GRPC_ARES 0
+#else
+#define GRPC_ARES 1
+#endif
+#endif
+
 #ifndef GRPC_MUST_USE_RESULT
 #if defined(__GNUC__) && !defined(__MINGW32__)
 #define GRPC_MUST_USE_RESULT __attribute__((warn_unused_result))
+#define GPR_ALIGN_STRUCT(n) __attribute__((aligned(n)))
 #else
 #define GRPC_MUST_USE_RESULT
+#define GPR_ALIGN_STRUCT(n)
 #endif
 #endif
 
diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h
index 0b09a0bfd89e44da84aef69249098f252f351cab..b89a3f7910aa9e492171367ac940cfddde64bf5e 100644
--- a/include/grpc/impl/codegen/slice.h
+++ b/include/grpc/impl/codegen/slice.h
@@ -34,8 +34,9 @@
 #ifndef GRPC_IMPL_CODEGEN_SLICE_H
 #define GRPC_IMPL_CODEGEN_SLICE_H
 
+#include <grpc/impl/codegen/port_platform.h>
+
 #include <stddef.h>
-#include <stdint.h>
 
 #include <grpc/impl/codegen/exec_ctx_fwd.h>
 #include <grpc/impl/codegen/gpr_slice.h>
diff --git a/include/grpc/impl/codegen/sync.h b/include/grpc/impl/codegen/sync.h
index 96aec0c2c09cd2897f5bb97ec0ab9e57376478a1..6a8e8a644f9fcc1b414bd5ee7a8eec2f5e0dc6ec 100644
--- a/include/grpc/impl/codegen/sync.h
+++ b/include/grpc/impl/codegen/sync.h
@@ -52,6 +52,10 @@
                                  provides no memory barriers.
  */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* Platform-specific type declarations of gpr_mu and gpr_cv.   */
 #include <grpc/impl/codegen/port_platform.h>
 #include <grpc/impl/codegen/sync_generic.h>
@@ -64,4 +68,8 @@
 #error Unable to determine platform for sync
 #endif
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* GRPC_IMPL_CODEGEN_SYNC_H */
diff --git a/include/grpc/load_reporting.h b/include/grpc/load_reporting.h
index c833ce5c63b9e05b21957248e1f2694d65f824fc..a334a11350759b8866f07f200c46f1f5d27d5cf1 100644
--- a/include/grpc/load_reporting.h
+++ b/include/grpc/load_reporting.h
@@ -35,7 +35,6 @@
 #define GRPC_LOAD_REPORTING_H
 
 #include <grpc/impl/codegen/port_platform.h>
-#include <grpc/slice.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -50,11 +49,12 @@ extern "C" {
  * gRPC LB system. */
 #define GRPC_LB_TOKEN_MD_KEY "lb-token"
 
-/** A sequence of values for load reporting purposes */
-typedef struct grpc_load_reporting_cost_context {
-  grpc_slice *values;
-  size_t values_count;
-} grpc_load_reporting_cost_context;
+/** Metadata key for gRPC LB cost reporting.
+ *
+ * The value corresponding to this key is an opaque binary blob reported by the
+ * backend as part of its trailing metadata containing cost information for the
+ * call. */
+#define GRPC_LB_COST_MD_KEY "lb-cost-bin"
 
 #ifdef __cplusplus
 }
diff --git a/include/grpc/slice.h b/include/grpc/slice.h
index ea66e094e9853744623a3f48b4820f43a336bf2c..9c4b158ae8db1c3d3dcfcf57ccc7cb88008525cb 100644
--- a/include/grpc/slice.h
+++ b/include/grpc/slice.h
@@ -53,6 +53,9 @@ GPRAPI grpc_slice grpc_slice_ref(grpc_slice s);
    where dest!=NULL , then (*dest)(start, len).  Requires s initialized.  */
 GPRAPI void grpc_slice_unref(grpc_slice s);
 
+/* Copy slice - create a new slice that contains the same data as s */
+GPRAPI grpc_slice grpc_slice_copy(grpc_slice s);
+
 /* Create a slice pointing at some data. Calls malloc to allocate a refcount
    for the object, and arranges that destroy will be called with the pointer
    passed in at destruction. */
@@ -75,6 +78,13 @@ GPRAPI grpc_slice grpc_slice_new_with_len(void *p, size_t len,
    call.
    Aborts if malloc() fails. */
 GPRAPI grpc_slice grpc_slice_malloc(size_t length);
+GPRAPI grpc_slice grpc_slice_malloc_large(size_t length);
+
+#define GRPC_SLICE_MALLOC(len)                                    \
+  ((len) <= GRPC_SLICE_INLINED_SIZE                               \
+       ? (grpc_slice){.refcount = NULL,                           \
+                      .data.inlined = {.length = (uint8_t)(len)}} \
+       : grpc_slice_malloc_large((len)))
 
 /* Intern a slice:
 
@@ -102,9 +112,9 @@ GPRAPI grpc_slice grpc_slice_from_static_string(const char *source);
 /* Create a slice pointing to constant memory */
 GPRAPI grpc_slice grpc_slice_from_static_buffer(const void *source, size_t len);
 
-/* Return a result slice derived from s, which shares a ref count with s, where
-   result.data==s.data+begin, and result.length==end-begin.
-   The ref count of s is increased by one.
+/* Return a result slice derived from s, which shares a ref count with \a s,
+   where result.data==s.data+begin, and result.length==end-begin. The ref count
+   of \a s is increased by one. Do not assign result back to \a s.
    Requires s initialized, begin <= end, begin <= s.length, and
    end <= source->length. */
 GPRAPI grpc_slice grpc_slice_sub(grpc_slice s, size_t begin, size_t end);
@@ -117,6 +127,18 @@ GPRAPI grpc_slice grpc_slice_sub_no_ref(grpc_slice s, size_t begin, size_t end);
    Requires s intialized, split <= s.length */
 GPRAPI grpc_slice grpc_slice_split_tail(grpc_slice *s, size_t split);
 
+typedef enum {
+  GRPC_SLICE_REF_TAIL = 1,
+  GRPC_SLICE_REF_HEAD = 2,
+  GRPC_SLICE_REF_BOTH = 1 + 2
+} grpc_slice_ref_whom;
+
+/* The same as grpc_slice_split_tail, but with an option to skip altering
+ * refcounts (grpc_slice_split_tail_maybe_ref(..., true) is equivalent to
+ * grpc_slice_split_tail(...)) */
+GPRAPI grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice *s, size_t split,
+                                                  grpc_slice_ref_whom ref_whom);
+
 /* Splits s into two: modifies s to be s[split:s.length], and returns a new
    slice, sharing a refcount with s, that contains s[0:split].
    Requires s intialized, split <= s.length */
diff --git a/include/grpc/slice_buffer.h b/include/grpc/slice_buffer.h
index 2ed896645b43a959ede7f72b95ba7c19e78b0f46..cdbd74776c6eaeaaa069d6db986f690d455f01db 100644
--- a/include/grpc/slice_buffer.h
+++ b/include/grpc/slice_buffer.h
@@ -77,6 +77,10 @@ GPRAPI void grpc_slice_buffer_trim_end(grpc_slice_buffer *src, size_t n,
 /* move the first n bytes of src into dst */
 GPRAPI void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
                                          grpc_slice_buffer *dst);
+/* move the first n bytes of src into dst without adding references */
+GPRAPI void grpc_slice_buffer_move_first_no_ref(grpc_slice_buffer *src,
+                                                size_t n,
+                                                grpc_slice_buffer *dst);
 /* move the first n bytes of src into dst (copying them) */
 GPRAPI void grpc_slice_buffer_move_first_into_buffer(grpc_exec_ctx *exec_ctx,
                                                      grpc_slice_buffer *src,
diff --git a/include/grpc/support/alloc.h b/include/grpc/support/alloc.h
index 541433c68804783033f9b82130b7a3605f9ca6a8..017d75a3d0ebc257807317869e21e7f84bfd6b43 100644
--- a/include/grpc/support/alloc.h
+++ b/include/grpc/support/alloc.h
@@ -68,7 +68,8 @@ GPRAPI void gpr_free_aligned(void *ptr);
 
 /** Request the family of allocation functions in \a functions be used. NOTE
  * that this request will be honored in a *best effort* basis and that no
- * guarantees are made about the default functions (eg, malloc) being called. */
+ * guarantees are made about the default functions (eg, malloc) being called.
+ * The functions.free_fn implementation must be a no-op for NULL input. */
 GPRAPI void gpr_set_allocation_functions(gpr_allocation_functions functions);
 
 /** Return the family of allocation functions currently in effect. */
diff --git a/include/grpc/support/sync.h b/include/grpc/support/sync.h
index a7bbb38c27e601af241335c4ad60b89c214f1b2b..5cfeecb6017a9f0b2da6b9035ee02168bd8f6c25 100644
--- a/include/grpc/support/sync.h
+++ b/include/grpc/support/sync.h
@@ -164,6 +164,10 @@ GPRAPI void gpr_refn(gpr_refcount *r, int n);
    zero. .  Requires *r initialized. */
 GPRAPI int gpr_unref(gpr_refcount *r);
 
+/* Return non-zero iff the reference count of *r is one, and thus is owned
+   by exactly one object. */
+GPRAPI int gpr_ref_is_unique(gpr_refcount *r);
+
 /* --- Stats counters ---
 
    These calls act on the integral type gpr_stats_counter.  It requires no
diff --git a/include/grpc/support/tls.h b/include/grpc/support/tls.h
index a45e1f0a4d557502966ba0b8dba94528ce0370ef..5365449f0dab192b4467be32916b34882f380757 100644
--- a/include/grpc/support/tls.h
+++ b/include/grpc/support/tls.h
@@ -58,7 +58,7 @@
      gpr_tls_set(&foo, new_value);
 
    Accessing a thread local:
-     current_value = gpr_tls_get(&foo, value);
+     current_value = gpr_tls_get(&foo);
 
    ALL functions here may be implemented as macros. */
 
diff --git a/package.json b/package.json
index d729f3d8376edb7815538a258983922a419b9843..e1499a089cd05425c65ad5a695068ddd6e0fe0af 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "grpc",
-  "version": "1.2.0-dev",
+  "version": "1.4.0-dev",
   "author": "Google Inc.",
   "description": "gRPC Library for Node",
   "homepage": "http://www.grpc.io/",
@@ -24,7 +24,7 @@
     "electron-build": "./node_modules/.bin/node-pre-gyp configure build --runtime=electron --disturl=https://atom.io/download/atom-shell",
     "gen_docs": "./node_modules/.bin/jsdoc -c src/node/jsdoc_conf.json",
     "coverage": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha src/node/test",
-    "install": "./node_modules/.bin/node-pre-gyp install --fallback-to-build"
+    "install": "./node_modules/.bin/node-pre-gyp install --fallback-to-build --library=static_library"
   },
   "bundledDependencies": [
     "node-pre-gyp"
@@ -34,7 +34,7 @@
     "lodash": "^4.15.0",
     "nan": "^2.0.0",
     "node-pre-gyp": "^0.6.0",
-    "protobufjs": "^5.0.0"
+    "protobufjs": "^6.7.0"
   },
   "devDependencies": {
     "async": "^2.0.1",
@@ -52,7 +52,7 @@
     "poisson-process": "^0.2.1"
   },
   "engines": {
-    "node": ">=1.1.0"
+    "node": ">=4"
   },
   "binary": {
     "module_name": "grpc_node",
diff --git a/package.xml b/package.xml
index e16161d7a2e769dd3896978f3b673011957d70d0..d47708efa4e5c12abe32424deb59e5d8a0da0b7e 100644
--- a/package.xml
+++ b/package.xml
@@ -13,8 +13,8 @@
  <date>2017-03-01</date>
  <time>16:06:07</time>
  <version>
-  <release>1.2.0dev</release>
-  <api>1.2.0dev</api>
+  <release>1.4.0dev</release>
+  <api>1.4.0dev</api>
  </version>
  <stability>
   <release>beta</release>
@@ -85,15 +85,19 @@
     <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_slice.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_types.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/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_windows.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/profiling/timers.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/arena.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/atomic.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/atomic_with_atm.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/atomic_with_std.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/backoff.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/block_annotate.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/env.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/memory.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/mpscq.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/murmur_hash.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/spinlock.h" role="src" />
@@ -106,6 +110,8 @@
     <file baseinstalldir="/" name="src/core/lib/profiling/basic_timers.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/profiling/stap_timers.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/alloc.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/arena.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/atm.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/avl.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/backoff.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/cmdline.c" role="src" />
@@ -163,6 +169,7 @@
     <file baseinstalldir="/" name="include/grpc/impl/codegen/exec_ctx_fwd.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/grpc_types.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/propagation_bits.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/slice.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/status.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" />
@@ -171,7 +178,6 @@
     <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_slice.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_types.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/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" />
@@ -181,16 +187,11 @@
     <file baseinstalldir="/" name="src/core/lib/channel/channel_args.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/channel_stack.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/channel_stack_builder.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/channel/compress_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/connected_channel.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/context.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/channel/deadline_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/handshaker.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/handshaker_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/handshaker_registry.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/channel/http_client_filter.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/channel/http_server_filter.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/channel/message_size_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/algorithm_metadata.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/message_compress.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/debug/trace.h" role="src" />
@@ -213,6 +214,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_internal.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_posix.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/load_file.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/lockfree_event.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/network_status_tracker.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/polling_entity.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset.h" role="src" />
@@ -227,6 +229,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_posix.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_utils.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_windows.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/socket_factory_posix.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_mutator.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils_posix.h" role="src" />
@@ -235,6 +238,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_posix.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_posix.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_utils_posix.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_uv.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_windows.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/time_averaged_stats.h" role="src" />
@@ -254,6 +258,7 @@
     <file baseinstalldir="/" name="src/core/lib/json/json_common.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/json/json_reader.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/json/json_writer.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/slice/b64.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/slice/percent_encoding.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/slice/slice_hash_table.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/slice/slice_internal.h" role="src" />
@@ -265,6 +270,7 @@
     <file baseinstalldir="/" name="src/core/lib/surface/channel_init.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/channel_stack_type.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/completion_queue.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/surface/completion_queue_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/event_string.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/init.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/lame_client.h" role="src" />
@@ -297,12 +303,16 @@
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/hpack_encoder.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/hpack_parser.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/hpack_table.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/http2_settings.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/huffsyms.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/incoming_metadata.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/internal.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/stream_map.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/varint.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/alpn/alpn.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/http/client/http_client_filter.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/http/message_compress/message_compress_filter.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/http/server/http_server_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/context/security_context.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/composite/composite_credentials.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/credentials.h" role="src" />
@@ -321,43 +331,48 @@
     <file baseinstalldir="/" name="src/core/lib/security/transport/security_connector.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/transport/security_handshaker.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/transport/tsi_error.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/security/util/b64.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/util/json_util.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/tsi/fake_transport_security.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/tsi/ssl_transport_security.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/tsi/ssl_types.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/tsi/transport_security.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/tsi/transport_security_interface.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_adapter.h" role="src" />
+    <file baseinstalldir="/" name="src/core/tsi/transport_security_interface.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/chttp2_server.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/client_channel.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/client_channel_factory.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/connector.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/http_connect_handshaker.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/http_proxy.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/initial_connect_string.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy_factory.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy_registry.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/parse_address.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/proxy_mapper.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/proxy_mapper_registry.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/resolver.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/resolver_factory.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/resolver_registry.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/subchannel.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/subchannel_index.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/uri_parser.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_connect_handshaker.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_proxy.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_factory.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_registry.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/parse_address.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper_registry.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_factory.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_registry.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/retry_throttle.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/uri_parser.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/grpclb.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/grpclb_channel.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.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/ext/load_reporting/load_reporting.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting_filter.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/load_reporting/load_reporting.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/load_reporting/load_reporting_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/aggregation.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/base_resources.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/census_interface.h" role="src" />
@@ -374,19 +389,16 @@
     <file baseinstalldir="/" name="src/core/ext/census/trace_status.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/trace_string.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/tracing.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/max_age/max_age_filter.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/message_size/message_size_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/init.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/channel_args.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/channel_stack.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/channel_stack_builder.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/channel/compress_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/connected_channel.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/channel/deadline_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/handshaker.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/handshaker_factory.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/handshaker_registry.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/channel/http_client_filter.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/channel/http_server_filter.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/channel/message_size_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/compression.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/message_compress.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/debug/trace.c" role="src" />
@@ -411,6 +423,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_uv.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/load_file.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/lockfree_event.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/network_status_tracker.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/polling_entity.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset_set_uv.c" role="src" />
@@ -422,6 +435,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/resolve_address_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/resource_quota.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_utils.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/socket_factory_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_mutator.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils_common_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils_linux.c" role="src" />
@@ -434,6 +448,9 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_utils_posix_common.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_uv.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_uv.c" role="src" />
@@ -456,6 +473,7 @@
     <file baseinstalldir="/" name="src/core/lib/json/json_reader.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/json/json_string.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/json/json_writer.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/slice/b64.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/slice/percent_encoding.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/slice/slice.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/slice/slice_buffer.c" role="src" />
@@ -474,8 +492,9 @@
     <file baseinstalldir="/" name="src/core/lib/surface/channel_ping.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/channel_stack_type.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/completion_queue.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/surface/completion_queue_factory.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/event_string.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/surface/lame_client.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/surface/lame_client.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/metadata_array.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/server.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/validate_metadata.c" role="src" />
@@ -507,6 +526,7 @@
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/hpack_encoder.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/hpack_parser.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/hpack_table.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/http2_settings.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/huffsyms.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/incoming_metadata.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/parsing.c" role="src" />
@@ -515,6 +535,10 @@
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/varint.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/writing.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/alpn/alpn.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/http/client/http_client_filter.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/http/http_filters_plugin.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/http/message_compress/message_compress_filter.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/http/server/http_server_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/http/httpcli_security_connector.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/context/security_context.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/composite/composite_credentials.c" role="src" />
@@ -537,53 +561,58 @@
     <file baseinstalldir="/" name="src/core/lib/security/transport/security_handshaker.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/transport/server_auth_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/transport/tsi_error.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/security/util/b64.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/util/json_util.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/init_secure.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/tsi/fake_transport_security.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/tsi/ssl_transport_security.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/tsi/transport_security.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/tsi/transport_security_adapter.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/chttp2_server.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/secure/secure_channel_create.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/channel_connectivity.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/client_channel.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/client_channel_factory.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/client_channel_plugin.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/connector.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/default_initial_connect_string.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/http_connect_handshaker.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/http_proxy.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/initial_connect_string.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy_factory.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy_registry.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/parse_address.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/proxy_mapper.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/proxy_mapper_registry.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/resolver.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/resolver_factory.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/resolver_registry.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/subchannel.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/subchannel_index.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/uri_parser.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/channel_connectivity.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_plugin.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_connect_handshaker.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_proxy.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_factory.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_registry.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/parse_address.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper_registry.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_factory.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_registry.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/retry_throttle.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/uri_parser.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/insecure/server_chttp2.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/grpclb.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.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="src/core/ext/lb_policy/pick_first/pick_first.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/lb_policy/round_robin/round_robin.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/resolver/dns/native/dns_resolver.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/resolver/sockaddr/sockaddr_resolver.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting_filter.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/load_reporting/load_reporting.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/load_reporting/load_reporting_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/base_resources.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/context.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/gen/census.pb.c" role="src" />
@@ -598,6 +627,8 @@
     <file baseinstalldir="/" name="src/core/ext/census/resource.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/trace_context.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/tracing.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/max_age/max_age_filter.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/message_size/message_size_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/plugin_registry/grpc_plugin_registry.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" />
@@ -1007,6 +1038,79 @@
     <file baseinstalldir="/" name="third_party/boringssl/ssl/tls13_server.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/ssl/tls_method.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/ssl/tls_record.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_data.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_dns.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_getenv.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_getopt.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_inet_net_pton.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_iphlpapi.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_ipv6.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_library_init.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_llist.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_nowarn.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_platform.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_private.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_rules.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_setup.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_strcasecmp.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_strdup.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_version.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/bitncmp.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/config-win32.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/setup_once.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/ares_build.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/config_linux/ares_config.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/config_darwin/ares_config.h" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares__close_sockets.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares__get_hostent.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares__read_line.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares__timeval.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_cancel.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_create_query.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_data.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_destroy.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_expand_name.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_expand_string.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_fds.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_free_hostent.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_free_string.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_getenv.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_gethostbyaddr.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_gethostbyname.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_getnameinfo.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_getopt.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_getsock.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_init.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_library_init.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_llist.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_mkquery.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_nowarn.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_options.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_parse_a_reply.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_parse_aaaa_reply.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_parse_mx_reply.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_parse_naptr_reply.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_parse_ns_reply.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_parse_ptr_reply.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_parse_soa_reply.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_parse_srv_reply.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_parse_txt_reply.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_platform.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_process.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_query.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_search.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_send.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_strcasecmp.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_strdup.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_strerror.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_timeout.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_version.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/ares_writev.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/bitncmp.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/inet_net_pton.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/inet_ntop.c" role="src" />
+    <file baseinstalldir="/" name="third_party/cares/cares/windows_port.c" role="src" />
   </dir>
  </contents>
  <dependencies>
diff --git a/requirements.txt b/requirements.txt
index bf87de07f894084ce57e7bd5d785a794bb4ff130..12969958aeeac640956c836c018252ac582dce04 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,6 +3,6 @@ coverage>=4.0
 cython>=0.23
 enum34>=1.0.4
 futures>=2.2.0
-protobuf>=3.0.0
+protobuf>=3.2.0
 six>=1.10
 wheel>=0.29
diff --git a/setup.py b/setup.py
index 234252a16ca27baac02e48adc8725a12558eaeae..18ba802fb0f8762777b128546a5b4156e10b7179 100644
--- a/setup.py
+++ b/setup.py
@@ -52,6 +52,13 @@ PYTHON_STEM = os.path.join('src', 'python', 'grpcio')
 CORE_INCLUDE = ('include', '.',)
 BORINGSSL_INCLUDE = (os.path.join('third_party', 'boringssl', 'include'),)
 ZLIB_INCLUDE = (os.path.join('third_party', 'zlib'),)
+CARES_INCLUDE = (
+    os.path.join('third_party', 'cares'),
+    os.path.join('third_party', 'cares', 'cares'),)
+if 'linux' in sys.platform:
+  CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_linux'),)
+if 'darwin' in sys.platform:
+  CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_darwin'),)
 README = os.path.join(PYTHON_STEM, 'README.rst')
 
 # Ensure we're in the proper directory whether or not we're being used by pip.
@@ -97,6 +104,7 @@ EXTRA_ENV_LINK_ARGS = os.environ.get('GRPC_PYTHON_LDFLAGS', None)
 if EXTRA_ENV_COMPILE_ARGS is None:
   EXTRA_ENV_COMPILE_ARGS = ''
   if 'win32' in sys.platform and sys.version_info < (3, 5):
+    EXTRA_ENV_COMPILE_ARGS += ' -std=c++11'
     # We use define flags here and don't directly add to DEFINE_MACROS below to
     # ensure that the expert user/builder has a way of turning it off (via the
     # envvars) without adding yet more GRPC-specific envvars.
@@ -107,7 +115,9 @@ if EXTRA_ENV_COMPILE_ARGS is None:
       EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime64 -D_timeb=__timeb64'
   elif 'win32' in sys.platform:
     EXTRA_ENV_COMPILE_ARGS += ' -D_PYTHON_MSVC'
-  elif "linux" in sys.platform or "darwin" in sys.platform:
+  elif "linux" in sys.platform:
+    EXTRA_ENV_COMPILE_ARGS += ' -std=c++11 -fvisibility=hidden -fno-wrapv'
+  elif "darwin" in sys.platform:
     EXTRA_ENV_COMPILE_ARGS += ' -fvisibility=hidden -fno-wrapv'
 
 if EXTRA_ENV_LINK_ARGS is None:
@@ -134,9 +144,12 @@ CYTHON_EXTENSION_MODULE_NAMES = ('grpc._cython.cygrpc',)
 CYTHON_HELPER_C_FILES = ()
 
 CORE_C_FILES = tuple(grpc_core_dependencies.CORE_SOURCE_FILES)
+if "win32" in sys.platform and "64bit" in platform.architecture()[0]:
+  CORE_C_FILES = filter(lambda x: 'third_party/cares' not in x, CORE_C_FILES)
 
 EXTENSION_INCLUDE_DIRECTORIES = (
-    (PYTHON_STEM,) + CORE_INCLUDE + BORINGSSL_INCLUDE + ZLIB_INCLUDE)
+    (PYTHON_STEM,) + CORE_INCLUDE + BORINGSSL_INCLUDE + ZLIB_INCLUDE +
+    CARES_INCLUDE)
 
 EXTENSION_LIBRARIES = ()
 if "linux" in sys.platform:
@@ -150,13 +163,17 @@ DEFINE_MACROS = (
     ('OPENSSL_NO_ASM', 1), ('_WIN32_WINNT', 0x600),
     ('GPR_BACKWARDS_COMPATIBILITY_MODE', 1),)
 if "win32" in sys.platform:
-  DEFINE_MACROS += (('WIN32_LEAN_AND_MEAN', 1),)
+  DEFINE_MACROS += (('WIN32_LEAN_AND_MEAN', 1), ('CARES_STATICLIB', 1),)
   if '64bit' in platform.architecture()[0]:
-    DEFINE_MACROS += (('MS_WIN64', 1),)
+    # TODO(zyc): Re-enble c-ares on x64 windows after fixing the
+    # ares_library_init compilation issue
+    DEFINE_MACROS += (('MS_WIN64', 1), ('GRPC_ARES', 0),)
   elif sys.version_info >= (3, 5):
     # For some reason, this is needed to get access to inet_pton/inet_ntop
     # on msvc, but only for 32 bits
     DEFINE_MACROS += (('NTDDI_VERSION', 0x06000000),)
+else:
+  DEFINE_MACROS += (('HAVE_CONFIG_H', 1),)
 
 LDFLAGS = tuple(EXTRA_LINK_ARGS)
 CFLAGS = tuple(EXTRA_COMPILE_ARGS)
@@ -182,13 +199,25 @@ def cython_extensions_and_necessity():
   cython_module_files = [os.path.join(PYTHON_STEM,
                                name.replace('.', '/') + '.pyx')
                   for name in CYTHON_EXTENSION_MODULE_NAMES]
+  config = os.environ.get('CONFIG', 'opt')
+  prefix = 'libs/' + config + '/'
+  if "darwin" in sys.platform:
+    extra_objects = [prefix + 'libares.a',
+                     prefix + 'libboringssl.a',
+                     prefix + 'libgpr.a',
+                     prefix + 'libgrpc.a']
+    core_c_files = []
+  else:
+    core_c_files = list(CORE_C_FILES)
+    extra_objects = []
   extensions = [
       _extension.Extension(
           name=module_name,
-          sources=[module_file] + list(CYTHON_HELPER_C_FILES) + list(CORE_C_FILES),
+          sources=[module_file] + list(CYTHON_HELPER_C_FILES) + core_c_files,
           include_dirs=list(EXTENSION_INCLUDE_DIRECTORIES),
           libraries=list(EXTENSION_LIBRARIES),
           define_macros=list(DEFINE_MACROS),
+          extra_objects=extra_objects,
           extra_compile_args=list(CFLAGS),
           extra_link_args=list(LDFLAGS),
       ) for (module_name, module_file) in zip(list(CYTHON_EXTENSION_MODULE_NAMES), cython_module_files)
@@ -206,14 +235,13 @@ PACKAGE_DIRECTORIES = {
 
 INSTALL_REQUIRES = (
     'six>=1.5.2',
-    'enum34>=1.0.4',
     # TODO(atash): eventually split the grpcio package into a metapackage
     # depending on protobuf and the runtime component (independent of protobuf)
-    'protobuf>=3.0.0',
+    'protobuf>=3.2.0',
 )
 
 if not PY3:
-  INSTALL_REQUIRES += ('futures>=2.2.0',)
+  INSTALL_REQUIRES += ('futures>=2.2.0', 'enum34>=1.0.4')
 
 SETUP_REQUIRES = INSTALL_REQUIRES + (
     'sphinx>=1.3',
@@ -265,6 +293,10 @@ PACKAGES = setuptools.find_packages(PYTHON_STEM)
 setuptools.setup(
   name='grpcio',
   version=grpc_version.VERSION,
+  description='HTTP/2-based RPC framework',
+  author='The gRPC Authors',
+  author_email='grpc-io@googlegroups.com',
+  url='http://www.grpc.io',
   license=LICENSE,
   long_description=open(README).read(),
   ext_modules=CYTHON_EXTENSION_MODULES,
diff --git a/src/c-ares/CMakeLists.txt b/src/c-ares/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..22acd51048fc4b4401162465141356283fec417e
--- /dev/null
+++ b/src/c-ares/CMakeLists.txt
@@ -0,0 +1,49 @@
+# c-ares cmake file for gRPC
+#
+# This is currently very experimental, and unsupported.
+#
+# 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.
+
+string(TOLOWER ${CMAKE_SYSTEM_NAME} cares_system_name)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../third_party/cares)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../third_party/cares/cares)
+
+if(${cares_system_name} MATCHES windows)
+  add_definitions(-DCARES_STATICLIB=1)
+  add_definitions(-DWIN32_LEAN_AND_MEAN=1)
+else()
+  include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../third_party/cares/config_${cares_system_name})
+  add_definitions(-DHAVE_CONFIG_H=1)
+  add_definitions(-D_GNU_SOURCE=1)
+endif()
+
+file(GLOB lib_sources ../../third_party/cares/cares/*.c)
+add_library(cares ${lib_sources})
diff --git a/src/c-ares/gen_build_yaml.py b/src/c-ares/gen_build_yaml.py
new file mode 100755
index 0000000000000000000000000000000000000000..b2ae971f37213ef5f8306d69eb11ba89667e59fb
--- /dev/null
+++ b/src/c-ares/gen_build_yaml.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python2.7
+
+# 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.
+
+import re
+import os
+import sys
+import yaml
+
+os.chdir(os.path.dirname(sys.argv[0])+'/../..')
+
+out = {}
+
+try:
+  def gen_ares_build(x):
+    subprocess.call("third_party/cares/cares/buildconf", shell=True)
+    subprocess.call("third_party/cares/cares/configure", shell=True)
+
+  def config_platform(x):
+    if 'linux' in sys.platform:
+      return 'src/cares/cares/config_linux/ares_config.h'
+    if 'darwin' in sys.platform:
+      return 'src/cares/cares/config_darwin/ares_config.h'
+    if not os.path.isfile('third_party/cares/cares/ares_config.h'):
+      gen_ares_build(x)
+    return 'third_party/cares/cares/ares_config.h'
+
+  def ares_build(x):
+    if os.path.isfile('src/cares/cares/ares_build.h'):
+      return 'src/cares/cares/ares_build.h'
+    if not os.path.isfile('third_party/cares/cares/ares_build.h'):
+      gen_ares_build(x)
+    return 'third_party/cares/cares/ares_build.h'
+
+  out['libs'] = [{
+      'name': 'ares',
+      'defaults': 'ares',
+      'build': 'private',
+      'language': 'c',
+      'secure': 'no',
+      'src': [
+        "third_party/cares/cares/ares__close_sockets.c",
+        "third_party/cares/cares/ares__get_hostent.c",
+        "third_party/cares/cares/ares__read_line.c",
+        "third_party/cares/cares/ares__timeval.c",
+        "third_party/cares/cares/ares_cancel.c",
+        "third_party/cares/cares/ares_create_query.c",
+        "third_party/cares/cares/ares_data.c",
+        "third_party/cares/cares/ares_destroy.c",
+        "third_party/cares/cares/ares_expand_name.c",
+        "third_party/cares/cares/ares_expand_string.c",
+        "third_party/cares/cares/ares_fds.c",
+        "third_party/cares/cares/ares_free_hostent.c",
+        "third_party/cares/cares/ares_free_string.c",
+        "third_party/cares/cares/ares_getenv.c",
+        "third_party/cares/cares/ares_gethostbyaddr.c",
+        "third_party/cares/cares/ares_gethostbyname.c",
+        "third_party/cares/cares/ares_getnameinfo.c",
+        "third_party/cares/cares/ares_getopt.c",
+        "third_party/cares/cares/ares_getsock.c",
+        "third_party/cares/cares/ares_init.c",
+        "third_party/cares/cares/ares_library_init.c",
+        "third_party/cares/cares/ares_llist.c",
+        "third_party/cares/cares/ares_mkquery.c",
+        "third_party/cares/cares/ares_nowarn.c",
+        "third_party/cares/cares/ares_options.c",
+        "third_party/cares/cares/ares_parse_a_reply.c",
+        "third_party/cares/cares/ares_parse_aaaa_reply.c",
+        "third_party/cares/cares/ares_parse_mx_reply.c",
+        "third_party/cares/cares/ares_parse_naptr_reply.c",
+        "third_party/cares/cares/ares_parse_ns_reply.c",
+        "third_party/cares/cares/ares_parse_ptr_reply.c",
+        "third_party/cares/cares/ares_parse_soa_reply.c",
+        "third_party/cares/cares/ares_parse_srv_reply.c",
+        "third_party/cares/cares/ares_parse_txt_reply.c",
+        "third_party/cares/cares/ares_platform.c",
+        "third_party/cares/cares/ares_process.c",
+        "third_party/cares/cares/ares_query.c",
+        "third_party/cares/cares/ares_search.c",
+        "third_party/cares/cares/ares_send.c",
+        "third_party/cares/cares/ares_strcasecmp.c",
+        "third_party/cares/cares/ares_strdup.c",
+        "third_party/cares/cares/ares_strerror.c",
+        "third_party/cares/cares/ares_timeout.c",
+        "third_party/cares/cares/ares_version.c",
+        "third_party/cares/cares/ares_writev.c",
+        "third_party/cares/cares/bitncmp.c",
+        "third_party/cares/cares/inet_net_pton.c",
+        "third_party/cares/cares/inet_ntop.c",
+        "third_party/cares/cares/windows_port.c",
+      ],
+      'headers': [
+        "third_party/cares/cares/ares.h",
+        "third_party/cares/cares/ares_data.h",
+        "third_party/cares/cares/ares_dns.h",
+        "third_party/cares/cares/ares_getenv.h",
+        "third_party/cares/cares/ares_getopt.h",
+        "third_party/cares/cares/ares_inet_net_pton.h",
+        "third_party/cares/cares/ares_iphlpapi.h",
+        "third_party/cares/cares/ares_ipv6.h",
+        "third_party/cares/cares/ares_library_init.h",
+        "third_party/cares/cares/ares_llist.h",
+        "third_party/cares/cares/ares_nowarn.h",
+        "third_party/cares/cares/ares_platform.h",
+        "third_party/cares/cares/ares_private.h",
+        "third_party/cares/cares/ares_rules.h",
+        "third_party/cares/cares/ares_setup.h",
+        "third_party/cares/cares/ares_strcasecmp.h",
+        "third_party/cares/cares/ares_strdup.h",
+        "third_party/cares/cares/ares_version.h",
+        "third_party/cares/cares/bitncmp.h",
+        "third_party/cares/cares/config-win32.h",
+        "third_party/cares/cares/setup_once.h",
+        "third_party/cares/ares_build.h",
+        "third_party/cares/config_linux/ares_config.h",
+        "third_party/cares/config_darwin/ares_config.h"
+    ],
+  }]
+except:
+  pass
+
+print yaml.dump(out)
diff --git a/src/compiler/README.md b/src/compiler/README.md
index a2f49b3cd5387f90595ac6b77458b67d1b6a15c4..d5684af7ff24e90af441514649141b70d40d9803 100644
--- a/src/compiler/README.md
+++ b/src/compiler/README.md
@@ -1,4 +1,4 @@
-#Overview
+# Overview
 
 This directory contains source code for gRPC protocol buffer compiler (*protoc*) plugins. Along with `protoc`,
 these plugins are used to generate gRPC client and server stubs from `.proto` files.
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index e481aaf811b4feb81d4ace031c314d381c9f4284..a1a0258c68012fee6723f358a00cdc87402c9960 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -40,6 +40,9 @@
 namespace grpc_cpp_generator {
 namespace {
 
+grpc::string message_header_ext() { return ".pb.h"; }
+grpc::string service_header_ext() { return ".grpc.pb.h"; }
+
 template <class T>
 grpc::string as_string(T x) {
   std::ostringstream out;
@@ -47,6 +50,14 @@ grpc::string as_string(T x) {
   return out.str();
 }
 
+inline bool ClientOnlyStreaming(const grpc_generator::Method *method) {
+  return method->ClientStreaming() && !method->ServerStreaming();
+}
+
+inline bool ServerOnlyStreaming(const grpc_generator::Method *method) {
+  return !method->ClientStreaming() && method->ServerStreaming();
+}
+
 grpc::string FilenameIdentifier(const grpc::string &filename) {
   grpc::string result;
   for (unsigned i = 0; i < filename.size(); i++) {
@@ -69,7 +80,8 @@ T *array_end(T (&array)[N]) {
   return array + N;
 }
 
-void PrintIncludes(Printer *printer, const std::vector<grpc::string> &headers,
+void PrintIncludes(grpc_generator::Printer *printer,
+                   const std::vector<grpc::string> &headers,
                    const Parameters &params) {
   std::map<grpc::string, grpc::string> vars;
 
@@ -90,7 +102,8 @@ void PrintIncludes(Printer *printer, const std::vector<grpc::string> &headers,
   }
 }
 
-grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) {
+grpc::string GetHeaderPrologue(grpc_generator::File *file,
+                               const Parameters & /*params*/) {
   grpc::string output;
   {
     // Scope the output stream so it closes and finalizes output to the string.
@@ -100,13 +113,13 @@ grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) {
     vars["filename"] = file->filename();
     vars["filename_identifier"] = FilenameIdentifier(file->filename());
     vars["filename_base"] = file->filename_without_ext();
-    vars["message_header_ext"] = file->message_header_ext();
+    vars["message_header_ext"] = message_header_ext();
 
-    printer->Print(vars, "// Generated by the gRPC protobuf plugin.\n");
+    printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
     printer->Print(vars,
                    "// If you make any local change, they will be lost.\n");
     printer->Print(vars, "// source: $filename$\n");
-    grpc::string leading_comments = file->GetLeadingComments();
+    grpc::string leading_comments = file->GetLeadingComments("//");
     if (!leading_comments.empty()) {
       printer->Print(vars, "// Original file comments:\n");
       printer->Print(leading_comments.c_str());
@@ -120,7 +133,8 @@ grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) {
   return output;
 }
 
-grpc::string GetHeaderIncludes(File *file, const Parameters &params) {
+grpc::string GetHeaderIncludes(grpc_generator::File *file,
+                               const Parameters &params) {
   grpc::string output;
   {
     // Scope the output stream so it closes and finalizes output to the string.
@@ -162,7 +176,7 @@ grpc::string GetHeaderIncludes(File *file, const Parameters &params) {
 }
 
 void PrintHeaderClientMethodInterfaces(
-    Printer *printer, const Method *method,
+    grpc_generator::Printer *printer, const grpc_generator::Method *method,
     std::map<grpc::string, grpc::string> *vars, bool is_public) {
   (*vars)["Method"] = method->name();
   (*vars)["Request"] = method->input_type_name();
@@ -187,7 +201,7 @@ void PrintHeaderClientMethodInterfaces(
                      "Async$Method$Raw(context, request, cq));\n");
       printer->Outdent();
       printer->Print("}\n");
-    } else if (method->ClientOnlyStreaming()) {
+    } else if (ClientOnlyStreaming(method)) {
       printer->Print(
           *vars,
           "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
@@ -213,7 +227,7 @@ void PrintHeaderClientMethodInterfaces(
                      "Async$Method$Raw(context, response, cq, tag));\n");
       printer->Outdent();
       printer->Print("}\n");
-    } else if (method->ServerOnlyStreaming()) {
+    } else if (ServerOnlyStreaming(method)) {
       printer->Print(
           *vars,
           "std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
@@ -275,7 +289,7 @@ void PrintHeaderClientMethodInterfaces(
           "Async$Method$Raw(::grpc::ClientContext* context, "
           "const $Request$& request, "
           "::grpc::CompletionQueue* cq) = 0;\n");
-    } else if (method->ClientOnlyStreaming()) {
+    } else if (ClientOnlyStreaming(method)) {
       printer->Print(
           *vars,
           "virtual ::grpc::ClientWriterInterface< $Request$>*"
@@ -286,7 +300,7 @@ void PrintHeaderClientMethodInterfaces(
                      " Async$Method$Raw(::grpc::ClientContext* context, "
                      "$Response$* response, "
                      "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
-    } else if (method->ServerOnlyStreaming()) {
+    } else if (ServerOnlyStreaming(method)) {
       printer->Print(
           *vars,
           "virtual ::grpc::ClientReaderInterface< $Response$>* $Method$Raw("
@@ -311,7 +325,8 @@ void PrintHeaderClientMethodInterfaces(
   }
 }
 
-void PrintHeaderClientMethod(Printer *printer, const Method *method,
+void PrintHeaderClientMethod(grpc_generator::Printer *printer,
+                             const grpc_generator::Method *method,
                              std::map<grpc::string, grpc::string> *vars,
                              bool is_public) {
   (*vars)["Method"] = method->name();
@@ -336,7 +351,7 @@ void PrintHeaderClientMethod(Printer *printer, const Method *method,
                      "Async$Method$Raw(context, request, cq));\n");
       printer->Outdent();
       printer->Print("}\n");
-    } else if (method->ClientOnlyStreaming()) {
+    } else if (ClientOnlyStreaming(method)) {
       printer->Print(
           *vars,
           "std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
@@ -360,7 +375,7 @@ void PrintHeaderClientMethod(Printer *printer, const Method *method,
           "Async$Method$Raw(context, response, cq, tag));\n");
       printer->Outdent();
       printer->Print("}\n");
-    } else if (method->ServerOnlyStreaming()) {
+    } else if (ServerOnlyStreaming(method)) {
       printer->Print(
           *vars,
           "std::unique_ptr< ::grpc::ClientReader< $Response$>>"
@@ -418,7 +433,7 @@ void PrintHeaderClientMethod(Printer *printer, const Method *method,
                      "Async$Method$Raw(::grpc::ClientContext* context, "
                      "const $Request$& request, "
                      "::grpc::CompletionQueue* cq) override;\n");
-    } else if (method->ClientOnlyStreaming()) {
+    } else if (ClientOnlyStreaming(method)) {
       printer->Print(*vars,
                      "::grpc::ClientWriter< $Request$>* $Method$Raw("
                      "::grpc::ClientContext* context, $Response$* response) "
@@ -427,7 +442,7 @@ void PrintHeaderClientMethod(Printer *printer, const Method *method,
                      "::grpc::ClientAsyncWriter< $Request$>* Async$Method$Raw("
                      "::grpc::ClientContext* context, $Response$* response, "
                      "::grpc::CompletionQueue* cq, void* tag) override;\n");
-    } else if (method->ServerOnlyStreaming()) {
+    } else if (ServerOnlyStreaming(method)) {
       printer->Print(*vars,
                      "::grpc::ClientReader< $Response$>* $Method$Raw("
                      "::grpc::ClientContext* context, const $Request$& request)"
@@ -449,30 +464,32 @@ void PrintHeaderClientMethod(Printer *printer, const Method *method,
   }
 }
 
-void PrintHeaderClientMethodData(Printer *printer, const Method *method,
+void PrintHeaderClientMethodData(grpc_generator::Printer *printer,
+                                 const grpc_generator::Method *method,
                                  std::map<grpc::string, grpc::string> *vars) {
   (*vars)["Method"] = method->name();
   printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n");
 }
 
-void PrintHeaderServerMethodSync(Printer *printer, const Method *method,
+void PrintHeaderServerMethodSync(grpc_generator::Printer *printer,
+                                 const grpc_generator::Method *method,
                                  std::map<grpc::string, grpc::string> *vars) {
   (*vars)["Method"] = method->name();
   (*vars)["Request"] = method->input_type_name();
   (*vars)["Response"] = method->output_type_name();
-  printer->Print(method->GetLeadingComments().c_str());
+  printer->Print(method->GetLeadingComments("//").c_str());
   if (method->NoStreaming()) {
     printer->Print(*vars,
                    "virtual ::grpc::Status $Method$("
                    "::grpc::ServerContext* context, const $Request$* request, "
                    "$Response$* response);\n");
-  } else if (method->ClientOnlyStreaming()) {
+  } else if (ClientOnlyStreaming(method)) {
     printer->Print(*vars,
                    "virtual ::grpc::Status $Method$("
                    "::grpc::ServerContext* context, "
                    "::grpc::ServerReader< $Request$>* reader, "
                    "$Response$* response);\n");
-  } else if (method->ServerOnlyStreaming()) {
+  } else if (ServerOnlyStreaming(method)) {
     printer->Print(*vars,
                    "virtual ::grpc::Status $Method$("
                    "::grpc::ServerContext* context, const $Request$* request, "
@@ -485,10 +502,11 @@ void PrintHeaderServerMethodSync(Printer *printer, const Method *method,
         "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
         "\n");
   }
-  printer->Print(method->GetTrailingComments().c_str());
+  printer->Print(method->GetTrailingComments("//").c_str());
 }
 
-void PrintHeaderServerMethodAsync(Printer *printer, const Method *method,
+void PrintHeaderServerMethodAsync(grpc_generator::Printer *printer,
+                                  const grpc_generator::Method *method,
                                   std::map<grpc::string, grpc::string> *vars) {
   (*vars)["Method"] = method->name();
   (*vars)["Request"] = method->input_type_name();
@@ -530,7 +548,7 @@ void PrintHeaderServerMethodAsync(Printer *printer, const Method *method,
                    "  ::grpc::Service::RequestAsyncUnary($Idx$, context, "
                    "request, response, new_call_cq, notification_cq, tag);\n");
     printer->Print("}\n");
-  } else if (method->ClientOnlyStreaming()) {
+  } else if (ClientOnlyStreaming(method)) {
     printer->Print(
         *vars,
         "// disable synchronous version of this method\n"
@@ -552,7 +570,7 @@ void PrintHeaderServerMethodAsync(Printer *printer, const Method *method,
                    "  ::grpc::Service::RequestAsyncClientStreaming($Idx$, "
                    "context, reader, new_call_cq, notification_cq, tag);\n");
     printer->Print("}\n");
-  } else if (method->ServerOnlyStreaming()) {
+  } else if (ServerOnlyStreaming(method)) {
     printer->Print(
         *vars,
         "// disable synchronous version of this method\n"
@@ -603,7 +621,7 @@ void PrintHeaderServerMethodAsync(Printer *printer, const Method *method,
 }
 
 void PrintHeaderServerMethodStreamedUnary(
-    Printer *printer, const Method *method,
+    grpc_generator::Printer *printer, const grpc_generator::Method *method,
     std::map<grpc::string, grpc::string> *vars) {
   (*vars)["Method"] = method->name();
   (*vars)["Request"] = method->input_type_name();
@@ -654,12 +672,12 @@ void PrintHeaderServerMethodStreamedUnary(
 }
 
 void PrintHeaderServerMethodSplitStreaming(
-    Printer *printer, const Method *method,
+    grpc_generator::Printer *printer, const grpc_generator::Method *method,
     std::map<grpc::string, grpc::string> *vars) {
   (*vars)["Method"] = method->name();
   (*vars)["Request"] = method->input_type_name();
   (*vars)["Response"] = method->output_type_name();
-  if (method->ServerOnlyStreaming()) {
+  if (ServerOnlyStreaming(method)) {
     printer->Print(*vars, "template <class BaseClass>\n");
     printer->Print(*vars,
                    "class WithSplitStreamingMethod_$Method$ : "
@@ -706,7 +724,7 @@ void PrintHeaderServerMethodSplitStreaming(
 }
 
 void PrintHeaderServerMethodGeneric(
-    Printer *printer, const Method *method,
+    grpc_generator::Printer *printer, const grpc_generator::Method *method,
     std::map<grpc::string, grpc::string> *vars) {
   (*vars)["Method"] = method->name();
   (*vars)["Request"] = method->input_type_name();
@@ -737,7 +755,7 @@ void PrintHeaderServerMethodGeneric(
         "  abort();\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "}\n");
-  } else if (method->ClientOnlyStreaming()) {
+  } else if (ClientOnlyStreaming(method)) {
     printer->Print(
         *vars,
         "// disable synchronous version of this method\n"
@@ -748,7 +766,7 @@ void PrintHeaderServerMethodGeneric(
         "  abort();\n"
         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
         "}\n");
-  } else if (method->ServerOnlyStreaming()) {
+  } else if (ServerOnlyStreaming(method)) {
     printer->Print(
         *vars,
         "// disable synchronous version of this method\n"
@@ -775,16 +793,23 @@ void PrintHeaderServerMethodGeneric(
   printer->Print(*vars, "};\n");
 }
 
-void PrintHeaderService(Printer *printer, const Service *service,
+void PrintHeaderService(grpc_generator::Printer *printer,
+                        const grpc_generator::Service *service,
                         std::map<grpc::string, grpc::string> *vars) {
   (*vars)["Service"] = service->name();
 
-  printer->Print(service->GetLeadingComments().c_str());
+  printer->Print(service->GetLeadingComments("//").c_str());
   printer->Print(*vars,
                  "class $Service$ final {\n"
                  " public:\n");
   printer->Indent();
 
+  // Service metadata
+  printer->Print(*vars,
+                 "static constexpr char const* service_full_name() {\n"
+                 "  return \"$Package$$Service$\";\n"
+                 "}\n");
+
   // Client side
   printer->Print(
       "class StubInterface {\n"
@@ -792,10 +817,10 @@ void PrintHeaderService(Printer *printer, const Service *service,
   printer->Indent();
   printer->Print("virtual ~StubInterface() {}\n");
   for (int i = 0; i < service->method_count(); ++i) {
-    printer->Print(service->method(i)->GetLeadingComments().c_str());
+    printer->Print(service->method(i)->GetLeadingComments("//").c_str());
     PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
                                       true);
-    printer->Print(service->method(i)->GetTrailingComments().c_str());
+    printer->Print(service->method(i)->GetTrailingComments("//").c_str());
   }
   printer->Outdent();
   printer->Print("private:\n");
@@ -903,13 +928,15 @@ void PrintHeaderService(Printer *printer, const Service *service,
   printer->Print("typedef ");
   for (int i = 0; i < service->method_count(); ++i) {
     (*vars)["method_name"] = service->method(i).get()->name();
-    if (service->method(i)->ServerOnlyStreaming()) {
+    auto method = service->method(i);
+    if (ServerOnlyStreaming(method.get())) {
       printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
     }
   }
   printer->Print("Service");
   for (int i = 0; i < service->method_count(); ++i) {
-    if (service->method(i)->ServerOnlyStreaming()) {
+    auto method = service->method(i);
+    if (ServerOnlyStreaming(method.get())) {
       printer->Print(" >");
     }
   }
@@ -919,7 +946,8 @@ void PrintHeaderService(Printer *printer, const Service *service,
   printer->Print("typedef ");
   for (int i = 0; i < service->method_count(); ++i) {
     (*vars)["method_name"] = service->method(i).get()->name();
-    if (service->method(i)->ServerOnlyStreaming()) {
+    auto method = service->method(i);
+    if (ServerOnlyStreaming(method.get())) {
       printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
     }
     if (service->method(i)->NoStreaming()) {
@@ -928,8 +956,9 @@ void PrintHeaderService(Printer *printer, const Service *service,
   }
   printer->Print("Service");
   for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
     if (service->method(i)->NoStreaming() ||
-        service->method(i)->ServerOnlyStreaming()) {
+        ServerOnlyStreaming(method.get())) {
       printer->Print(" >");
     }
   }
@@ -937,10 +966,11 @@ void PrintHeaderService(Printer *printer, const Service *service,
 
   printer->Outdent();
   printer->Print("};\n");
-  printer->Print(service->GetTrailingComments().c_str());
+  printer->Print(service->GetTrailingComments("//").c_str());
 }
 
-grpc::string GetHeaderServices(File *file, const Parameters &params) {
+grpc::string GetHeaderServices(grpc_generator::File *file,
+                               const Parameters &params) {
   grpc::string output;
   {
     // Scope the output stream so it closes and finalizes output to the string.
@@ -970,7 +1000,8 @@ grpc::string GetHeaderServices(File *file, const Parameters &params) {
   return output;
 }
 
-grpc::string GetHeaderEpilogue(File *file, const Parameters & /*params*/) {
+grpc::string GetHeaderEpilogue(grpc_generator::File *file,
+                               const Parameters & /*params*/) {
   grpc::string output;
   {
     // Scope the output stream so it closes and finalizes output to the string.
@@ -993,12 +1024,13 @@ grpc::string GetHeaderEpilogue(File *file, const Parameters & /*params*/) {
     printer->Print(vars, "\n");
     printer->Print(vars, "#endif  // GRPC_$filename_identifier$__INCLUDED\n");
 
-    printer->Print(file->GetTrailingComments().c_str());
+    printer->Print(file->GetTrailingComments("//").c_str());
   }
   return output;
 }
 
-grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) {
+grpc::string GetSourcePrologue(grpc_generator::File *file,
+                               const Parameters & /*params*/) {
   grpc::string output;
   {
     // Scope the output stream so it closes and finalizes output to the string.
@@ -1007,10 +1039,10 @@ grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) {
 
     vars["filename"] = file->filename();
     vars["filename_base"] = file->filename_without_ext();
-    vars["message_header_ext"] = file->message_header_ext();
-    vars["service_header_ext"] = file->service_header_ext();
+    vars["message_header_ext"] = message_header_ext();
+    vars["service_header_ext"] = service_header_ext();
 
-    printer->Print(vars, "// Generated by the gRPC protobuf plugin.\n");
+    printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
     printer->Print(vars,
                    "// If you make any local change, they will be lost.\n");
     printer->Print(vars, "// source: $filename$\n\n");
@@ -1023,7 +1055,8 @@ grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) {
   return output;
 }
 
-grpc::string GetSourceIncludes(File *file, const Parameters &params) {
+grpc::string GetSourceIncludes(grpc_generator::File *file,
+                               const Parameters &params) {
   grpc::string output;
   {
     // Scope the output stream so it closes and finalizes output to the string.
@@ -1056,7 +1089,8 @@ grpc::string GetSourceIncludes(File *file, const Parameters &params) {
   return output;
 }
 
-void PrintSourceClientMethod(Printer *printer, const Method *method,
+void PrintSourceClientMethod(grpc_generator::Printer *printer,
+                             const grpc_generator::Method *method,
                              std::map<grpc::string, grpc::string> *vars) {
   (*vars)["Method"] = method->name();
   (*vars)["Request"] = method->input_type_name();
@@ -1078,13 +1112,13 @@ void PrintSourceClientMethod(Printer *printer, const Method *method,
         "const $Request$& request, "
         "::grpc::CompletionQueue* cq) {\n");
     printer->Print(*vars,
-                   "  return new "
-                   "::grpc::ClientAsyncResponseReader< $Response$>("
+                   "  return "
+                   "::grpc::ClientAsyncResponseReader< $Response$>::Create("
                    "channel_.get(), cq, "
                    "rpcmethod_$Method$_, "
                    "context, request);\n"
                    "}\n\n");
-  } else if (method->ClientOnlyStreaming()) {
+  } else if (ClientOnlyStreaming(method)) {
     printer->Print(*vars,
                    "::grpc::ClientWriter< $Request$>* "
                    "$ns$$Service$::Stub::$Method$Raw("
@@ -1101,12 +1135,12 @@ void PrintSourceClientMethod(Printer *printer, const Method *method,
                    "::grpc::ClientContext* context, $Response$* response, "
                    "::grpc::CompletionQueue* cq, void* tag) {\n");
     printer->Print(*vars,
-                   "  return new ::grpc::ClientAsyncWriter< $Request$>("
+                   "  return ::grpc::ClientAsyncWriter< $Request$>::Create("
                    "channel_.get(), cq, "
                    "rpcmethod_$Method$_, "
                    "context, response, tag);\n"
                    "}\n\n");
-  } else if (method->ServerOnlyStreaming()) {
+  } else if (ServerOnlyStreaming(method)) {
     printer->Print(
         *vars,
         "::grpc::ClientReader< $Response$>* "
@@ -1124,7 +1158,7 @@ void PrintSourceClientMethod(Printer *printer, const Method *method,
                    "::grpc::ClientContext* context, const $Request$& request, "
                    "::grpc::CompletionQueue* cq, void* tag) {\n");
     printer->Print(*vars,
-                   "  return new ::grpc::ClientAsyncReader< $Response$>("
+                   "  return ::grpc::ClientAsyncReader< $Response$>::Create("
                    "channel_.get(), cq, "
                    "rpcmethod_$Method$_, "
                    "context, request, tag);\n"
@@ -1146,17 +1180,19 @@ void PrintSourceClientMethod(Printer *printer, const Method *method,
         "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
         "$ns$$Service$::Stub::Async$Method$Raw(::grpc::ClientContext* context, "
         "::grpc::CompletionQueue* cq, void* tag) {\n");
-    printer->Print(*vars,
-                   "  return new "
-                   "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>("
-                   "channel_.get(), cq, "
-                   "rpcmethod_$Method$_, "
-                   "context, tag);\n"
-                   "}\n\n");
+    printer->Print(
+        *vars,
+        "  return "
+        "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>::Create("
+        "channel_.get(), cq, "
+        "rpcmethod_$Method$_, "
+        "context, tag);\n"
+        "}\n\n");
   }
 }
 
-void PrintSourceServerMethod(Printer *printer, const Method *method,
+void PrintSourceServerMethod(grpc_generator::Printer *printer,
+                             const grpc_generator::Method *method,
                              std::map<grpc::string, grpc::string> *vars) {
   (*vars)["Method"] = method->name();
   (*vars)["Request"] = method->input_type_name();
@@ -1173,7 +1209,7 @@ void PrintSourceServerMethod(Printer *printer, const Method *method,
         "  return ::grpc::Status("
         "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
     printer->Print("}\n\n");
-  } else if (method->ClientOnlyStreaming()) {
+  } else if (ClientOnlyStreaming(method)) {
     printer->Print(*vars,
                    "::grpc::Status $ns$$Service$::Service::$Method$("
                    "::grpc::ServerContext* context, "
@@ -1186,7 +1222,7 @@ void PrintSourceServerMethod(Printer *printer, const Method *method,
         "  return ::grpc::Status("
         "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
     printer->Print("}\n\n");
-  } else if (method->ServerOnlyStreaming()) {
+  } else if (ServerOnlyStreaming(method)) {
     printer->Print(*vars,
                    "::grpc::Status $ns$$Service$::Service::$Method$("
                    "::grpc::ServerContext* context, "
@@ -1214,7 +1250,8 @@ void PrintSourceServerMethod(Printer *printer, const Method *method,
   }
 }
 
-void PrintSourceService(Printer *printer, const Service *service,
+void PrintSourceService(grpc_generator::Printer *printer,
+                        const grpc_generator::Service *service,
                         std::map<grpc::string, grpc::string> *vars) {
   (*vars)["Service"] = service->name();
 
@@ -1250,9 +1287,9 @@ void PrintSourceService(Printer *printer, const Service *service,
       // NOTE: There is no reason to consider streamed-unary as a separate
       // category here since this part is setting up the client-side stub
       // and this appears as a NORMAL_RPC from the client-side.
-    } else if (method->ClientOnlyStreaming()) {
+    } else if (ClientOnlyStreaming(method.get())) {
       (*vars)["StreamingType"] = "CLIENT_STREAMING";
-    } else if (method->ServerOnlyStreaming()) {
+    } else if (ServerOnlyStreaming(method.get())) {
       (*vars)["StreamingType"] = "SERVER_STREAMING";
     } else {
       (*vars)["StreamingType"] = "BIDI_STREAMING";
@@ -1290,7 +1327,7 @@ void PrintSourceService(Printer *printer, const Service *service,
           "$Request$, "
           "$Response$>(\n"
           "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
-    } else if (method->ClientOnlyStreaming()) {
+    } else if (ClientOnlyStreaming(method.get())) {
       printer->Print(
           *vars,
           "AddMethod(new ::grpc::RpcServiceMethod(\n"
@@ -1299,7 +1336,7 @@ void PrintSourceService(Printer *printer, const Service *service,
           "    new ::grpc::ClientStreamingHandler< "
           "$ns$$Service$::Service, $Request$, $Response$>(\n"
           "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
-    } else if (method->ServerOnlyStreaming()) {
+    } else if (ServerOnlyStreaming(method.get())) {
       printer->Print(
           *vars,
           "AddMethod(new ::grpc::RpcServiceMethod(\n"
@@ -1330,7 +1367,8 @@ void PrintSourceService(Printer *printer, const Service *service,
   }
 }
 
-grpc::string GetSourceServices(File *file, const Parameters &params) {
+grpc::string GetSourceServices(grpc_generator::File *file,
+                               const Parameters &params) {
   grpc::string output;
   {
     // Scope the output stream so it closes and finalizes output to the string.
@@ -1358,7 +1396,8 @@ grpc::string GetSourceServices(File *file, const Parameters &params) {
   return output;
 }
 
-grpc::string GetSourceEpilogue(File *file, const Parameters & /*params*/) {
+grpc::string GetSourceEpilogue(grpc_generator::File *file,
+                               const Parameters & /*params*/) {
   grpc::string temp;
 
   if (!file->package().empty()) {
@@ -1375,4 +1414,180 @@ grpc::string GetSourceEpilogue(File *file, const Parameters & /*params*/) {
   return temp;
 }
 
+// TODO(mmukhi): Make sure we need parameters or not.
+grpc::string GetMockPrologue(grpc_generator::File *file,
+                             const Parameters & /*params*/) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+
+    vars["filename"] = file->filename();
+    vars["filename_base"] = file->filename_without_ext();
+    vars["message_header_ext"] = message_header_ext();
+    vars["service_header_ext"] = service_header_ext();
+
+    printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
+    printer->Print(vars,
+                   "// If you make any local change, they will be lost.\n");
+    printer->Print(vars, "// source: $filename$\n\n");
+
+    printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
+    printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
+    printer->Print(vars, file->additional_headers().c_str());
+    printer->Print(vars, "\n");
+  }
+  return output;
+}
+
+// TODO(mmukhi): Add client-stream and completion-queue headers.
+grpc::string GetMockIncludes(grpc_generator::File *file,
+                             const Parameters &params) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+
+    static const char *headers_strs[] = {
+        "grpc++/impl/codegen/async_stream.h",
+        "grpc++/impl/codegen/sync_stream.h", "gmock/gmock.h",
+    };
+    std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
+    PrintIncludes(printer.get(), headers, params);
+
+    if (!file->package().empty()) {
+      std::vector<grpc::string> parts = file->package_parts();
+
+      for (auto part = parts.begin(); part != parts.end(); part++) {
+        vars["part"] = *part;
+        printer->Print(vars, "namespace $part$ {\n");
+      }
+    }
+
+    printer->Print(vars, "\n");
+  }
+  return output;
+}
+
+void PrintMockClientMethods(grpc_generator::Printer *printer,
+                            const grpc_generator::Method *method,
+                            std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+
+  if (method->NoStreaming()) {
+    printer->Print(
+        *vars,
+        "MOCK_METHOD3($Method$, ::grpc::Status(::grpc::ClientContext* context, "
+        "const $Request$& request, $Response$* response));\n");
+    printer->Print(*vars,
+                   "MOCK_METHOD3(Async$Method$Raw, "
+                   "::grpc::ClientAsyncResponseReaderInterface< $Response$>*"
+                   "(::grpc::ClientContext* context, const $Request$& request, "
+                   "::grpc::CompletionQueue* cq));\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "MOCK_METHOD2($Method$Raw, "
+        "::grpc::ClientWriterInterface< $Request$>*"
+        "(::grpc::ClientContext* context, $Response$* response));\n");
+    printer->Print(*vars,
+                   "MOCK_METHOD4(Async$Method$Raw, "
+                   "::grpc::ClientAsyncWriterInterface< $Request$>*"
+                   "(::grpc::ClientContext* context, $Response$* response, "
+                   "::grpc::CompletionQueue* cq, void* tag));\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "MOCK_METHOD2($Method$Raw, "
+        "::grpc::ClientReaderInterface< $Response$>*"
+        "(::grpc::ClientContext* context, const $Request$& request));\n");
+    printer->Print(*vars,
+                   "MOCK_METHOD4(Async$Method$Raw, "
+                   "::grpc::ClientAsyncReaderInterface< $Response$>*"
+                   "(::grpc::ClientContext* context, const $Request$& request, "
+                   "::grpc::CompletionQueue* cq, void* tag));\n");
+  } else if (method->BidiStreaming()) {
+    printer->Print(
+        *vars,
+        "MOCK_METHOD1($Method$Raw, "
+        "::grpc::ClientReaderWriterInterface< $Request$, $Response$>*"
+        "(::grpc::ClientContext* context));\n");
+    printer->Print(
+        *vars,
+        "MOCK_METHOD3(Async$Method$Raw, "
+        "::grpc::ClientAsyncReaderWriterInterface<$Request$, $Response$>*"
+        "(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, "
+        "void* tag));\n");
+  }
+}
+
+void PrintMockService(grpc_generator::Printer *printer,
+                      const grpc_generator::Service *service,
+                      std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Service"] = service->name();
+
+  printer->Print(*vars,
+                 "class Mock$Service$Stub : public $Service$::StubInterface {\n"
+                 " public:\n");
+  printer->Indent();
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintMockClientMethods(printer, service->method(i).get(), vars);
+  }
+  printer->Outdent();
+  printer->Print("};\n");
+}
+
+grpc::string GetMockServices(grpc_generator::File *file,
+                             const Parameters &params) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+    // Package string is empty or ends with a dot. It is used to fully qualify
+    // method names.
+    vars["Package"] = file->package();
+    if (!file->package().empty()) {
+      vars["Package"].append(".");
+    }
+
+    if (!params.services_namespace.empty()) {
+      vars["services_namespace"] = params.services_namespace;
+      printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
+    }
+
+    for (int i = 0; i < file->service_count(); i++) {
+      PrintMockService(printer.get(), file->service(i).get(), &vars);
+      printer->Print("\n");
+    }
+
+    if (!params.services_namespace.empty()) {
+      printer->Print(vars, "} // namespace $services_namespace$\n\n");
+    }
+  }
+  return output;
+}
+
+grpc::string GetMockEpilogue(grpc_generator::File *file,
+                             const Parameters & /*params*/) {
+  grpc::string temp;
+
+  if (!file->package().empty()) {
+    std::vector<grpc::string> parts = file->package_parts();
+
+    for (auto part = parts.begin(); part != parts.end(); part++) {
+      temp.append("} // namespace ");
+      temp.append(*part);
+      temp.append("\n");
+    }
+    temp.append("\n");
+  }
+
+  return temp;
+}
+
 }  // namespace grpc_cpp_generator
diff --git a/src/compiler/cpp_generator.h b/src/compiler/cpp_generator.h
index d0343e9978b358e874512ba5d2bff8bb5755ad7d..6119ebe2896c9a9065a39a286b1d32440a4a7ac9 100644
--- a/src/compiler/cpp_generator.h
+++ b/src/compiler/cpp_generator.h
@@ -42,6 +42,7 @@
 #include <vector>
 
 #include "src/compiler/config.h"
+#include "src/compiler/schema_interface.h"
 
 #ifndef GRPC_CUSTOM_STRING
 #include <string>
@@ -64,93 +65,73 @@ struct Parameters {
   bool use_system_headers;
   // Prefix to any grpc include
   grpc::string grpc_search_path;
-};
-
-// A common interface for objects having comments in the source.
-// Return formatted comments to be inserted in generated code.
-struct CommentHolder {
-  virtual ~CommentHolder() {}
-  virtual grpc::string GetLeadingComments() const = 0;
-  virtual grpc::string GetTrailingComments() const = 0;
-};
-
-// An abstract interface representing a method.
-struct Method : public CommentHolder {
-  virtual ~Method() {}
-
-  virtual grpc::string name() const = 0;
-
-  virtual grpc::string input_type_name() const = 0;
-  virtual grpc::string output_type_name() const = 0;
-
-  virtual bool NoStreaming() const = 0;
-  virtual bool ClientOnlyStreaming() const = 0;
-  virtual bool ServerOnlyStreaming() const = 0;
-  virtual bool BidiStreaming() const = 0;
-};
-
-// An abstract interface representing a service.
-struct Service : public CommentHolder {
-  virtual ~Service() {}
-
-  virtual grpc::string name() const = 0;
-
-  virtual int method_count() const = 0;
-  virtual std::unique_ptr<const Method> method(int i) const = 0;
-};
-
-struct Printer {
-  virtual ~Printer() {}
-
-  virtual void Print(const std::map<grpc::string, grpc::string> &vars,
-                     const char *template_string) = 0;
-  virtual void Print(const char *string) = 0;
-  virtual void Indent() = 0;
-  virtual void Outdent() = 0;
-};
-
-// An interface that allows the source generated to be output using various
-// libraries/idls/serializers.
-struct File : public CommentHolder {
-  virtual ~File() {}
-
-  virtual grpc::string filename() const = 0;
-  virtual grpc::string filename_without_ext() const = 0;
-  virtual grpc::string message_header_ext() const = 0;
-  virtual grpc::string service_header_ext() const = 0;
-  virtual grpc::string package() const = 0;
-  virtual std::vector<grpc::string> package_parts() const = 0;
-  virtual grpc::string additional_headers() const = 0;
-
-  virtual int service_count() const = 0;
-  virtual std::unique_ptr<const Service> service(int i) const = 0;
-
-  virtual std::unique_ptr<Printer> CreatePrinter(grpc::string *str) const = 0;
+  // Generate GMOCK code to facilitate unit testing.
+  bool generate_mock_code;
 };
 
 // Return the prologue of the generated header file.
-grpc::string GetHeaderPrologue(File *file, const Parameters &params);
+grpc::string GetHeaderPrologue(grpc_generator::File *file,
+                               const Parameters &params);
 
 // Return the includes needed for generated header file.
-grpc::string GetHeaderIncludes(File *file, const Parameters &params);
+grpc::string GetHeaderIncludes(grpc_generator::File *file,
+                               const Parameters &params);
 
 // Return the includes needed for generated source file.
-grpc::string GetSourceIncludes(File *file, const Parameters &params);
+grpc::string GetSourceIncludes(grpc_generator::File *file,
+                               const Parameters &params);
 
 // Return the epilogue of the generated header file.
-grpc::string GetHeaderEpilogue(File *file, const Parameters &params);
+grpc::string GetHeaderEpilogue(grpc_generator::File *file,
+                               const Parameters &params);
 
 // Return the prologue of the generated source file.
-grpc::string GetSourcePrologue(File *file, const Parameters &params);
+grpc::string GetSourcePrologue(grpc_generator::File *file,
+                               const Parameters &params);
 
 // Return the services for generated header file.
-grpc::string GetHeaderServices(File *file, const Parameters &params);
+grpc::string GetHeaderServices(grpc_generator::File *file,
+                               const Parameters &params);
 
 // Return the services for generated source file.
-grpc::string GetSourceServices(File *file, const Parameters &params);
+grpc::string GetSourceServices(grpc_generator::File *file,
+                               const Parameters &params);
 
 // Return the epilogue of the generated source file.
-grpc::string GetSourceEpilogue(File *file, const Parameters &params);
+grpc::string GetSourceEpilogue(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the prologue of the generated mock file.
+grpc::string GetMockPrologue(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the includes needed for generated mock file.
+grpc::string GetMockIncludes(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the services for generated mock file.
+grpc::string GetMockServices(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the epilogue of generated mock file.
+grpc::string GetMockEpilogue(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the prologue of the generated mock file.
+grpc::string GetMockPrologue(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the includes needed for generated mock file.
+grpc::string GetMockIncludes(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the services for generated mock file.
+grpc::string GetMockServices(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the epilogue of generated mock file.
+grpc::string GetMockEpilogue(grpc_generator::File *file,
+                             const Parameters &params);
 
 }  // namespace grpc_cpp_generator
 
diff --git a/src/compiler/cpp_generator_helpers.h b/src/compiler/cpp_generator_helpers.h
index 87e278f1b9fe5a0b71067994a42ff0f9793acfb2..83932a09bb80eb94409dcff68b7189a6accfcb07 100644
--- a/src/compiler/cpp_generator_helpers.h
+++ b/src/compiler/cpp_generator_helpers.h
@@ -35,6 +35,7 @@
 #define GRPC_INTERNAL_COMPILER_CPP_GENERATOR_HELPERS_H
 
 #include <map>
+
 #include "src/compiler/config.h"
 #include "src/compiler/generator_helpers.h"
 
diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc
index 38f8f738ed93dceb1f47749b6b7bc6e20f028566..35f1bf3e93c8c11bb72087d08973d7d0e9ffe2eb 100644
--- a/src/compiler/cpp_plugin.cc
+++ b/src/compiler/cpp_plugin.cc
@@ -40,139 +40,8 @@
 #include "src/compiler/config.h"
 
 #include "src/compiler/cpp_generator.h"
-#include "src/compiler/cpp_generator_helpers.h"
 #include "src/compiler/generator_helpers.h"
-
-using grpc_cpp_generator::GetCppComments;
-
-class ProtoBufMethod : public grpc_cpp_generator::Method {
- public:
-  ProtoBufMethod(const grpc::protobuf::MethodDescriptor *method)
-      : method_(method) {}
-
-  grpc::string name() const { return method_->name(); }
-
-  grpc::string input_type_name() const {
-    return grpc_cpp_generator::ClassName(method_->input_type(), true);
-  }
-  grpc::string output_type_name() const {
-    return grpc_cpp_generator::ClassName(method_->output_type(), true);
-  }
-
-  bool NoStreaming() const {
-    return !method_->client_streaming() && !method_->server_streaming();
-  }
-
-  bool ClientOnlyStreaming() const {
-    return method_->client_streaming() && !method_->server_streaming();
-  }
-
-  bool ServerOnlyStreaming() const {
-    return !method_->client_streaming() && method_->server_streaming();
-  }
-
-  bool BidiStreaming() const {
-    return method_->client_streaming() && method_->server_streaming();
-  }
-
-  grpc::string GetLeadingComments() const {
-    return GetCppComments(method_, true);
-  }
-
-  grpc::string GetTrailingComments() const {
-    return GetCppComments(method_, false);
-  }
-
- private:
-  const grpc::protobuf::MethodDescriptor *method_;
-};
-
-class ProtoBufService : public grpc_cpp_generator::Service {
- public:
-  ProtoBufService(const grpc::protobuf::ServiceDescriptor *service)
-      : service_(service) {}
-
-  grpc::string name() const { return service_->name(); }
-
-  int method_count() const { return service_->method_count(); };
-  std::unique_ptr<const grpc_cpp_generator::Method> method(int i) const {
-    return std::unique_ptr<const grpc_cpp_generator::Method>(
-        new ProtoBufMethod(service_->method(i)));
-  };
-
-  grpc::string GetLeadingComments() const {
-    return GetCppComments(service_, true);
-  }
-
-  grpc::string GetTrailingComments() const {
-    return GetCppComments(service_, false);
-  }
-
- private:
-  const grpc::protobuf::ServiceDescriptor *service_;
-};
-
-class ProtoBufPrinter : public grpc_cpp_generator::Printer {
- public:
-  ProtoBufPrinter(grpc::string *str)
-      : output_stream_(str), printer_(&output_stream_, '$') {}
-
-  void Print(const std::map<grpc::string, grpc::string> &vars,
-             const char *string_template) {
-    printer_.Print(vars, string_template);
-  }
-
-  void Print(const char *string) { printer_.Print(string); }
-  void Indent() { printer_.Indent(); }
-  void Outdent() { printer_.Outdent(); }
-
- private:
-  grpc::protobuf::io::StringOutputStream output_stream_;
-  grpc::protobuf::io::Printer printer_;
-};
-
-class ProtoBufFile : public grpc_cpp_generator::File {
- public:
-  ProtoBufFile(const grpc::protobuf::FileDescriptor *file) : file_(file) {}
-
-  grpc::string filename() const { return file_->name(); }
-  grpc::string filename_without_ext() const {
-    return grpc_generator::StripProto(filename());
-  }
-
-  grpc::string message_header_ext() const { return ".pb.h"; }
-  grpc::string service_header_ext() const { return ".grpc.pb.h"; }
-
-  grpc::string package() const { return file_->package(); }
-  std::vector<grpc::string> package_parts() const {
-    return grpc_generator::tokenize(package(), ".");
-  }
-
-  grpc::string additional_headers() const { return ""; }
-
-  int service_count() const { return file_->service_count(); };
-  std::unique_ptr<const grpc_cpp_generator::Service> service(int i) const {
-    return std::unique_ptr<const grpc_cpp_generator::Service>(
-        new ProtoBufService(file_->service(i)));
-  }
-
-  std::unique_ptr<grpc_cpp_generator::Printer> CreatePrinter(
-      grpc::string *str) const {
-    return std::unique_ptr<grpc_cpp_generator::Printer>(
-        new ProtoBufPrinter(str));
-  }
-
-  grpc::string GetLeadingComments() const {
-    return GetCppComments(file_, true);
-  }
-
-  grpc::string GetTrailingComments() const {
-    return GetCppComments(file_, false);
-  }
-
- private:
-  const grpc::protobuf::FileDescriptor *file_;
-};
+#include "src/compiler/protobuf_plugin.h"
 
 class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
  public:
@@ -193,6 +62,7 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
 
     grpc_cpp_generator::Parameters generator_parameters;
     generator_parameters.use_system_headers = true;
+    generator_parameters.generate_mock_code = false;
 
     ProtoBufFile pbfile(file);
 
@@ -216,6 +86,13 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
           }
         } else if (param[0] == "grpc_search_path") {
           generator_parameters.grpc_search_path = param[1];
+        } else if (param[0] == "generate_mock_code") {
+          if (param[1] == "true") {
+            generator_parameters.generate_mock_code = true;
+          } else if (param[1] != "false") {
+            *error = grpc::string("Invalid parameter: ") + *parameter_string;
+            return false;
+          }
         } else {
           *error = grpc::string("Unknown parameter: ") + *parameter_string;
           return false;
@@ -245,6 +122,19 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
     grpc::protobuf::io::CodedOutputStream source_coded_out(source_output.get());
     source_coded_out.WriteRaw(source_code.data(), source_code.size());
 
+    if (!generator_parameters.generate_mock_code) {
+      return true;
+    }
+    grpc::string mock_code =
+        grpc_cpp_generator::GetMockPrologue(&pbfile, generator_parameters) +
+        grpc_cpp_generator::GetMockIncludes(&pbfile, generator_parameters) +
+        grpc_cpp_generator::GetMockServices(&pbfile, generator_parameters) +
+        grpc_cpp_generator::GetMockEpilogue(&pbfile, generator_parameters);
+    std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> mock_output(
+        context->Open(file_name + "_mock.grpc.pb.h"));
+    grpc::protobuf::io::CodedOutputStream mock_coded_out(mock_output.get());
+    mock_coded_out.WriteRaw(mock_code.data(), mock_code.size());
+
     return true;
   }
 
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index cc7a7a96aeab5c31256a2891c362d91446fb8d96..ce1e6b94c3fbaeadd3fdb920f2bc57544c2ed835 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -203,13 +203,13 @@ std::string GetServerClassName(const ServiceDescriptor *service) {
 std::string GetCSharpMethodType(MethodType method_type) {
   switch (method_type) {
     case METHODTYPE_NO_STREAMING:
-      return "MethodType.Unary";
+      return "grpc::MethodType.Unary";
     case METHODTYPE_CLIENT_STREAMING:
-      return "MethodType.ClientStreaming";
+      return "grpc::MethodType.ClientStreaming";
     case METHODTYPE_SERVER_STREAMING:
-      return "MethodType.ServerStreaming";
+      return "grpc::MethodType.ServerStreaming";
     case METHODTYPE_BIDI_STREAMING:
-      return "MethodType.DuplexStreaming";
+      return "grpc::MethodType.DuplexStreaming";
   }
   GOOGLE_LOG(FATAL) << "Can't get here.";
   return "";
@@ -243,16 +243,19 @@ std::string GetAccessLevel(bool internal_access) {
 std::string GetMethodReturnTypeClient(const MethodDescriptor *method) {
   switch (GetMethodType(method)) {
     case METHODTYPE_NO_STREAMING:
-      return "AsyncUnaryCall<" + GetClassName(method->output_type()) + ">";
+      return "grpc::AsyncUnaryCall<" + GetClassName(method->output_type()) +
+             ">";
     case METHODTYPE_CLIENT_STREAMING:
-      return "AsyncClientStreamingCall<" + GetClassName(method->input_type()) +
-             ", " + GetClassName(method->output_type()) + ">";
+      return "grpc::AsyncClientStreamingCall<" +
+             GetClassName(method->input_type()) + ", " +
+             GetClassName(method->output_type()) + ">";
     case METHODTYPE_SERVER_STREAMING:
-      return "AsyncServerStreamingCall<" + GetClassName(method->output_type()) +
-             ">";
+      return "grpc::AsyncServerStreamingCall<" +
+             GetClassName(method->output_type()) + ">";
     case METHODTYPE_BIDI_STREAMING:
-      return "AsyncDuplexStreamingCall<" + GetClassName(method->input_type()) +
-             ", " + GetClassName(method->output_type()) + ">";
+      return "grpc::AsyncDuplexStreamingCall<" +
+             GetClassName(method->input_type()) + ", " +
+             GetClassName(method->output_type()) + ">";
   }
   GOOGLE_LOG(FATAL) << "Can't get here.";
   return "";
@@ -265,7 +268,7 @@ std::string GetMethodRequestParamServer(const MethodDescriptor *method) {
       return GetClassName(method->input_type()) + " request";
     case METHODTYPE_CLIENT_STREAMING:
     case METHODTYPE_BIDI_STREAMING:
-      return "IAsyncStreamReader<" + GetClassName(method->input_type()) +
+      return "grpc::IAsyncStreamReader<" + GetClassName(method->input_type()) +
              "> requestStream";
   }
   GOOGLE_LOG(FATAL) << "Can't get here.";
@@ -293,8 +296,8 @@ std::string GetMethodResponseStreamMaybe(const MethodDescriptor *method) {
       return "";
     case METHODTYPE_SERVER_STREAMING:
     case METHODTYPE_BIDI_STREAMING:
-      return ", IServerStreamWriter<" + GetClassName(method->output_type()) +
-             "> responseStream";
+      return ", grpc::IServerStreamWriter<" +
+             GetClassName(method->output_type()) + "> responseStream";
   }
   GOOGLE_LOG(FATAL) << "Can't get here.";
   return "";
@@ -325,8 +328,8 @@ void GenerateMarshallerFields(Printer *out, const ServiceDescriptor *service) {
   for (size_t i = 0; i < used_messages.size(); i++) {
     const Descriptor *message = used_messages[i];
     out->Print(
-        "static readonly Marshaller<$type$> $fieldname$ = "
-        "Marshallers.Create((arg) => "
+        "static readonly grpc::Marshaller<$type$> $fieldname$ = "
+        "grpc::Marshallers.Create((arg) => "
         "global::Google.Protobuf.MessageExtensions.ToByteArray(arg), "
         "$type$.Parser.ParseFrom);\n",
         "fieldname", GetMarshallerFieldName(message), "type",
@@ -337,8 +340,8 @@ void GenerateMarshallerFields(Printer *out, const ServiceDescriptor *service) {
 
 void GenerateStaticMethodField(Printer *out, const MethodDescriptor *method) {
   out->Print(
-      "static readonly Method<$request$, $response$> $fieldname$ = new "
-      "Method<$request$, $response$>(\n",
+      "static readonly grpc::Method<$request$, $response$> $fieldname$ = new "
+      "grpc::Method<$request$, $response$>(\n",
       "fieldname", GetMethodFieldName(method), "request",
       GetClassName(method->input_type()), "response",
       GetClassName(method->output_type()));
@@ -389,7 +392,7 @@ void GenerateServerClass(Printer *out, const ServiceDescriptor *service) {
     out->Print(
         "public virtual $returntype$ "
         "$methodname$($request$$response_stream_maybe$, "
-        "ServerCallContext context)\n",
+        "grpc::ServerCallContext context)\n",
         "methodname", method->name(), "returntype",
         GetMethodReturnTypeServer(method), "request",
         GetMethodRequestParamServer(method), "response_stream_maybe",
@@ -397,8 +400,8 @@ void GenerateServerClass(Printer *out, const ServiceDescriptor *service) {
     out->Print("{\n");
     out->Indent();
     out->Print(
-        "throw new RpcException("
-        "new Status(StatusCode.Unimplemented, \"\"));\n");
+        "throw new grpc::RpcException("
+        "new grpc::Status(grpc::StatusCode.Unimplemented, \"\"));\n");
     out->Outdent();
     out->Print("}\n\n");
   }
@@ -410,7 +413,7 @@ void GenerateServerClass(Printer *out, const ServiceDescriptor *service) {
 void GenerateClientStub(Printer *out, const ServiceDescriptor *service) {
   out->Print("/// <summary>Client for $servicename$</summary>\n", "servicename",
              GetServiceClassName(service));
-  out->Print("public partial class $name$ : ClientBase<$name$>\n", "name",
+  out->Print("public partial class $name$ : grpc::ClientBase<$name$>\n", "name",
              GetClientClassName(service));
   out->Print("{\n");
   out->Indent();
@@ -421,7 +424,7 @@ void GenerateClientStub(Printer *out, const ServiceDescriptor *service) {
       "/// <param name=\"channel\">The channel to use to make remote "
       "calls.</param>\n",
       "servicename", GetServiceClassName(service));
-  out->Print("public $name$(Channel channel) : base(channel)\n", "name",
+  out->Print("public $name$(grpc::Channel channel) : base(channel)\n", "name",
              GetClientClassName(service));
   out->Print("{\n");
   out->Print("}\n");
@@ -431,8 +434,9 @@ void GenerateClientStub(Printer *out, const ServiceDescriptor *service) {
       "/// <param name=\"callInvoker\">The callInvoker to use to make remote "
       "calls.</param>\n",
       "servicename", GetServiceClassName(service));
-  out->Print("public $name$(CallInvoker callInvoker) : base(callInvoker)\n",
-             "name", GetClientClassName(service));
+  out->Print(
+      "public $name$(grpc::CallInvoker callInvoker) : base(callInvoker)\n",
+      "name", GetClientClassName(service));
   out->Print("{\n");
   out->Print("}\n");
   out->Print(
@@ -461,7 +465,8 @@ void GenerateClientStub(Printer *out, const ServiceDescriptor *service) {
       // unary calls have an extra synchronous stub method
       GenerateDocCommentClientMethod(out, method, true, false);
       out->Print(
-          "public virtual $response$ $methodname$($request$ request, Metadata "
+          "public virtual $response$ $methodname$($request$ request, "
+          "grpc::Metadata "
           "headers = null, DateTime? deadline = null, CancellationToken "
           "cancellationToken = default(CancellationToken))\n",
           "methodname", method->name(), "request",
@@ -470,7 +475,8 @@ void GenerateClientStub(Printer *out, const ServiceDescriptor *service) {
       out->Print("{\n");
       out->Indent();
       out->Print(
-          "return $methodname$(request, new CallOptions(headers, deadline, "
+          "return $methodname$(request, new grpc::CallOptions(headers, "
+          "deadline, "
           "cancellationToken));\n",
           "methodname", method->name());
       out->Outdent();
@@ -480,7 +486,7 @@ void GenerateClientStub(Printer *out, const ServiceDescriptor *service) {
       GenerateDocCommentClientMethod(out, method, true, true);
       out->Print(
           "public virtual $response$ $methodname$($request$ request, "
-          "CallOptions options)\n",
+          "grpc::CallOptions options)\n",
           "methodname", method->name(), "request",
           GetClassName(method->input_type()), "response",
           GetClassName(method->output_type()));
@@ -500,7 +506,8 @@ void GenerateClientStub(Printer *out, const ServiceDescriptor *service) {
     }
     GenerateDocCommentClientMethod(out, method, false, false);
     out->Print(
-        "public virtual $returntype$ $methodname$($request_maybe$Metadata "
+        "public virtual $returntype$ "
+        "$methodname$($request_maybe$grpc::Metadata "
         "headers = null, DateTime? deadline = null, CancellationToken "
         "cancellationToken = default(CancellationToken))\n",
         "methodname", method_name, "request_maybe",
@@ -510,7 +517,8 @@ void GenerateClientStub(Printer *out, const ServiceDescriptor *service) {
     out->Indent();
 
     out->Print(
-        "return $methodname$($request_maybe$new CallOptions(headers, deadline, "
+        "return $methodname$($request_maybe$new grpc::CallOptions(headers, "
+        "deadline, "
         "cancellationToken));\n",
         "methodname", method_name, "request_maybe",
         GetMethodRequestParamMaybe(method, true));
@@ -520,7 +528,8 @@ void GenerateClientStub(Printer *out, const ServiceDescriptor *service) {
     // overload taking CallOptions as a param
     GenerateDocCommentClientMethod(out, method, false, true);
     out->Print(
-        "public virtual $returntype$ $methodname$($request_maybe$CallOptions "
+        "public virtual $returntype$ "
+        "$methodname$($request_maybe$grpc::CallOptions "
         "options)\n",
         "methodname", method_name, "request_maybe",
         GetMethodRequestParamMaybe(method), "returntype",
@@ -587,13 +596,13 @@ void GenerateBindServiceMethod(Printer *out, const ServiceDescriptor *service) {
       "/// <param name=\"serviceImpl\">An object implementing the server-side"
       " handling logic.</param>\n");
   out->Print(
-      "public static ServerServiceDefinition BindService($implclass$ "
+      "public static grpc::ServerServiceDefinition BindService($implclass$ "
       "serviceImpl)\n",
       "implclass", GetServerClassName(service));
   out->Print("{\n");
   out->Indent();
 
-  out->Print("return ServerServiceDefinition.CreateBuilder()\n");
+  out->Print("return grpc::ServerServiceDefinition.CreateBuilder()\n");
   out->Indent();
   out->Indent();
   for (int i = 0; i < service->method_count(); i++) {
@@ -681,7 +690,7 @@ grpc::string GetServices(const FileDescriptor *file, bool generate_client,
     out.Print("using System;\n");
     out.Print("using System.Threading;\n");
     out.Print("using System.Threading.Tasks;\n");
-    out.Print("using Grpc.Core;\n");
+    out.Print("using grpc = global::Grpc.Core;\n");
     out.Print("\n");
 
     out.Print("namespace $namespace$ {\n", "namespace", GetFileNamespace(file));
diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc
index 8de0997ebeae33f503c725219c1690570bab4c3c..5178115e44c67995241d93d5289361b59a31aff3 100644
--- a/src/compiler/objective_c_plugin.cc
+++ b/src/compiler/objective_c_plugin.cc
@@ -68,6 +68,7 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
       ::grpc::string imports = ::grpc::string("#import \"") + file_name +
                                ".pbobjc.h\"\n\n"
                                "#import <ProtoRPC/ProtoService.h>\n"
+                               "#import <ProtoRPC/ProtoRPC.h>\n"
                                "#import <RxLibrary/GRXWriteable.h>\n"
                                "#import <RxLibrary/GRXWriter.h>\n";
 
diff --git a/src/compiler/php_generator.cc b/src/compiler/php_generator.cc
index fba8cbaa97b269e701bf9ba13f886fd7622fd62c..7d51d4030135212cfe4265cf3e7577c0811d27a3 100644
--- a/src/compiler/php_generator.cc
+++ b/src/compiler/php_generator.cc
@@ -118,7 +118,7 @@ void PrintService(const ServiceDescriptor *service, Printer *out) {
   out->Print(
       "/**\n * @param string $$hostname hostname\n"
       " * @param array $$opts channel options\n"
-      " * @param Grpc\\Channel $$channel (optional) re-use channel "
+      " * @param \\Grpc\\Channel $$channel (optional) re-use channel "
       "object\n */\n"
       "public function __construct($$hostname, $$opts, "
       "$$channel = null) {\n");
diff --git a/src/compiler/protobuf_plugin.h b/src/compiler/protobuf_plugin.h
new file mode 100644
index 0000000000000000000000000000000000000000..cb01bd349872f23ca1473fb2b9304fefd5b10045
--- /dev/null
+++ b/src/compiler/protobuf_plugin.h
@@ -0,0 +1,210 @@
+/*
+ *
+ * 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_COMPILER_PROTOBUF_PLUGIN_H
+#define GRPC_INTERNAL_COMPILER_PROTOBUF_PLUGIN_H
+
+#include "src/compiler/config.h"
+#include "src/compiler/cpp_generator_helpers.h"
+#include "src/compiler/python_generator_helpers.h"
+#include "src/compiler/python_private_generator.h"
+#include "src/compiler/schema_interface.h"
+
+#include <vector>
+
+// Get leading or trailing comments in a string.
+template <typename DescriptorType>
+inline grpc::string GetCommentsHelper(const DescriptorType *desc, bool leading,
+                                      const grpc::string &prefix) {
+  return grpc_generator::GetPrefixedComments(desc, leading, prefix);
+}
+
+class ProtoBufMethod : public grpc_generator::Method {
+ public:
+  ProtoBufMethod(const grpc::protobuf::MethodDescriptor *method)
+      : method_(method) {}
+
+  grpc::string name() const { return method_->name(); }
+
+  grpc::string input_type_name() const {
+    return grpc_cpp_generator::ClassName(method_->input_type(), true);
+  }
+  grpc::string output_type_name() const {
+    return grpc_cpp_generator::ClassName(method_->output_type(), true);
+  }
+
+  grpc::string get_input_type_name() const {
+    return method_->input_type()->file()->name();
+  }
+  grpc::string get_output_type_name() const {
+    return method_->output_type()->file()->name();
+  }
+
+  bool get_module_and_message_path_input(grpc::string *str,
+                                         grpc::string generator_file_name,
+                                         bool generate_in_pb2_grpc,
+                                         grpc::string import_prefix) const {
+    return grpc_python_generator::GetModuleAndMessagePath(
+        method_->input_type(), str, generator_file_name, generate_in_pb2_grpc,
+        import_prefix);
+  }
+
+  bool get_module_and_message_path_output(grpc::string *str,
+                                          grpc::string generator_file_name,
+                                          bool generate_in_pb2_grpc,
+                                          grpc::string import_prefix) const {
+    return grpc_python_generator::GetModuleAndMessagePath(
+        method_->output_type(), str, generator_file_name, generate_in_pb2_grpc,
+        import_prefix);
+  }
+
+  bool NoStreaming() const {
+    return !method_->client_streaming() && !method_->server_streaming();
+  }
+
+  bool ClientStreaming() const { return method_->client_streaming(); }
+
+  bool ServerStreaming() const { return method_->server_streaming(); }
+
+  bool BidiStreaming() const {
+    return method_->client_streaming() && method_->server_streaming();
+  }
+
+  grpc::string GetLeadingComments(const grpc::string prefix) const {
+    return GetCommentsHelper(method_, true, prefix);
+  }
+
+  grpc::string GetTrailingComments(const grpc::string prefix) const {
+    return GetCommentsHelper(method_, false, prefix);
+  }
+
+  vector<grpc::string> GetAllComments() const {
+    return grpc_python_generator::get_all_comments(method_);
+  }
+
+ private:
+  const grpc::protobuf::MethodDescriptor *method_;
+};
+
+class ProtoBufService : public grpc_generator::Service {
+ public:
+  ProtoBufService(const grpc::protobuf::ServiceDescriptor *service)
+      : service_(service) {}
+
+  grpc::string name() const { return service_->name(); }
+
+  int method_count() const { return service_->method_count(); };
+  std::unique_ptr<const grpc_generator::Method> method(int i) const {
+    return std::unique_ptr<const grpc_generator::Method>(
+        new ProtoBufMethod(service_->method(i)));
+  };
+
+  grpc::string GetLeadingComments(const grpc::string prefix) const {
+    return GetCommentsHelper(service_, true, prefix);
+  }
+
+  grpc::string GetTrailingComments(const grpc::string prefix) const {
+    return GetCommentsHelper(service_, false, prefix);
+  }
+
+  vector<grpc::string> GetAllComments() const {
+    return grpc_python_generator::get_all_comments(service_);
+  }
+
+ private:
+  const grpc::protobuf::ServiceDescriptor *service_;
+};
+
+class ProtoBufPrinter : public grpc_generator::Printer {
+ public:
+  ProtoBufPrinter(grpc::string *str)
+      : output_stream_(str), printer_(&output_stream_, '$') {}
+
+  void Print(const std::map<grpc::string, grpc::string> &vars,
+             const char *string_template) {
+    printer_.Print(vars, string_template);
+  }
+
+  void Print(const char *string) { printer_.Print(string); }
+  void Indent() { printer_.Indent(); }
+  void Outdent() { printer_.Outdent(); }
+
+ private:
+  grpc::protobuf::io::StringOutputStream output_stream_;
+  grpc::protobuf::io::Printer printer_;
+};
+
+class ProtoBufFile : public grpc_generator::File {
+ public:
+  ProtoBufFile(const grpc::protobuf::FileDescriptor *file) : file_(file) {}
+
+  grpc::string filename() const { return file_->name(); }
+  grpc::string filename_without_ext() const {
+    return grpc_generator::StripProto(filename());
+  }
+
+  grpc::string package() const { return file_->package(); }
+  std::vector<grpc::string> package_parts() const {
+    return grpc_generator::tokenize(package(), ".");
+  }
+
+  grpc::string additional_headers() const { return ""; }
+
+  int service_count() const { return file_->service_count(); };
+  std::unique_ptr<const grpc_generator::Service> service(int i) const {
+    return std::unique_ptr<const grpc_generator::Service>(
+        new ProtoBufService(file_->service(i)));
+  }
+
+  std::unique_ptr<grpc_generator::Printer> CreatePrinter(
+      grpc::string *str) const {
+    return std::unique_ptr<grpc_generator::Printer>(new ProtoBufPrinter(str));
+  }
+
+  grpc::string GetLeadingComments(const grpc::string prefix) const {
+    return GetCommentsHelper(file_, true, prefix);
+  }
+
+  grpc::string GetTrailingComments(const grpc::string prefix) const {
+    return GetCommentsHelper(file_, false, prefix);
+  }
+
+  vector<grpc::string> GetAllComments() const {
+    return grpc_python_generator::get_all_comments(file_);
+  }
+
+ private:
+  const grpc::protobuf::FileDescriptor *file_;
+};
+
+#endif  // GRPC_INTERNAL_COMPILER_PROTOBUF_PLUGIN_H
diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc
index 4841da8da8e8529f85966081e9d193b1b8bc2451..278e5072b264d3c53cb15db18168373f8bb52541 100644
--- a/src/compiler/python_generator.cc
+++ b/src/compiler/python_generator.cc
@@ -47,20 +47,15 @@
 
 #include "src/compiler/config.h"
 #include "src/compiler/generator_helpers.h"
+#include "src/compiler/protobuf_plugin.h"
 #include "src/compiler/python_generator.h"
+#include "src/compiler/python_generator_helpers.h"
+#include "src/compiler/python_private_generator.h"
 
-using grpc_generator::StringReplace;
-using grpc_generator::StripProto;
-using grpc::protobuf::Descriptor;
 using grpc::protobuf::FileDescriptor;
-using grpc::protobuf::MethodDescriptor;
-using grpc::protobuf::ServiceDescriptor;
 using grpc::protobuf::compiler::GeneratorContext;
 using grpc::protobuf::io::CodedOutputStream;
-using grpc::protobuf::io::Printer;
-using grpc::protobuf::io::StringOutputStream;
 using grpc::protobuf::io::ZeroCopyOutputStream;
-using std::initializer_list;
 using std::make_pair;
 using std::map;
 using std::pair;
@@ -71,9 +66,10 @@ using std::set;
 
 namespace grpc_python_generator {
 
+grpc::string generator_file_name;
+
 namespace {
 
-typedef vector<const Descriptor*> DescriptorVector;
 typedef map<grpc::string, grpc::string> StringMap;
 typedef vector<grpc::string> StringVector;
 typedef tuple<grpc::string, grpc::string> StringPair;
@@ -88,132 +84,31 @@ typedef set<StringPair> StringPairSet;
 // }
 class IndentScope {
  public:
-  explicit IndentScope(Printer* printer) : printer_(printer) {
+  explicit IndentScope(grpc_generator::Printer* printer) : printer_(printer) {
     printer_->Indent();
   }
 
   ~IndentScope() { printer_->Outdent(); }
 
  private:
-  Printer* printer_;
-};
-
-// TODO(https://github.com/google/protobuf/issues/888):
-// Export `ModuleName` from protobuf's
-// `src/google/protobuf/compiler/python/python_generator.cc` file.
-grpc::string ModuleName(const grpc::string& filename) {
-  grpc::string basename = StripProto(filename);
-  basename = StringReplace(basename, "-", "_");
-  basename = StringReplace(basename, "/", ".");
-  return basename + "_pb2";
-}
-
-// TODO(https://github.com/google/protobuf/issues/888):
-// Export `ModuleAlias` from protobuf's
-// `src/google/protobuf/compiler/python/python_generator.cc` file.
-grpc::string ModuleAlias(const grpc::string& filename) {
-  grpc::string module_name = ModuleName(filename);
-  // We can't have dots in the module name, so we replace each with _dot_.
-  // But that could lead to a collision between a.b and a_dot_b, so we also
-  // duplicate each underscore.
-  module_name = StringReplace(module_name, "_", "__");
-  module_name = StringReplace(module_name, ".", "_dot_");
-  return module_name;
-}
-
-// Tucks all generator state in an anonymous namespace away from
-// PythonGrpcGenerator and the header file, mostly to encourage future changes
-// to not require updates to the grpcio-tools C++ code part. Assumes that it is
-// only ever used from a single thread.
-struct PrivateGenerator {
-  const GeneratorConfiguration& config;
-  const FileDescriptor* file;
-
-  bool generate_in_pb2_grpc;
-
-  Printer* out;
-
-  PrivateGenerator(const GeneratorConfiguration& config,
-                   const FileDescriptor* file);
-
-  std::pair<bool, grpc::string> GetGrpcServices();
-
- private:
-  bool PrintPreamble();
-  bool PrintBetaPreamble();
-  bool PrintGAServices();
-  bool PrintBetaServices();
-
-  bool PrintAddServicerToServer(
-      const grpc::string& package_qualified_service_name,
-      const ServiceDescriptor* service);
-  bool PrintServicer(const ServiceDescriptor* service);
-  bool PrintStub(const grpc::string& package_qualified_service_name,
-                 const ServiceDescriptor* service);
-
-  bool PrintBetaServicer(const ServiceDescriptor* service);
-  bool PrintBetaServerFactory(
-      const grpc::string& package_qualified_service_name,
-      const ServiceDescriptor* service);
-  bool PrintBetaStub(const ServiceDescriptor* service);
-  bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
-                            const ServiceDescriptor* service);
-
-  // Get all comments (leading, leading_detached, trailing) and print them as a
-  // docstring. Any leading space of a line will be removed, but the line
-  // wrapping will not be changed.
-  template <typename DescriptorType>
-  void PrintAllComments(const DescriptorType* descriptor);
-
-  bool GetModuleAndMessagePath(const Descriptor* type, grpc::string* out);
+  grpc_generator::Printer* printer_;
 };
 
 PrivateGenerator::PrivateGenerator(const GeneratorConfiguration& config,
-                                   const FileDescriptor* file)
+                                   const grpc_generator::File* file)
     : config(config), file(file) {}
 
-bool PrivateGenerator::GetModuleAndMessagePath(const Descriptor* type,
-                                               grpc::string* out) {
-  const Descriptor* path_elem_type = type;
-  DescriptorVector message_path;
-  do {
-    message_path.push_back(path_elem_type);
-    path_elem_type = path_elem_type->containing_type();
-  } while (path_elem_type);  // implicit nullptr comparison; don't be explicit
-  grpc::string file_name = type->file()->name();
-  static const int proto_suffix_length = strlen(".proto");
-  if (!(file_name.size() > static_cast<size_t>(proto_suffix_length) &&
-        file_name.find_last_of(".proto") == file_name.size() - 1)) {
-    return false;
-  }
-  grpc::string generator_file_name = file->name();
-  grpc::string module;
-  if (generator_file_name != file_name || generate_in_pb2_grpc) {
-    module = ModuleAlias(file_name) + ".";
-  } else {
-    module = "";
-  }
-  grpc::string message_type;
-  for (DescriptorVector::reverse_iterator path_iter = message_path.rbegin();
-       path_iter != message_path.rend(); ++path_iter) {
-    message_type += (*path_iter)->name() + ".";
-  }
-  // no pop_back prior to C++11
-  message_type.resize(message_type.size() - 1);
-  *out = module + message_type;
-  return true;
-}
-
-template <typename DescriptorType>
-void PrivateGenerator::PrintAllComments(const DescriptorType* descriptor) {
-  StringVector comments;
-  grpc_generator::GetComment(
-      descriptor, grpc_generator::COMMENTTYPE_LEADING_DETACHED, &comments);
-  grpc_generator::GetComment(descriptor, grpc_generator::COMMENTTYPE_LEADING,
-                             &comments);
-  grpc_generator::GetComment(descriptor, grpc_generator::COMMENTTYPE_TRAILING,
-                             &comments);
+void PrivateGenerator::PrintAllComments(StringVector comments,
+                                        grpc_generator::Printer* out) {
   if (comments.empty()) {
+    // Python requires code structures like class and def to have
+    // a body, even if it is just "pass" or a docstring.  We need
+    // to ensure not to generate empty bodies. We could do something
+    // smarter and more sophisticated, but at the moment, if there is
+    // no docstring to print, we simply emit "pass" to ensure validity
+    // of the generated code.
+    out->Print("# missing associated documentation comment in .proto file\n");
+    out->Print("pass\n");
     return;
   }
   out->Print("\"\"\"");
@@ -228,10 +123,12 @@ void PrivateGenerator::PrintAllComments(const DescriptorType* descriptor) {
   out->Print("\"\"\"\n");
 }
 
-bool PrivateGenerator::PrintBetaServicer(const ServiceDescriptor* service) {
+bool PrivateGenerator::PrintBetaServicer(const grpc_generator::Service* service,
+                                         grpc_generator::Printer* out) {
+  StringMap service_dict;
+  service_dict["Service"] = service->name();
   out->Print("\n\n");
-  out->Print("class Beta$Service$Servicer(object):\n", "Service",
-             service->name());
+  out->Print(service_dict, "class Beta$Service$Servicer(object):\n");
   {
     IndentScope raii_class_indent(out);
     out->Print(
@@ -241,16 +138,20 @@ bool PrivateGenerator::PrintBetaServicer(const ServiceDescriptor* service) {
         "generated\n"
         "only to ease transition from grpcio<0.15.0 to "
         "grpcio>=0.15.0.\"\"\"\n");
-    PrintAllComments(service);
+    StringVector service_comments = service->GetAllComments();
+    PrintAllComments(service_comments, out);
     for (int i = 0; i < service->method_count(); ++i) {
-      const MethodDescriptor* method = service->method(i);
+      auto method = service->method(i);
       grpc::string arg_name =
-          method->client_streaming() ? "request_iterator" : "request";
-      out->Print("def $Method$(self, $ArgName$, context):\n", "Method",
-                 method->name(), "ArgName", arg_name);
+          method->ClientStreaming() ? "request_iterator" : "request";
+      StringMap method_dict;
+      method_dict["Method"] = method->name();
+      method_dict["ArgName"] = arg_name;
+      out->Print(method_dict, "def $Method$(self, $ArgName$, context):\n");
       {
         IndentScope raii_method_indent(out);
-        PrintAllComments(method);
+        StringVector method_comments = method->GetAllComments();
+        PrintAllComments(method_comments, out);
         out->Print("context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)\n");
       }
     }
@@ -258,9 +159,12 @@ bool PrivateGenerator::PrintBetaServicer(const ServiceDescriptor* service) {
   return true;
 }
 
-bool PrivateGenerator::PrintBetaStub(const ServiceDescriptor* service) {
+bool PrivateGenerator::PrintBetaStub(const grpc_generator::Service* service,
+                                     grpc_generator::Printer* out) {
+  StringMap service_dict;
+  service_dict["Service"] = service->name();
   out->Print("\n\n");
-  out->Print("class Beta$Service$Stub(object):\n", "Service", service->name());
+  out->Print(service_dict, "class Beta$Service$Stub(object):\n");
   {
     IndentScope raii_class_indent(out);
     out->Print(
@@ -270,11 +174,12 @@ bool PrivateGenerator::PrintBetaStub(const ServiceDescriptor* service) {
         "generated\n"
         "only to ease transition from grpcio<0.15.0 to "
         "grpcio>=0.15.0.\"\"\"\n");
-    PrintAllComments(service);
+    StringVector service_comments = service->GetAllComments();
+    PrintAllComments(service_comments, out);
     for (int i = 0; i < service->method_count(); ++i) {
-      const MethodDescriptor* method = service->method(i);
+      auto method = service->method(i);
       grpc::string arg_name =
-          method->client_streaming() ? "request_iterator" : "request";
+          method->ClientStreaming() ? "request_iterator" : "request";
       StringMap method_dict;
       method_dict["Method"] = method->name();
       method_dict["ArgName"] = arg_name;
@@ -283,10 +188,11 @@ bool PrivateGenerator::PrintBetaStub(const ServiceDescriptor* service) {
                  "with_call=False, protocol_options=None):\n");
       {
         IndentScope raii_method_indent(out);
-        PrintAllComments(method);
+        StringVector method_comments = method->GetAllComments();
+        PrintAllComments(method_comments, out);
         out->Print("raise NotImplementedError()\n");
       }
-      if (!method->server_streaming()) {
+      if (!method->ServerStreaming()) {
         out->Print(method_dict, "$Method$.future = None\n");
       }
     }
@@ -296,12 +202,13 @@ bool PrivateGenerator::PrintBetaStub(const ServiceDescriptor* service) {
 
 bool PrivateGenerator::PrintBetaServerFactory(
     const grpc::string& package_qualified_service_name,
-    const ServiceDescriptor* service) {
+    const grpc_generator::Service* service, grpc_generator::Printer* out) {
+  StringMap service_dict;
+  service_dict["Service"] = service->name();
   out->Print("\n\n");
-  out->Print(
-      "def beta_create_$Service$_server(servicer, pool=None, "
-      "pool_size=None, default_timeout=None, maximum_timeout=None):\n",
-      "Service", service->name());
+  out->Print(service_dict,
+             "def beta_create_$Service$_server(servicer, pool=None, "
+             "pool_size=None, default_timeout=None, maximum_timeout=None):\n");
   {
     IndentScope raii_create_server_indent(out);
     out->Print(
@@ -314,19 +221,21 @@ bool PrivateGenerator::PrintBetaServerFactory(
     StringMap input_message_modules_and_classes;
     StringMap output_message_modules_and_classes;
     for (int i = 0; i < service->method_count(); ++i) {
-      const MethodDescriptor* method = service->method(i);
+      auto method = service->method(i);
       const grpc::string method_implementation_constructor =
-          grpc::string(method->client_streaming() ? "stream_" : "unary_") +
-          grpc::string(method->server_streaming() ? "stream_" : "unary_") +
+          grpc::string(method->ClientStreaming() ? "stream_" : "unary_") +
+          grpc::string(method->ServerStreaming() ? "stream_" : "unary_") +
           "inline";
       grpc::string input_message_module_and_class;
-      if (!GetModuleAndMessagePath(method->input_type(),
-                                   &input_message_module_and_class)) {
+      if (!method->get_module_and_message_path_input(
+              &input_message_module_and_class, generator_file_name,
+              generate_in_pb2_grpc, config.import_prefix)) {
         return false;
       }
       grpc::string output_message_module_and_class;
-      if (!GetModuleAndMessagePath(method->output_type(),
-                                   &output_message_module_and_class)) {
+      if (!method->get_module_and_message_path_output(
+              &output_message_module_and_class, generator_file_name,
+              generate_in_pb2_grpc, config.import_prefix)) {
         return false;
       }
       method_implementation_constructors.insert(
@@ -336,19 +245,21 @@ bool PrivateGenerator::PrintBetaServerFactory(
       output_message_modules_and_classes.insert(
           make_pair(method->name(), output_message_module_and_class));
     }
+    StringMap method_dict;
+    method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
     out->Print("request_deserializers = {\n");
     for (StringMap::iterator name_and_input_module_class_pair =
              input_message_modules_and_classes.begin();
          name_and_input_module_class_pair !=
          input_message_modules_and_classes.end();
          name_and_input_module_class_pair++) {
+      method_dict["MethodName"] = name_and_input_module_class_pair->first;
+      method_dict["InputTypeModuleAndClass"] =
+          name_and_input_module_class_pair->second;
       IndentScope raii_indent(out);
-      out->Print(
-          "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
-          "$InputTypeModuleAndClass$.FromString,\n",
-          "PackageQualifiedServiceName", package_qualified_service_name,
-          "MethodName", name_and_input_module_class_pair->first,
-          "InputTypeModuleAndClass", name_and_input_module_class_pair->second);
+      out->Print(method_dict,
+                 "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
+                 "$InputTypeModuleAndClass$.FromString,\n");
     }
     out->Print("}\n");
     out->Print("response_serializers = {\n");
@@ -357,14 +268,13 @@ bool PrivateGenerator::PrintBetaServerFactory(
          name_and_output_module_class_pair !=
          output_message_modules_and_classes.end();
          name_and_output_module_class_pair++) {
+      method_dict["MethodName"] = name_and_output_module_class_pair->first;
+      method_dict["OutputTypeModuleAndClass"] =
+          name_and_output_module_class_pair->second;
       IndentScope raii_indent(out);
-      out->Print(
-          "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
-          "$OutputTypeModuleAndClass$.SerializeToString,\n",
-          "PackageQualifiedServiceName", package_qualified_service_name,
-          "MethodName", name_and_output_module_class_pair->first,
-          "OutputTypeModuleAndClass",
-          name_and_output_module_class_pair->second);
+      out->Print(method_dict,
+                 "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
+                 "$OutputTypeModuleAndClass$.SerializeToString,\n");
     }
     out->Print("}\n");
     out->Print("method_implementations = {\n");
@@ -373,15 +283,14 @@ bool PrivateGenerator::PrintBetaServerFactory(
          name_and_implementation_constructor !=
          method_implementation_constructors.end();
          name_and_implementation_constructor++) {
+      method_dict["Method"] = name_and_implementation_constructor->first;
+      method_dict["Constructor"] = name_and_implementation_constructor->second;
       IndentScope raii_descriptions_indent(out);
       const grpc::string method_name =
           name_and_implementation_constructor->first;
-      out->Print(
-          "(\'$PackageQualifiedServiceName$\', \'$Method$\'): "
-          "face_utilities.$Constructor$(servicer.$Method$),\n",
-          "PackageQualifiedServiceName", package_qualified_service_name,
-          "Method", name_and_implementation_constructor->first, "Constructor",
-          name_and_implementation_constructor->second);
+      out->Print(method_dict,
+                 "(\'$PackageQualifiedServiceName$\', \'$Method$\'): "
+                 "face_utilities.$Constructor$(servicer.$Method$),\n");
     }
     out->Print("}\n");
     out->Print(
@@ -400,7 +309,7 @@ bool PrivateGenerator::PrintBetaServerFactory(
 
 bool PrivateGenerator::PrintBetaStubFactory(
     const grpc::string& package_qualified_service_name,
-    const ServiceDescriptor* service) {
+    const grpc_generator::Service* service, grpc_generator::Printer* out) {
   StringMap dict;
   dict["Service"] = service->name();
   out->Print("\n\n");
@@ -419,18 +328,20 @@ bool PrivateGenerator::PrintBetaStubFactory(
     StringMap input_message_modules_and_classes;
     StringMap output_message_modules_and_classes;
     for (int i = 0; i < service->method_count(); ++i) {
-      const MethodDescriptor* method = service->method(i);
+      auto method = service->method(i);
       const grpc::string method_cardinality =
-          grpc::string(method->client_streaming() ? "STREAM" : "UNARY") + "_" +
-          grpc::string(method->server_streaming() ? "STREAM" : "UNARY");
+          grpc::string(method->ClientStreaming() ? "STREAM" : "UNARY") + "_" +
+          grpc::string(method->ServerStreaming() ? "STREAM" : "UNARY");
       grpc::string input_message_module_and_class;
-      if (!GetModuleAndMessagePath(method->input_type(),
-                                   &input_message_module_and_class)) {
+      if (!method->get_module_and_message_path_input(
+              &input_message_module_and_class, generator_file_name,
+              generate_in_pb2_grpc, config.import_prefix)) {
         return false;
       }
       grpc::string output_message_module_and_class;
-      if (!GetModuleAndMessagePath(method->output_type(),
-                                   &output_message_module_and_class)) {
+      if (!method->get_module_and_message_path_output(
+              &output_message_module_and_class, generator_file_name,
+              generate_in_pb2_grpc, config.import_prefix)) {
         return false;
       }
       method_cardinalities.insert(
@@ -440,19 +351,21 @@ bool PrivateGenerator::PrintBetaStubFactory(
       output_message_modules_and_classes.insert(
           make_pair(method->name(), output_message_module_and_class));
     }
+    StringMap method_dict;
+    method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
     out->Print("request_serializers = {\n");
     for (StringMap::iterator name_and_input_module_class_pair =
              input_message_modules_and_classes.begin();
          name_and_input_module_class_pair !=
          input_message_modules_and_classes.end();
          name_and_input_module_class_pair++) {
+      method_dict["MethodName"] = name_and_input_module_class_pair->first;
+      method_dict["InputTypeModuleAndClass"] =
+          name_and_input_module_class_pair->second;
       IndentScope raii_indent(out);
-      out->Print(
-          "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
-          "$InputTypeModuleAndClass$.SerializeToString,\n",
-          "PackageQualifiedServiceName", package_qualified_service_name,
-          "MethodName", name_and_input_module_class_pair->first,
-          "InputTypeModuleAndClass", name_and_input_module_class_pair->second);
+      out->Print(method_dict,
+                 "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
+                 "$InputTypeModuleAndClass$.SerializeToString,\n");
     }
     out->Print("}\n");
     out->Print("response_deserializers = {\n");
@@ -461,14 +374,13 @@ bool PrivateGenerator::PrintBetaStubFactory(
          name_and_output_module_class_pair !=
          output_message_modules_and_classes.end();
          name_and_output_module_class_pair++) {
+      method_dict["MethodName"] = name_and_output_module_class_pair->first;
+      method_dict["OutputTypeModuleAndClass"] =
+          name_and_output_module_class_pair->second;
       IndentScope raii_indent(out);
-      out->Print(
-          "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
-          "$OutputTypeModuleAndClass$.FromString,\n",
-          "PackageQualifiedServiceName", package_qualified_service_name,
-          "MethodName", name_and_output_module_class_pair->first,
-          "OutputTypeModuleAndClass",
-          name_and_output_module_class_pair->second);
+      out->Print(method_dict,
+                 "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
+                 "$OutputTypeModuleAndClass$.FromString,\n");
     }
     out->Print("}\n");
     out->Print("cardinalities = {\n");
@@ -476,10 +388,11 @@ bool PrivateGenerator::PrintBetaStubFactory(
              method_cardinalities.begin();
          name_and_cardinality != method_cardinalities.end();
          name_and_cardinality++) {
+      method_dict["Method"] = name_and_cardinality->first;
+      method_dict["Cardinality"] = name_and_cardinality->second;
       IndentScope raii_descriptions_indent(out);
-      out->Print("\'$Method$\': cardinality.Cardinality.$Cardinality$,\n",
-                 "Method", name_and_cardinality->first, "Cardinality",
-                 name_and_cardinality->second);
+      out->Print(method_dict,
+                 "\'$Method$\': cardinality.Cardinality.$Cardinality$,\n");
     }
     out->Print("}\n");
     out->Print(
@@ -488,23 +401,25 @@ bool PrivateGenerator::PrintBetaStubFactory(
         "request_serializers=request_serializers, "
         "response_deserializers=response_deserializers, "
         "thread_pool=pool, thread_pool_size=pool_size)\n");
-    out->Print(
-        "return beta_implementations.dynamic_stub(channel, "
-        "\'$PackageQualifiedServiceName$\', "
-        "cardinalities, options=stub_options)\n",
-        "PackageQualifiedServiceName", package_qualified_service_name);
+    out->Print(method_dict,
+               "return beta_implementations.dynamic_stub(channel, "
+               "\'$PackageQualifiedServiceName$\', "
+               "cardinalities, options=stub_options)\n");
   }
   return true;
 }
 
 bool PrivateGenerator::PrintStub(
     const grpc::string& package_qualified_service_name,
-    const ServiceDescriptor* service) {
+    const grpc_generator::Service* service, grpc_generator::Printer* out) {
+  StringMap dict;
+  dict["Service"] = service->name();
   out->Print("\n\n");
-  out->Print("class $Service$Stub(object):\n", "Service", service->name());
+  out->Print(dict, "class $Service$Stub(object):\n");
   {
     IndentScope raii_class_indent(out);
-    PrintAllComments(service);
+    StringVector service_comments = service->GetAllComments();
+    PrintAllComments(service_comments, out);
     out->Print("\n");
     out->Print("def __init__(self, channel):\n");
     {
@@ -518,35 +433,41 @@ bool PrivateGenerator::PrintStub(
       }
       out->Print("\"\"\"\n");
       for (int i = 0; i < service->method_count(); ++i) {
-        const MethodDescriptor* method = service->method(i);
+        auto method = service->method(i);
         grpc::string multi_callable_constructor =
-            grpc::string(method->client_streaming() ? "stream" : "unary") +
-            "_" + grpc::string(method->server_streaming() ? "stream" : "unary");
+            grpc::string(method->ClientStreaming() ? "stream" : "unary") + "_" +
+            grpc::string(method->ServerStreaming() ? "stream" : "unary");
         grpc::string request_module_and_class;
-        if (!GetModuleAndMessagePath(method->input_type(),
-                                     &request_module_and_class)) {
+        if (!method->get_module_and_message_path_input(
+                &request_module_and_class, generator_file_name,
+                generate_in_pb2_grpc, config.import_prefix)) {
           return false;
         }
         grpc::string response_module_and_class;
-        if (!GetModuleAndMessagePath(method->output_type(),
-                                     &response_module_and_class)) {
+        if (!method->get_module_and_message_path_output(
+                &response_module_and_class, generator_file_name,
+                generate_in_pb2_grpc, config.import_prefix)) {
           return false;
         }
-        out->Print("self.$Method$ = channel.$MultiCallableConstructor$(\n",
-                   "Method", method->name(), "MultiCallableConstructor",
-                   multi_callable_constructor);
+        StringMap method_dict;
+        method_dict["Method"] = method->name();
+        method_dict["MultiCallableConstructor"] = multi_callable_constructor;
+        out->Print(method_dict,
+                   "self.$Method$ = channel.$MultiCallableConstructor$(\n");
         {
+          method_dict["PackageQualifiedService"] =
+              package_qualified_service_name;
+          method_dict["RequestModuleAndClass"] = request_module_and_class;
+          method_dict["ResponseModuleAndClass"] = response_module_and_class;
           IndentScope raii_first_attribute_indent(out);
           IndentScope raii_second_attribute_indent(out);
-          out->Print("'/$PackageQualifiedService$/$Method$',\n",
-                     "PackageQualifiedService", package_qualified_service_name,
-                     "Method", method->name());
-          out->Print(
-              "request_serializer=$RequestModuleAndClass$.SerializeToString,\n",
-              "RequestModuleAndClass", request_module_and_class);
+          out->Print(method_dict, "'/$PackageQualifiedService$/$Method$',\n");
+          out->Print(method_dict,
+                     "request_serializer=$RequestModuleAndClass$."
+                     "SerializeToString,\n");
           out->Print(
-              "response_deserializer=$ResponseModuleAndClass$.FromString,\n",
-              "ResponseModuleAndClass", response_module_and_class);
+              method_dict,
+              "response_deserializer=$ResponseModuleAndClass$.FromString,\n");
           out->Print(")\n");
         }
       }
@@ -555,22 +476,29 @@ bool PrivateGenerator::PrintStub(
   return true;
 }
 
-bool PrivateGenerator::PrintServicer(const ServiceDescriptor* service) {
+bool PrivateGenerator::PrintServicer(const grpc_generator::Service* service,
+                                     grpc_generator::Printer* out) {
+  StringMap service_dict;
+  service_dict["Service"] = service->name();
   out->Print("\n\n");
-  out->Print("class $Service$Servicer(object):\n", "Service", service->name());
+  out->Print(service_dict, "class $Service$Servicer(object):\n");
   {
     IndentScope raii_class_indent(out);
-    PrintAllComments(service);
+    StringVector service_comments = service->GetAllComments();
+    PrintAllComments(service_comments, out);
     for (int i = 0; i < service->method_count(); ++i) {
-      const MethodDescriptor* method = service->method(i);
+      auto method = service->method(i);
       grpc::string arg_name =
-          method->client_streaming() ? "request_iterator" : "request";
+          method->ClientStreaming() ? "request_iterator" : "request";
+      StringMap method_dict;
+      method_dict["Method"] = method->name();
+      method_dict["ArgName"] = arg_name;
       out->Print("\n");
-      out->Print("def $Method$(self, $ArgName$, context):\n", "Method",
-                 method->name(), "ArgName", arg_name);
+      out->Print(method_dict, "def $Method$(self, $ArgName$, context):\n");
       {
         IndentScope raii_method_indent(out);
-        PrintAllComments(method);
+        StringVector method_comments = method->GetAllComments();
+        PrintAllComments(method_comments, out);
         out->Print("context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n");
         out->Print("context.set_details('Method not implemented!')\n");
         out->Print("raise NotImplementedError('Method not implemented!')\n");
@@ -582,10 +510,12 @@ bool PrivateGenerator::PrintServicer(const ServiceDescriptor* service) {
 
 bool PrivateGenerator::PrintAddServicerToServer(
     const grpc::string& package_qualified_service_name,
-    const ServiceDescriptor* service) {
+    const grpc_generator::Service* service, grpc_generator::Printer* out) {
+  StringMap service_dict;
+  service_dict["Service"] = service->name();
   out->Print("\n\n");
-  out->Print("def add_$Service$Servicer_to_server(servicer, server):\n",
-             "Service", service->name());
+  out->Print(service_dict,
+             "def add_$Service$Servicer_to_server(servicer, server):\n");
   {
     IndentScope raii_class_indent(out);
     out->Print("rpc_method_handlers = {\n");
@@ -593,122 +523,153 @@ bool PrivateGenerator::PrintAddServicerToServer(
       IndentScope raii_dict_first_indent(out);
       IndentScope raii_dict_second_indent(out);
       for (int i = 0; i < service->method_count(); ++i) {
-        const MethodDescriptor* method = service->method(i);
+        auto method = service->method(i);
         grpc::string method_handler_constructor =
-            grpc::string(method->client_streaming() ? "stream" : "unary") +
-            "_" +
-            grpc::string(method->server_streaming() ? "stream" : "unary") +
+            grpc::string(method->ClientStreaming() ? "stream" : "unary") + "_" +
+            grpc::string(method->ServerStreaming() ? "stream" : "unary") +
             "_rpc_method_handler";
         grpc::string request_module_and_class;
-        if (!GetModuleAndMessagePath(method->input_type(),
-                                     &request_module_and_class)) {
+        if (!method->get_module_and_message_path_input(
+                &request_module_and_class, generator_file_name,
+                generate_in_pb2_grpc, config.import_prefix)) {
           return false;
         }
         grpc::string response_module_and_class;
-        if (!GetModuleAndMessagePath(method->output_type(),
-                                     &response_module_and_class)) {
+        if (!method->get_module_and_message_path_output(
+                &response_module_and_class, generator_file_name,
+                generate_in_pb2_grpc, config.import_prefix)) {
           return false;
         }
-        out->Print("'$Method$': grpc.$MethodHandlerConstructor$(\n", "Method",
-                   method->name(), "MethodHandlerConstructor",
-                   method_handler_constructor);
+        StringMap method_dict;
+        method_dict["Method"] = method->name();
+        method_dict["MethodHandlerConstructor"] = method_handler_constructor;
+        method_dict["RequestModuleAndClass"] = request_module_and_class;
+        method_dict["ResponseModuleAndClass"] = response_module_and_class;
+        out->Print(method_dict,
+                   "'$Method$': grpc.$MethodHandlerConstructor$(\n");
         {
           IndentScope raii_call_first_indent(out);
           IndentScope raii_call_second_indent(out);
-          out->Print("servicer.$Method$,\n", "Method", method->name());
+          out->Print(method_dict, "servicer.$Method$,\n");
           out->Print(
-              "request_deserializer=$RequestModuleAndClass$.FromString,\n",
-              "RequestModuleAndClass", request_module_and_class);
+              method_dict,
+              "request_deserializer=$RequestModuleAndClass$.FromString,\n");
           out->Print(
+              method_dict,
               "response_serializer=$ResponseModuleAndClass$.SerializeToString,"
-              "\n",
-              "ResponseModuleAndClass", response_module_and_class);
+              "\n");
         }
         out->Print("),\n");
       }
     }
+    StringMap method_dict;
+    method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
     out->Print("}\n");
     out->Print("generic_handler = grpc.method_handlers_generic_handler(\n");
     {
       IndentScope raii_call_first_indent(out);
       IndentScope raii_call_second_indent(out);
-      out->Print("'$PackageQualifiedServiceName$', rpc_method_handlers)\n",
-                 "PackageQualifiedServiceName", package_qualified_service_name);
+      out->Print(method_dict,
+                 "'$PackageQualifiedServiceName$', rpc_method_handlers)\n");
     }
     out->Print("server.add_generic_rpc_handlers((generic_handler,))\n");
   }
   return true;
 }
 
-bool PrivateGenerator::PrintBetaPreamble() {
-  out->Print("from $Package$ import implementations as beta_implementations\n",
-             "Package", config.beta_package_root);
-  out->Print("from $Package$ import interfaces as beta_interfaces\n", "Package",
-             config.beta_package_root);
-  return true;
-}
-
-bool PrivateGenerator::PrintPreamble() {
-  out->Print("import $Package$\n", "Package", config.grpc_package_root);
+bool PrivateGenerator::PrintBetaPreamble(grpc_generator::Printer* out) {
+  StringMap var;
+  var["Package"] = config.beta_package_root;
+  out->Print(var,
+             "from $Package$ import implementations as beta_implementations\n");
+  out->Print(var, "from $Package$ import interfaces as beta_interfaces\n");
   out->Print("from grpc.framework.common import cardinality\n");
   out->Print(
       "from grpc.framework.interfaces.face import utilities as "
       "face_utilities\n");
+  return true;
+}
+
+bool PrivateGenerator::PrintPreamble(grpc_generator::Printer* out) {
+  StringMap var;
+  var["Package"] = config.grpc_package_root;
+  out->Print(var, "import $Package$\n");
   if (generate_in_pb2_grpc) {
     out->Print("\n");
     StringPairSet imports_set;
     for (int i = 0; i < file->service_count(); ++i) {
-      const ServiceDescriptor* service = file->service(i);
+      auto service = file->service(i);
       for (int j = 0; j < service->method_count(); ++j) {
-        const MethodDescriptor* method = service->method(j);
-        const Descriptor* types[2] = {method->input_type(),
-                                      method->output_type()};
-        for (int k = 0; k < 2; ++k) {
-          const Descriptor* type = types[k];
-          grpc::string type_file_name = type->file()->name();
-          grpc::string module_name = ModuleName(type_file_name);
-          grpc::string module_alias = ModuleAlias(type_file_name);
-          imports_set.insert(std::make_tuple(module_name, module_alias));
-        }
+        auto method = service.get()->method(j);
+
+        grpc::string input_type_file_name = method->get_input_type_name();
+        grpc::string input_module_name =
+            ModuleName(input_type_file_name, config.import_prefix);
+        grpc::string input_module_alias =
+            ModuleAlias(input_type_file_name, config.import_prefix);
+        imports_set.insert(
+            std::make_tuple(input_module_name, input_module_alias));
+
+        grpc::string output_type_file_name = method->get_output_type_name();
+        grpc::string output_module_name =
+            ModuleName(output_type_file_name, config.import_prefix);
+        grpc::string output_module_alias =
+            ModuleAlias(output_type_file_name, config.import_prefix);
+        imports_set.insert(
+            std::make_tuple(output_module_name, output_module_alias));
       }
     }
+
     for (StringPairSet::iterator it = imports_set.begin();
          it != imports_set.end(); ++it) {
-      out->Print("import $ModuleName$ as $ModuleAlias$\n", "ModuleName",
-                 std::get<0>(*it), "ModuleAlias", std::get<1>(*it));
+      auto module_name = std::get<0>(*it);
+      var["ModuleAlias"] = std::get<1>(*it);
+      const size_t last_dot_pos = module_name.rfind('.');
+      if (last_dot_pos == grpc::string::npos) {
+        var["ImportStatement"] = "import " + module_name;
+      } else {
+        var["ImportStatement"] = "from " + module_name.substr(0, last_dot_pos) +
+                                 " import " +
+                                 module_name.substr(last_dot_pos + 1);
+      }
+      out->Print(var, "$ImportStatement$ as $ModuleAlias$\n");
     }
   }
   return true;
 }
 
-bool PrivateGenerator::PrintGAServices() {
+bool PrivateGenerator::PrintGAServices(grpc_generator::Printer* out) {
   grpc::string package = file->package();
   if (!package.empty()) {
     package = package.append(".");
   }
   for (int i = 0; i < file->service_count(); ++i) {
-    const ServiceDescriptor* service = file->service(i);
+    auto service = file->service(i);
     grpc::string package_qualified_service_name = package + service->name();
-    if (!(PrintStub(package_qualified_service_name, service) &&
-          PrintServicer(service) &&
-          PrintAddServicerToServer(package_qualified_service_name, service))) {
+    if (!(PrintStub(package_qualified_service_name, service.get(), out) &&
+          PrintServicer(service.get(), out) &&
+          PrintAddServicerToServer(package_qualified_service_name,
+                                   service.get(), out))) {
       return false;
     }
   }
   return true;
 }
 
-bool PrivateGenerator::PrintBetaServices() {
+bool PrivateGenerator::PrintBetaServices(grpc_generator::Printer* out) {
   grpc::string package = file->package();
   if (!package.empty()) {
     package = package.append(".");
   }
   for (int i = 0; i < file->service_count(); ++i) {
-    const ServiceDescriptor* service = file->service(i);
+    auto service = file->service(i);
     grpc::string package_qualified_service_name = package + service->name();
-    if (!(PrintBetaServicer(service) && PrintBetaStub(service) &&
-          PrintBetaServerFactory(package_qualified_service_name, service) &&
-          PrintBetaStubFactory(package_qualified_service_name, service))) {
+    if (!(PrintBetaServicer(service.get(), out) &&
+          PrintBetaStub(service.get(), out) &&
+          PrintBetaServerFactory(package_qualified_service_name, service.get(),
+                                 out) &&
+          PrintBetaStubFactory(package_qualified_service_name, service.get(),
+                               out))) {
       return false;
     }
   }
@@ -719,43 +680,40 @@ pair<bool, grpc::string> PrivateGenerator::GetGrpcServices() {
   grpc::string output;
   {
     // Scope the output stream so it closes and finalizes output to the string.
-    StringOutputStream output_stream(&output);
-    Printer out_printer(&output_stream, '$');
-    out = &out_printer;
-
+    auto out = file->CreatePrinter(&output);
     if (generate_in_pb2_grpc) {
       out->Print(
           "# Generated by the gRPC Python protocol compiler plugin. "
           "DO NOT EDIT!\n");
-      if (!PrintPreamble()) {
+      if (!PrintPreamble(out.get())) {
         return make_pair(false, "");
       }
-      if (!PrintGAServices()) {
+      if (!PrintGAServices(out.get())) {
         return make_pair(false, "");
       }
     } else {
       out->Print("try:\n");
       {
-        IndentScope raii_dict_try_indent(out);
+        IndentScope raii_dict_try_indent(out.get());
         out->Print(
             "# THESE ELEMENTS WILL BE DEPRECATED.\n"
             "# Please use the generated *_pb2_grpc.py files instead.\n");
-        if (!PrintPreamble()) {
+        if (!PrintPreamble(out.get())) {
           return make_pair(false, "");
         }
-        if (!PrintBetaPreamble()) {
+        if (!PrintBetaPreamble(out.get())) {
           return make_pair(false, "");
         }
-        if (!PrintGAServices()) {
+        if (!PrintGAServices(out.get())) {
           return make_pair(false, "");
         }
-        if (!PrintBetaServices()) {
+        if (!PrintBetaServices(out.get())) {
           return make_pair(false, "");
         }
       }
       out->Print("except ImportError:\n");
       {
-        IndentScope raii_dict_except_indent(out);
+        IndentScope raii_dict_except_indent(out.get());
         out->Print("pass");
       }
     }
@@ -766,7 +724,9 @@ pair<bool, grpc::string> PrivateGenerator::GetGrpcServices() {
 }  // namespace
 
 GeneratorConfiguration::GeneratorConfiguration()
-    : grpc_package_root("grpc"), beta_package_root("grpc.beta") {}
+    : grpc_package_root("grpc"),
+      beta_package_root("grpc.beta"),
+      import_prefix("") {}
 
 PythonGrpcGenerator::PythonGrpcGenerator(const GeneratorConfiguration& config)
     : config_(config) {}
@@ -817,8 +777,10 @@ bool PythonGrpcGenerator::Generate(const FileDescriptor* file,
     *error = "Invalid proto file name. Proto file must end with .proto";
     return false;
   }
+  generator_file_name = file->name();
 
-  PrivateGenerator generator(config_, file);
+  ProtoBufFile pbfile(file);
+  PrivateGenerator generator(config_, &pbfile);
   if (parameter == "grpc_2_0") {
     return GenerateGrpc(context, generator, pb2_grpc_file_name, true);
   } else if (parameter == "") {
diff --git a/src/compiler/python_generator.h b/src/compiler/python_generator.h
index 6a95255d40e4a088d8c60a1b2a70cfda904f3a13..0c0d7449b568ef26d3b9feb2c17b3e0b52cd1394 100644
--- a/src/compiler/python_generator.h
+++ b/src/compiler/python_generator.h
@@ -37,6 +37,7 @@
 #include <utility>
 
 #include "src/compiler/config.h"
+#include "src/compiler/schema_interface.h"
 
 namespace grpc_python_generator {
 
@@ -45,7 +46,10 @@ namespace grpc_python_generator {
 struct GeneratorConfiguration {
   GeneratorConfiguration();
   grpc::string grpc_package_root;
+  // TODO(https://github.com/grpc/grpc/issues/8622): Drop this.
   grpc::string beta_package_root;
+  // TODO(https://github.com/google/protobuf/issues/888): Drop this.
+  grpc::string import_prefix;
 };
 
 class PythonGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
diff --git a/src/compiler/python_generator_helpers.h b/src/compiler/python_generator_helpers.h
new file mode 100644
index 0000000000000000000000000000000000000000..9fca711c183b45e05d2801c887459e490be794cb
--- /dev/null
+++ b/src/compiler/python_generator_helpers.h
@@ -0,0 +1,142 @@
+/*
+ *
+ * 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_COMPILER_PYTHON_GENERATOR_HELPERS_H
+#define GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_HELPERS_H
+
+#include <cstring>
+#include <fstream>
+#include <iostream>
+#include <vector>
+
+#include "src/compiler/config.h"
+#include "src/compiler/generator_helpers.h"
+#include "src/compiler/python_generator.h"
+#include "src/compiler/python_private_generator.h"
+
+using std::vector;
+using grpc_generator::StringReplace;
+using grpc_generator::StripProto;
+using grpc::protobuf::Descriptor;
+using grpc::protobuf::FileDescriptor;
+using grpc::protobuf::MethodDescriptor;
+using grpc::protobuf::ServiceDescriptor;
+using grpc::protobuf::compiler::GeneratorContext;
+using grpc::protobuf::io::CodedOutputStream;
+using grpc::protobuf::io::Printer;
+using grpc::protobuf::io::StringOutputStream;
+using grpc::protobuf::io::ZeroCopyOutputStream;
+
+namespace grpc_python_generator {
+
+namespace {
+
+typedef vector<const Descriptor*> DescriptorVector;
+typedef vector<grpc::string> StringVector;
+
+// TODO(https://github.com/google/protobuf/issues/888):
+// Export `ModuleName` from protobuf's
+// `src/google/protobuf/compiler/python/python_generator.cc` file.
+grpc::string ModuleName(const grpc::string& filename,
+                        const grpc::string& import_prefix) {
+  grpc::string basename = StripProto(filename);
+  basename = StringReplace(basename, "-", "_");
+  basename = StringReplace(basename, "/", ".");
+  return import_prefix + basename + "_pb2";
+}
+
+// TODO(https://github.com/google/protobuf/issues/888):
+// Export `ModuleAlias` from protobuf's
+// `src/google/protobuf/compiler/python/python_generator.cc` file.
+grpc::string ModuleAlias(const grpc::string& filename,
+                         const grpc::string& import_prefix) {
+  grpc::string module_name = ModuleName(filename, import_prefix);
+  // We can't have dots in the module name, so we replace each with _dot_.
+  // But that could lead to a collision between a.b and a_dot_b, so we also
+  // duplicate each underscore.
+  module_name = StringReplace(module_name, "_", "__");
+  module_name = StringReplace(module_name, ".", "_dot_");
+  return module_name;
+}
+
+bool GetModuleAndMessagePath(const Descriptor* type, grpc::string* out,
+                             grpc::string generator_file_name,
+                             bool generate_in_pb2_grpc,
+                             grpc::string& import_prefix) {
+  const Descriptor* path_elem_type = type;
+  DescriptorVector message_path;
+  do {
+    message_path.push_back(path_elem_type);
+    path_elem_type = path_elem_type->containing_type();
+  } while (path_elem_type);  // implicit nullptr comparison; don't be explicit
+  grpc::string file_name = type->file()->name();
+  static const int proto_suffix_length = strlen(".proto");
+  if (!(file_name.size() > static_cast<size_t>(proto_suffix_length) &&
+        file_name.find_last_of(".proto") == file_name.size() - 1)) {
+    return false;
+  }
+
+  grpc::string module;
+  if (generator_file_name != file_name || generate_in_pb2_grpc) {
+    module = ModuleAlias(file_name, import_prefix) + ".";
+  } else {
+    module = "";
+  }
+  grpc::string message_type;
+  for (DescriptorVector::reverse_iterator path_iter = message_path.rbegin();
+       path_iter != message_path.rend(); ++path_iter) {
+    message_type += (*path_iter)->name() + ".";
+  }
+  // no pop_back prior to C++11
+  message_type.resize(message_type.size() - 1);
+  *out = module + message_type;
+  return true;
+}
+
+template <typename DescriptorType>
+StringVector get_all_comments(const DescriptorType* descriptor) {
+  StringVector comments;
+  grpc_generator::GetComment(
+      descriptor, grpc_generator::COMMENTTYPE_LEADING_DETACHED, &comments);
+  grpc_generator::GetComment(descriptor, grpc_generator::COMMENTTYPE_LEADING,
+                             &comments);
+  grpc_generator::GetComment(descriptor, grpc_generator::COMMENTTYPE_TRAILING,
+                             &comments);
+  return comments;
+}
+
+}  // namespace
+
+}  // namespace grpc_python_generator
+
+#endif  // GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_HELPERS_H
diff --git a/src/compiler/python_plugin.cc b/src/compiler/python_plugin.cc
index 3457aa631a36bb11547ece7c50f3524bfc008300..f34abcc3139ab13dbeef9ec717196521f73c9844 100644
--- a/src/compiler/python_plugin.cc
+++ b/src/compiler/python_plugin.cc
@@ -34,6 +34,7 @@
 // Generates a Python gRPC service interface out of Protobuf IDL.
 
 #include "src/compiler/config.h"
+#include "src/compiler/protobuf_plugin.h"
 #include "src/compiler/python_generator.h"
 
 int main(int argc, char* argv[]) {
diff --git a/src/compiler/python_private_generator.h b/src/compiler/python_private_generator.h
new file mode 100644
index 0000000000000000000000000000000000000000..d20ff51b204142eb62e550e9e3e5d7e7b210ff5b
--- /dev/null
+++ b/src/compiler/python_private_generator.h
@@ -0,0 +1,99 @@
+/*
+ *
+ * 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_COMPILER_PYTHON_PRIVATE_GENERATOR_H
+#define GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
+
+#include <iostream>
+#include <vector>
+
+#include "src/compiler/python_generator.h"
+#include "src/compiler/schema_interface.h"
+
+namespace grpc_python_generator {
+
+namespace {
+
+// Tucks all generator state in an anonymous namespace away from
+// PythonGrpcGenerator and the header file, mostly to encourage future changes
+// to not require updates to the grpcio-tools C++ code part. Assumes that it is
+// only ever used from a single thread.
+struct PrivateGenerator {
+  const GeneratorConfiguration& config;
+  const grpc_generator::File* file;
+
+  bool generate_in_pb2_grpc;
+
+  PrivateGenerator(const GeneratorConfiguration& config,
+                   const grpc_generator::File* file);
+
+  std::pair<bool, grpc::string> GetGrpcServices();
+
+ private:
+  bool PrintPreamble(grpc_generator::Printer* out);
+  bool PrintBetaPreamble(grpc_generator::Printer* out);
+  bool PrintGAServices(grpc_generator::Printer* out);
+  bool PrintBetaServices(grpc_generator::Printer* out);
+
+  bool PrintAddServicerToServer(
+      const grpc::string& package_qualified_service_name,
+      const grpc_generator::Service* service, grpc_generator::Printer* out);
+  bool PrintServicer(const grpc_generator::Service* service,
+                     grpc_generator::Printer* out);
+  bool PrintStub(const grpc::string& package_qualified_service_name,
+                 const grpc_generator::Service* service,
+                 grpc_generator::Printer* out);
+
+  bool PrintBetaServicer(const grpc_generator::Service* service,
+                         grpc_generator::Printer* out);
+  bool PrintBetaServerFactory(
+      const grpc::string& package_qualified_service_name,
+      const grpc_generator::Service* service, grpc_generator::Printer* out);
+  bool PrintBetaStub(const grpc_generator::Service* service,
+                     grpc_generator::Printer* out);
+  bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
+                            const grpc_generator::Service* service,
+                            grpc_generator::Printer* out);
+
+  // Get all comments (leading, leading_detached, trailing) and print them as a
+  // docstring. Any leading space of a line will be removed, but the line
+  // wrapping will not be changed.
+  void PrintAllComments(std::vector<grpc::string> comments,
+                        grpc_generator::Printer* out);
+};
+
+}  // namespace
+
+}  // namespace grpc_python_generator
+
+#endif  // GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
diff --git a/src/compiler/schema_interface.h b/src/compiler/schema_interface.h
new file mode 100644
index 0000000000000000000000000000000000000000..25bbdb5142061c028adfe72e9eb331e567f74f3f
--- /dev/null
+++ b/src/compiler/schema_interface.h
@@ -0,0 +1,126 @@
+/*
+ *
+ * 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_COMPILER_SCHEMA_INTERFACE_H
+#define GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
+
+#include "src/compiler/config.h"
+
+#include <memory>
+#include <vector>
+
+#ifndef GRPC_CUSTOM_STRING
+#include <string>
+#define GRPC_CUSTOM_STRING std::string
+#endif
+
+namespace grpc {
+
+typedef GRPC_CUSTOM_STRING string;
+
+}  // namespace grpc
+
+namespace grpc_generator {
+
+// A common interface for objects having comments in the source.
+// Return formatted comments to be inserted in generated code.
+struct CommentHolder {
+  virtual ~CommentHolder() {}
+  virtual grpc::string GetLeadingComments(const grpc::string prefix) const = 0;
+  virtual grpc::string GetTrailingComments(const grpc::string prefix) const = 0;
+  virtual std::vector<grpc::string> GetAllComments() const = 0;
+};
+
+// An abstract interface representing a method.
+struct Method : public CommentHolder {
+  virtual ~Method() {}
+
+  virtual grpc::string name() const = 0;
+
+  virtual grpc::string input_type_name() const = 0;
+  virtual grpc::string output_type_name() const = 0;
+
+  virtual bool get_module_and_message_path_input(
+      grpc::string *str, grpc::string generator_file_name,
+      bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0;
+  virtual bool get_module_and_message_path_output(
+      grpc::string *str, grpc::string generator_file_name,
+      bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0;
+
+  virtual grpc::string get_input_type_name() const = 0;
+  virtual grpc::string get_output_type_name() const = 0;
+  virtual bool NoStreaming() const = 0;
+  virtual bool ClientStreaming() const = 0;
+  virtual bool ServerStreaming() const = 0;
+  virtual bool BidiStreaming() const = 0;
+};
+
+// An abstract interface representing a service.
+struct Service : public CommentHolder {
+  virtual ~Service() {}
+
+  virtual grpc::string name() const = 0;
+
+  virtual int method_count() const = 0;
+  virtual std::unique_ptr<const Method> method(int i) const = 0;
+};
+
+struct Printer {
+  virtual ~Printer() {}
+
+  virtual void Print(const std::map<grpc::string, grpc::string> &vars,
+                     const char *template_string) = 0;
+  virtual void Print(const char *string) = 0;
+  virtual void Indent() = 0;
+  virtual void Outdent() = 0;
+};
+
+// An interface that allows the source generated to be output using various
+// libraries/idls/serializers.
+struct File : public CommentHolder {
+  virtual ~File() {}
+
+  virtual grpc::string filename() const = 0;
+  virtual grpc::string filename_without_ext() const = 0;
+  virtual grpc::string package() const = 0;
+  virtual std::vector<grpc::string> package_parts() const = 0;
+  virtual grpc::string additional_headers() const = 0;
+
+  virtual int service_count() const = 0;
+  virtual std::unique_ptr<const Service> service(int i) const = 0;
+
+  virtual std::unique_ptr<Printer> CreatePrinter(grpc::string *str) const = 0;
+};
+}  // namespace grpc_generator
+
+#endif  // GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
diff --git a/src/core/README.md b/src/core/README.md
index 44c6f247725896b9667c02befcb22e2b4ef34308..130d2652b3990b5cc492b0ff9ad49c4172a6baf0 100644
--- a/src/core/README.md
+++ b/src/core/README.md
@@ -1,4 +1,4 @@
-#Overview
+# Overview
 
 This directory contains source code for C library (a.k.a the *gRPC C core*) that provides all gRPC's core functionality through a low level API. Libraries in other languages in this repository (C++, Ruby,
 Python, PHP, NodeJS, Objective-C) are layered on top of this library.
diff --git a/src/core/ext/census/context.c b/src/core/ext/census/context.c
index 0dfc4ecbf1da6e31c0086dfc86fdb3d70d826fd1..4195cb1c9b3cdf1df6ec8efd9d550823eae0bd04 100644
--- a/src/core/ext/census/context.c
+++ b/src/core/ext/census/context.c
@@ -200,7 +200,7 @@ static bool tag_set_add_tag(struct tag_set *tags, const census_tag *tag,
     // allocate new memory if needed
     tags->kvm_size += 2 * CENSUS_MAX_TAG_KV_LEN + TAG_HEADER_SIZE;
     char *new_kvm = gpr_malloc(tags->kvm_size);
-    memcpy(new_kvm, tags->kvm, tags->kvm_used);
+    if (tags->kvm_used > 0) memcpy(new_kvm, tags->kvm, tags->kvm_used);
     gpr_free(tags->kvm);
     tags->kvm = new_kvm;
   }
diff --git a/src/core/ext/census/gen/README.md b/src/core/ext/census/gen/README.md
index fdbac1084cd4a234689fc9c875805c8dc5bb6d8c..d4612bc7c85172c8c5f0062930da5be8dc705ae6 100644
--- a/src/core/ext/census/gen/README.md
+++ b/src/core/ext/census/gen/README.md
@@ -1,6 +1,6 @@
 Files generated for use by Census stats and trace recording subsystem.
 
-#Files
+# Files
 * census.pb.{h,c} - Generated from src/core/ext/census/census.proto, using the
   script `tools/codegen/core/gen_nano_proto.sh src/proto/census/census.proto
   $PWD/src/core/ext/census/gen src/core/ext/census/gen`
diff --git a/src/core/ext/census/gen/trace_context.pb.h b/src/core/ext/census/gen/trace_context.pb.h
index ea127bf70a79ae21ab46cd4c7937f9de5c5dca9f..6fafc04c813d7c34fb0e68e4f7f4e24ecdb052e4 100644
--- a/src/core/ext/census/gen/trace_context.pb.h
+++ b/src/core/ext/census/gen/trace_context.pb.h
@@ -90,4 +90,4 @@ extern const pb_field_t google_trace_TraceContext_fields[5];
 #endif
 /* @@protoc_insertion_point(eof) */
 
-#endif
+#endif /* GRPC_CORE_EXT_CENSUS_GEN_TRACE_CONTEXT_PB_H */
diff --git a/src/core/ext/census/grpc_filter.c b/src/core/ext/census/grpc_filter.c
index b80d831557f7ecab0f3c9a8a2fdb4a0814fe5b19..bcf59a4efee01c1aac255d333c4fee8f0038ad8a 100644
--- a/src/core/ext/census/grpc_filter.c
+++ b/src/core/ext/census/grpc_filter.c
@@ -74,17 +74,18 @@ static void extract_and_annotate_method_tag(grpc_metadata_batch *md,
 }
 
 static void client_mutate_op(grpc_call_element *elem,
-                             grpc_transport_stream_op *op) {
+                             grpc_transport_stream_op_batch *op) {
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
   if (op->send_initial_metadata) {
-    extract_and_annotate_method_tag(op->send_initial_metadata, calld, chand);
+    extract_and_annotate_method_tag(
+        op->payload->send_initial_metadata.send_initial_metadata, calld, chand);
   }
 }
 
 static void client_start_transport_op(grpc_exec_ctx *exec_ctx,
                                       grpc_call_element *elem,
-                                      grpc_transport_stream_op *op) {
+                                      grpc_transport_stream_op_batch *op) {
   client_mutate_op(elem, op);
   grpc_call_next_op(exec_ctx, elem, op);
 }
@@ -103,19 +104,22 @@ static void server_on_done_recv(grpc_exec_ctx *exec_ctx, void *ptr,
 }
 
 static void server_mutate_op(grpc_call_element *elem,
-                             grpc_transport_stream_op *op) {
+                             grpc_transport_stream_op_batch *op) {
   call_data *calld = elem->call_data;
   if (op->recv_initial_metadata) {
     /* substitute our callback for the op callback */
-    calld->recv_initial_metadata = op->recv_initial_metadata;
-    calld->on_done_recv = op->recv_initial_metadata_ready;
-    op->recv_initial_metadata_ready = &calld->finish_recv;
+    calld->recv_initial_metadata =
+        op->payload->recv_initial_metadata.recv_initial_metadata;
+    calld->on_done_recv =
+        op->payload->recv_initial_metadata.recv_initial_metadata_ready;
+    op->payload->recv_initial_metadata.recv_initial_metadata_ready =
+        &calld->finish_recv;
   }
 }
 
 static void server_start_transport_op(grpc_exec_ctx *exec_ctx,
                                       grpc_call_element *elem,
-                                      grpc_transport_stream_op *op) {
+                                      grpc_transport_stream_op_batch *op) {
   /* TODO(ctiller): this code fails. I don't know why. I expect it's
                     incomplete, and someone should look at it soon.
 
@@ -138,7 +142,7 @@ static grpc_error *client_init_call_elem(grpc_exec_ctx *exec_ctx,
 static void client_destroy_call_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_call_element *elem,
                                      const grpc_call_final_info *final_info,
-                                     void *ignored) {
+                                     grpc_closure *ignored) {
   call_data *d = elem->call_data;
   GPR_ASSERT(d != NULL);
   /* TODO(hongyu): record rpc client stats and census_rpc_end_op here */
@@ -160,7 +164,7 @@ static grpc_error *server_init_call_elem(grpc_exec_ctx *exec_ctx,
 static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_call_element *elem,
                                      const grpc_call_final_info *final_info,
-                                     void *ignored) {
+                                     grpc_closure *ignored) {
   call_data *d = elem->call_data;
   GPR_ASSERT(d != NULL);
   /* TODO(hongyu): record rpc server stats and census_tracing_end_op here */
diff --git a/src/core/ext/census/grpc_plugin.c b/src/core/ext/census/grpc_plugin.c
index c9fe453af867e533d6c925a9d6fa1ec3eaae1fee..7d0c9f14ae67d9ad01f179c639255552d317abef 100644
--- a/src/core/ext/census/grpc_plugin.c
+++ b/src/core/ext/census/grpc_plugin.c
@@ -31,6 +31,8 @@
  *
  */
 
+#include <grpc/support/port_platform.h>
+
 #include <limits.h>
 #include <string.h>
 
@@ -48,7 +50,7 @@ static bool is_census_enabled(const grpc_channel_args *a) {
       return a->args[i].value.integer != 0 && census_enabled();
     }
   }
-  return census_enabled();
+  return census_enabled() && !grpc_channel_args_want_minimal_stack(a);
 }
 
 static bool maybe_add_census_filter(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/ext/census/resource.c b/src/core/ext/census/resource.c
index ed44f004f91c2bf74ea726628afcf5e3f34aa8d7..26ea1a86720b17a7322cfd5be1b23f810b942fd7 100644
--- a/src/core/ext/census/resource.c
+++ b/src/core/ext/census/resource.c
@@ -223,7 +223,9 @@ size_t allocate_resource(void) {
   if (n_resources == n_defined_resources) {
     size_t new_n_resources = n_resources ? n_resources * 2 : 2;
     resource **new_resources = gpr_malloc(new_n_resources * sizeof(resource *));
-    memcpy(new_resources, resources, n_resources * sizeof(resource *));
+    if (n_resources != 0) {
+      memcpy(new_resources, resources, n_resources * sizeof(resource *));
+    }
     memset(new_resources + n_resources, 0,
            (new_n_resources - n_resources) * sizeof(resource *));
     gpr_free(resources);
diff --git a/src/core/ext/census/trace_label.h b/src/core/ext/census/trace_label.h
index 0e4a8d885f15a349dee8a57146b1d471ada8dc53..701f6f5a6369f0e3dc6838a7299256134c68884c 100644
--- a/src/core/ext/census/trace_label.h
+++ b/src/core/ext/census/trace_label.h
@@ -58,4 +58,4 @@ typedef struct trace_label {
   } value;
 } trace_label;
 
-#endif
+#endif /* GRPC_CORE_EXT_CENSUS_TRACE_LABEL_H */
diff --git a/src/core/ext/census/trace_propagation.h b/src/core/ext/census/trace_propagation.h
index 75c4ebaa3988df0cd7f39b2129ded1f148cfcf58..0c27bfa111371d8c9a35844513f7416157f83ec1 100644
--- a/src/core/ext/census/trace_propagation.h
+++ b/src/core/ext/census/trace_propagation.h
@@ -60,4 +60,4 @@ size_t trace_span_context_to_http_format(const trace_span_context *ctxt,
 size_t http_format_to_trace_span_context(const char *buf, size_t buf_size,
                                          trace_span_context *ctxt);
 
-#endif
+#endif /* GRPC_CORE_EXT_CENSUS_TRACE_PROPAGATION_H */
diff --git a/src/core/ext/census/trace_status.h b/src/core/ext/census/trace_status.h
index adc0ebd0c02ba7af8c2db9f51cd4153f95de17cb..0734ec6d3d594c64ce044ca2d893351067507078 100644
--- a/src/core/ext/census/trace_status.h
+++ b/src/core/ext/census/trace_status.h
@@ -42,4 +42,4 @@ typedef struct trace_status {
   trace_string errorMessage;
 } trace_status;
 
-#endif
+#endif /* GRPC_CORE_EXT_CENSUS_TRACE_STATUS_H */
diff --git a/src/core/ext/census/trace_string.h b/src/core/ext/census/trace_string.h
index 8e77ee9f7ed76e52d3906588641451c44b4c1457..cd63cfb92f45e9dec8492bd874011f3b05e21a3b 100644
--- a/src/core/ext/census/trace_string.h
+++ b/src/core/ext/census/trace_string.h
@@ -47,4 +47,4 @@ typedef struct trace_string {
   size_t length;
 } trace_string;
 
-#endif
+#endif /* GRPC_CORE_EXT_CENSUS_TRACE_STRING_H */
diff --git a/src/core/ext/census/tracing.h b/src/core/ext/census/tracing.h
index c2b947ae407ce32c5541934c10937ea6f4be617a..3a7c6f45e433ce056d397bb8bc9d092d66e58139 100644
--- a/src/core/ext/census/tracing.h
+++ b/src/core/ext/census/tracing.h
@@ -121,4 +121,4 @@ free to ignore all further calls using the Span. EndSpanOptions can
 optionally be NULL. */
 void trace_end_span(const trace_status *status, trace_span_context *span_ctxt);
 
-#endif
+#endif /* GRPC_CORE_EXT_CENSUS_TRACING_H */
diff --git a/src/core/ext/client_channel/README.md b/src/core/ext/filters/client_channel/README.md
similarity index 100%
rename from src/core/ext/client_channel/README.md
rename to src/core/ext/filters/client_channel/README.md
diff --git a/src/core/ext/client_channel/channel_connectivity.c b/src/core/ext/filters/client_channel/channel_connectivity.c
similarity index 97%
rename from src/core/ext/client_channel/channel_connectivity.c
rename to src/core/ext/filters/client_channel/channel_connectivity.c
index dd70bc2c6c8997b075514f9641b37fa151daa6c1..62f58fb278a2f71d40e1ab8fe12fffadc9ed9ddf 100644
--- a/src/core/ext/client_channel/channel_connectivity.c
+++ b/src/core/ext/filters/client_channel/channel_connectivity.c
@@ -36,7 +36,7 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/completion_queue.h"
@@ -139,8 +139,8 @@ static void partly_done(grpc_exec_ctx *exec_ctx, state_watcher *w,
     error = GRPC_ERROR_NONE;
   } else {
     if (error == GRPC_ERROR_NONE) {
-      error =
-          GRPC_ERROR_CREATE("Timed out waiting for connection state change");
+      error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "Timed out waiting for connection state change");
     } else if (error == GRPC_ERROR_CANCELLED) {
       error = GRPC_ERROR_NONE;
     }
diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/filters/client_channel/client_channel.c
similarity index 69%
rename from src/core/ext/client_channel/client_channel.c
rename to src/core/ext/filters/client_channel/client_channel.c
index bf64f84772c48d9c721643dfd79deab896b5875d..24843d52e9f0ab5754d2ceaa17c948e8f8787e27 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/filters/client_channel/client_channel.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
 
 #include <stdbool.h>
 #include <stdio.h>
@@ -43,14 +43,15 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/useful.h>
 
-#include "src/core/ext/client_channel/http_connect_handshaker.h"
-#include "src/core/ext/client_channel/lb_policy_registry.h"
-#include "src/core/ext/client_channel/proxy_mapper_registry.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
-#include "src/core/ext/client_channel/subchannel.h"
+#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
+#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/retry_throttle.h"
+#include "src/core/ext/filters/client_channel/subchannel.h"
+#include "src/core/ext/filters/deadline/deadline_filter.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/deadline_filter.h"
 #include "src/core/lib/iomgr/combiner.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/iomgr/polling_entity.h"
@@ -71,7 +72,8 @@
  */
 
 typedef enum {
-  WAIT_FOR_READY_UNSET,
+  /* zero so it can be default initialized */
+  WAIT_FOR_READY_UNSET = 0,
   WAIT_FOR_READY_FALSE,
   WAIT_FOR_READY_TRUE
 } wait_for_ready_value;
@@ -94,17 +96,10 @@ static void method_parameters_unref(method_parameters *method_params) {
   }
 }
 
-static void *method_parameters_copy(void *value) {
-  return method_parameters_ref(value);
-}
-
 static void method_parameters_free(grpc_exec_ctx *exec_ctx, void *value) {
   method_parameters_unref(value);
 }
 
-static const grpc_slice_hash_table_vtable method_parameters_vtable = {
-    method_parameters_free, method_parameters_copy};
-
 static bool parse_wait_for_ready(grpc_json *field,
                                  wait_for_ready_value *wait_for_ready) {
   if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) {
@@ -181,6 +176,8 @@ typedef struct client_channel_channel_data {
   grpc_resolver *resolver;
   /** have we started resolving this channel */
   bool started_resolving;
+  /** is deadline checking enabled? */
+  bool deadline_checking_enabled;
   /** client channel factory */
   grpc_client_channel_factory *client_channel_factory;
 
@@ -188,6 +185,8 @@ typedef struct client_channel_channel_data {
   grpc_combiner *combiner;
   /** currently active load balancer */
   grpc_lb_policy *lb_policy;
+  /** retry throttle data */
+  grpc_server_retry_throttle_data *retry_throttle_data;
   /** maps method names to method_parameters structs */
   grpc_slice_hash_table *method_params_table;
   /** incoming resolver result - set by resolver.next() */
@@ -232,14 +231,23 @@ static void set_channel_connectivity_state_locked(grpc_exec_ctx *exec_ctx,
                                                   grpc_connectivity_state state,
                                                   grpc_error *error,
                                                   const char *reason) {
-  if ((state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
-       state == GRPC_CHANNEL_SHUTDOWN) &&
-      chand->lb_policy != NULL) {
-    /* cancel picks with wait_for_ready=false */
-    grpc_lb_policy_cancel_picks_locked(
-        exec_ctx, chand->lb_policy,
-        /* mask= */ GRPC_INITIAL_METADATA_WAIT_FOR_READY,
-        /* check= */ 0, GRPC_ERROR_REF(error));
+  /* TODO: Improve failure handling:
+   * - Make it possible for policies to return GRPC_CHANNEL_TRANSIENT_FAILURE.
+   * - Hand over pending picks from old policies during the switch that happens
+   *   when resolver provides an update. */
+  if (chand->lb_policy != NULL) {
+    if (state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
+      /* cancel picks with wait_for_ready=false */
+      grpc_lb_policy_cancel_picks_locked(
+          exec_ctx, chand->lb_policy,
+          /* mask= */ GRPC_INITIAL_METADATA_WAIT_FOR_READY,
+          /* check= */ 0, GRPC_ERROR_REF(error));
+    } else if (state == GRPC_CHANNEL_SHUTDOWN) {
+      /* cancel all picks */
+      grpc_lb_policy_cancel_picks_locked(exec_ctx, chand->lb_policy,
+                                         /* mask= */ 0, /* check= */ 0,
+                                         GRPC_ERROR_REF(error));
+    }
   }
   grpc_connectivity_state_set(exec_ctx, &chand->state_tracker, state, error,
                               reason);
@@ -283,6 +291,92 @@ static void watch_lb_policy_locked(grpc_exec_ctx *exec_ctx, channel_data *chand,
                                                &w->on_changed);
 }
 
+typedef struct {
+  char *server_name;
+  grpc_server_retry_throttle_data *retry_throttle_data;
+} service_config_parsing_state;
+
+static void parse_retry_throttle_params(const grpc_json *field, void *arg) {
+  service_config_parsing_state *parsing_state = arg;
+  if (strcmp(field->key, "retryThrottling") == 0) {
+    if (parsing_state->retry_throttle_data != NULL) return;  // Duplicate.
+    if (field->type != GRPC_JSON_OBJECT) return;
+    int max_milli_tokens = 0;
+    int milli_token_ratio = 0;
+    for (grpc_json *sub_field = field->child; sub_field != NULL;
+         sub_field = sub_field->next) {
+      if (sub_field->key == NULL) return;
+      if (strcmp(sub_field->key, "maxTokens") == 0) {
+        if (max_milli_tokens != 0) return;  // Duplicate.
+        if (sub_field->type != GRPC_JSON_NUMBER) return;
+        max_milli_tokens = gpr_parse_nonnegative_int(sub_field->value);
+        if (max_milli_tokens == -1) return;
+        max_milli_tokens *= 1000;
+      } else if (strcmp(sub_field->key, "tokenRatio") == 0) {
+        if (milli_token_ratio != 0) return;  // Duplicate.
+        if (sub_field->type != GRPC_JSON_NUMBER) return;
+        // We support up to 3 decimal digits.
+        size_t whole_len = strlen(sub_field->value);
+        uint32_t multiplier = 1;
+        uint32_t decimal_value = 0;
+        const char *decimal_point = strchr(sub_field->value, '.');
+        if (decimal_point != NULL) {
+          whole_len = (size_t)(decimal_point - sub_field->value);
+          multiplier = 1000;
+          size_t decimal_len = strlen(decimal_point + 1);
+          if (decimal_len > 3) decimal_len = 3;
+          if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len,
+                                         &decimal_value)) {
+            return;
+          }
+          uint32_t decimal_multiplier = 1;
+          for (size_t i = 0; i < (3 - decimal_len); ++i) {
+            decimal_multiplier *= 10;
+          }
+          decimal_value *= decimal_multiplier;
+        }
+        uint32_t whole_value;
+        if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len,
+                                       &whole_value)) {
+          return;
+        }
+        milli_token_ratio = (int)((whole_value * multiplier) + decimal_value);
+        if (milli_token_ratio <= 0) return;
+      }
+    }
+    parsing_state->retry_throttle_data =
+        grpc_retry_throttle_map_get_data_for_server(
+            parsing_state->server_name, max_milli_tokens, milli_token_ratio);
+  }
+}
+
+// Wrap a closure associated with \a lb_policy. The associated callback (\a
+// wrapped_on_pick_closure_cb) is responsible for unref'ing \a lb_policy after
+// scheduling \a wrapped_closure.
+typedef struct wrapped_on_pick_closure_arg {
+  /* the closure instance using this struct as argument */
+  grpc_closure wrapper_closure;
+
+  /* the original closure. Usually a on_complete/notify cb for pick() and ping()
+   * calls against the internal RR instance, respectively. */
+  grpc_closure *wrapped_closure;
+
+  /* The policy instance related to the closure */
+  grpc_lb_policy *lb_policy;
+} wrapped_on_pick_closure_arg;
+
+// Invoke \a arg->wrapped_closure, unref \a arg->lb_policy and free \a arg.
+static void wrapped_on_pick_closure_cb(grpc_exec_ctx *exec_ctx, void *arg,
+                                       grpc_error *error) {
+  wrapped_on_pick_closure_arg *wc_arg = arg;
+  GPR_ASSERT(wc_arg != NULL);
+  GPR_ASSERT(wc_arg->wrapped_closure != NULL);
+  GPR_ASSERT(wc_arg->lb_policy != NULL);
+  grpc_closure_run(exec_ctx, wc_arg->wrapped_closure, GRPC_ERROR_REF(error));
+  GRPC_LB_POLICY_UNREF(exec_ctx, wc_arg->lb_policy, "pick_subchannel_wrapping");
+  gpr_free(wc_arg);
+}
+
 static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
                                               void *arg, grpc_error *error) {
   channel_data *chand = arg;
@@ -292,8 +386,11 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
   grpc_slice_hash_table *method_params_table = NULL;
   grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE;
   bool exit_idle = false;
-  grpc_error *state_error = GRPC_ERROR_CREATE("No load balancing policy");
+  grpc_error *state_error =
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("No load balancing policy");
   char *service_config_json = NULL;
+  service_config_parsing_state parsing_state;
+  memset(&parsing_state, 0, sizeof(parsing_state));
 
   if (chand->resolver_result != NULL) {
     // Find LB policy name.
@@ -303,27 +400,24 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
       GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
       lb_policy_name = channel_arg->value.string;
     }
-    // Special case: If all of the addresses are balancer addresses,
-    // assume that we should use the grpclb policy, regardless of what the
-    // resolver actually specified.
+    // Special case: If at least one balancer address is present, we use
+    // the grpclb policy, regardless of what the resolver actually specified.
     channel_arg =
         grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_ADDRESSES);
-    if (channel_arg != NULL) {
-      GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER);
+    if (channel_arg != NULL && channel_arg->type == GRPC_ARG_POINTER) {
       grpc_lb_addresses *addresses = channel_arg->value.pointer.p;
-      bool found_backend_address = false;
+      bool found_balancer_address = false;
       for (size_t i = 0; i < addresses->num_addresses; ++i) {
-        if (!addresses->addresses[i].is_balancer) {
-          found_backend_address = true;
+        if (addresses->addresses[i].is_balancer) {
+          found_balancer_address = true;
           break;
         }
       }
-      if (!found_backend_address) {
+      if (found_balancer_address) {
         if (lb_policy_name != NULL && strcmp(lb_policy_name, "grpclb") != 0) {
           gpr_log(GPR_INFO,
-                  "resolver requested LB policy %s but provided only balancer "
-                  "addresses, no backend addresses -- forcing use of grpclb LB "
-                  "policy",
+                  "resolver requested LB policy %s but provided at least one "
+                  "balancer address -- forcing use of grpclb LB policy",
                   lb_policy_name);
         }
         lb_policy_name = "grpclb";
@@ -354,9 +448,22 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
       grpc_service_config *service_config =
           grpc_service_config_create(service_config_json);
       if (service_config != NULL) {
+        channel_arg =
+            grpc_channel_args_find(chand->resolver_result, GRPC_ARG_SERVER_URI);
+        GPR_ASSERT(channel_arg != NULL);
+        GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
+        grpc_uri *uri =
+            grpc_uri_parse(exec_ctx, channel_arg->value.string, true);
+        GPR_ASSERT(uri->path[0] != '\0');
+        parsing_state.server_name =
+            uri->path[0] == '/' ? uri->path + 1 : uri->path;
+        grpc_service_config_parse_global_params(
+            service_config, parse_retry_throttle_params, &parsing_state);
+        parsing_state.server_name = NULL;
+        grpc_uri_destroy(uri);
         method_params_table = grpc_service_config_create_method_config_table(
             exec_ctx, service_config, method_parameters_create_from_json,
-            &method_parameters_vtable);
+            method_parameters_free);
         grpc_service_config_destroy(service_config);
       }
     }
@@ -385,6 +492,11 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
     chand->info_service_config_json = service_config_json;
   }
   gpr_mu_unlock(&chand->info_mu);
+
+  if (chand->retry_throttle_data != NULL) {
+    grpc_server_retry_throttle_data_unref(chand->retry_throttle_data);
+  }
+  chand->retry_throttle_data = parsing_state.retry_throttle_data;
   if (chand->method_params_table != NULL) {
     grpc_slice_hash_table_unref(exec_ctx, chand->method_params_table);
   }
@@ -392,9 +504,9 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
   if (lb_policy != NULL) {
     grpc_closure_list_sched(exec_ctx, &chand->waiting_for_config_closures);
   } else if (chand->resolver == NULL /* disconnected */) {
-    grpc_closure_list_fail_all(
-        &chand->waiting_for_config_closures,
-        GRPC_ERROR_CREATE_REFERENCING("Channel disconnected", &error, 1));
+    grpc_closure_list_fail_all(&chand->waiting_for_config_closures,
+                               GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                                   "Channel disconnected", &error, 1));
     grpc_closure_list_sched(exec_ctx, &chand->waiting_for_config_closures);
   }
   if (lb_policy != NULL && chand->exit_idle_when_lb_policy_arrives) {
@@ -422,8 +534,8 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
     grpc_error *refs[] = {error, state_error};
     set_channel_connectivity_state_locked(
         exec_ctx, chand, GRPC_CHANNEL_SHUTDOWN,
-        GRPC_ERROR_CREATE_REFERENCING("Got config after disconnection", refs,
-                                      GPR_ARRAY_SIZE(refs)),
+        GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+            "Got config after disconnection", refs, GPR_ARRAY_SIZE(refs)),
         "resolver_gone");
   }
 
@@ -449,7 +561,7 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
 static void start_transport_op_locked(grpc_exec_ctx *exec_ctx, void *arg,
                                       grpc_error *error_ignored) {
   grpc_transport_op *op = arg;
-  grpc_channel_element *elem = op->transport_private.args[0];
+  grpc_channel_element *elem = op->handler_private.extra_arg;
   channel_data *chand = elem->channel_data;
 
   if (op->on_connectivity_state_change != NULL) {
@@ -462,8 +574,9 @@ static void start_transport_op_locked(grpc_exec_ctx *exec_ctx, void *arg,
 
   if (op->send_ping != NULL) {
     if (chand->lb_policy == NULL) {
-      grpc_closure_sched(exec_ctx, op->send_ping,
-                         GRPC_ERROR_CREATE("Ping with no load balancing"));
+      grpc_closure_sched(
+          exec_ctx, op->send_ping,
+          GRPC_ERROR_CREATE_FROM_STATIC_STRING("Ping with no load balancing"));
     } else {
       grpc_lb_policy_ping_one_locked(exec_ctx, chand->lb_policy, op->send_ping);
       op->bind_pollset = NULL;
@@ -510,12 +623,12 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx,
                                  op->bind_pollset);
   }
 
-  op->transport_private.args[0] = elem;
+  op->handler_private.extra_arg = elem;
   GRPC_CHANNEL_STACK_REF(chand->owning_stack, "start_transport_op");
   grpc_closure_sched(
-      exec_ctx, grpc_closure_init(
-                    &op->transport_private.closure, start_transport_op_locked,
-                    op, grpc_combiner_scheduler(chand->combiner, false)),
+      exec_ctx,
+      grpc_closure_init(&op->handler_private.closure, start_transport_op_locked,
+                        op, grpc_combiner_scheduler(chand->combiner, false)),
       GRPC_ERROR_NONE);
 }
 
@@ -558,14 +671,26 @@ static grpc_error *cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
   // Record client channel factory.
   const grpc_arg *arg = grpc_channel_args_find(args->channel_args,
                                                GRPC_ARG_CLIENT_CHANNEL_FACTORY);
-  GPR_ASSERT(arg != NULL);
-  GPR_ASSERT(arg->type == GRPC_ARG_POINTER);
+  if (arg == NULL) {
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Missing client channel factory in args for client channel filter");
+  }
+  if (arg->type != GRPC_ARG_POINTER) {
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "client channel factory arg must be a pointer");
+  }
   grpc_client_channel_factory_ref(arg->value.pointer.p);
   chand->client_channel_factory = arg->value.pointer.p;
   // Get server name to resolve, using proxy mapper if needed.
   arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI);
-  GPR_ASSERT(arg != NULL);
-  GPR_ASSERT(arg->type == GRPC_ARG_STRING);
+  if (arg == NULL) {
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Missing server uri in args for client channel filter");
+  }
+  if (arg->type != GRPC_ARG_STRING) {
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "server uri arg must be a string");
+  }
   char *proxy_name = NULL;
   grpc_channel_args *new_args = NULL;
   grpc_proxy_mappers_map_name(exec_ctx, arg->value.string, args->channel_args,
@@ -578,8 +703,10 @@ static grpc_error *cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
   if (proxy_name != NULL) gpr_free(proxy_name);
   if (new_args != NULL) grpc_channel_args_destroy(exec_ctx, new_args);
   if (chand->resolver == NULL) {
-    return GRPC_ERROR_CREATE("resolver creation failed");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed");
   }
+  chand->deadline_checking_enabled =
+      grpc_deadline_checking_enabled(args->channel_args);
   return GRPC_ERROR_NONE;
 }
 
@@ -612,6 +739,9 @@ static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx,
   }
   gpr_free(chand->info_lb_policy_name);
   gpr_free(chand->info_service_config_json);
+  if (chand->retry_throttle_data != NULL) {
+    grpc_server_retry_throttle_data_unref(chand->retry_throttle_data);
+  }
   if (chand->method_params_table != NULL) {
     grpc_slice_hash_table_unref(exec_ctx, chand->method_params_table);
   }
@@ -630,11 +760,6 @@ static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx,
 
 #define CANCELLED_CALL ((grpc_subchannel_call *)1)
 
-typedef enum {
-  GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING,
-  GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL
-} subchannel_creation_phase;
-
 /** Call data.  Holds a pointer to grpc_subchannel_call and the
     associated machinery to create such a pointer.
     Handles queueing of stream ops until a call object is ready, waiting
@@ -652,20 +777,22 @@ typedef struct client_channel_call_data {
   grpc_slice path;  // Request path.
   gpr_timespec call_start_time;
   gpr_timespec deadline;
+  grpc_server_retry_throttle_data *retry_throttle_data;
   method_parameters *method_params;
-  grpc_closure read_service_config;
 
   grpc_error *cancel_error;
 
   /** either 0 for no call, 1 for cancelled, or a pointer to a
       grpc_subchannel_call */
   gpr_atm subchannel_call;
+  gpr_arena *arena;
 
-  subchannel_creation_phase creation_phase;
+  bool pick_pending;
   grpc_connected_subchannel *connected_subchannel;
+  grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT];
   grpc_polling_entity *pollent;
 
-  grpc_transport_stream_op **waiting_ops;
+  grpc_transport_stream_op_batch **waiting_ops;
   size_t waiting_ops_count;
   size_t waiting_ops_capacity;
 
@@ -674,6 +801,9 @@ typedef struct client_channel_call_data {
   grpc_call_stack *owning_call;
 
   grpc_linked_mdelem lb_token_mdelem;
+
+  grpc_closure on_complete;
+  grpc_closure *original_on_complete;
 } call_data;
 
 grpc_subchannel_call *grpc_client_channel_get_subchannel_call(
@@ -682,7 +812,8 @@ grpc_subchannel_call *grpc_client_channel_get_subchannel_call(
   return scc == CANCELLED_CALL ? NULL : scc;
 }
 
-static void add_waiting_locked(call_data *calld, grpc_transport_stream_op *op) {
+static void add_waiting_locked(call_data *calld,
+                               grpc_transport_stream_op_batch *op) {
   GPR_TIMER_BEGIN("add_waiting_locked", 0);
   if (calld->waiting_ops_count == calld->waiting_ops_capacity) {
     calld->waiting_ops_capacity = GPR_MAX(3, 2 * calld->waiting_ops_capacity);
@@ -698,7 +829,7 @@ static void fail_locked(grpc_exec_ctx *exec_ctx, call_data *calld,
                         grpc_error *error) {
   size_t i;
   for (i = 0; i < calld->waiting_ops_count; i++) {
-    grpc_transport_stream_op_finish_with_failure(
+    grpc_transport_stream_op_batch_finish_with_failure(
         exec_ctx, calld->waiting_ops[i], GRPC_ERROR_REF(error));
   }
   calld->waiting_ops_count = 0;
@@ -711,7 +842,7 @@ static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, call_data *calld) {
   }
 
   grpc_subchannel_call *call = GET_CALL(calld);
-  grpc_transport_stream_op **ops = calld->waiting_ops;
+  grpc_transport_stream_op_batch **ops = calld->waiting_ops;
   size_t nops = calld->waiting_ops_count;
   if (call == CANCELLED_CALL) {
     fail_locked(exec_ctx, calld, GRPC_ERROR_CANCELLED);
@@ -726,24 +857,72 @@ static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, call_data *calld) {
   gpr_free(ops);
 }
 
+// Sets calld->method_params and calld->retry_throttle_data.
+// If the method params specify a timeout, populates
+// *per_method_deadline and returns true.
+static bool set_call_method_params_from_service_config_locked(
+    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+    gpr_timespec *per_method_deadline) {
+  channel_data *chand = elem->channel_data;
+  call_data *calld = elem->call_data;
+  if (chand->retry_throttle_data != NULL) {
+    calld->retry_throttle_data =
+        grpc_server_retry_throttle_data_ref(chand->retry_throttle_data);
+  }
+  if (chand->method_params_table != NULL) {
+    calld->method_params = grpc_method_config_table_get(
+        exec_ctx, chand->method_params_table, calld->path);
+    if (calld->method_params != NULL) {
+      method_parameters_ref(calld->method_params);
+      if (gpr_time_cmp(calld->method_params->timeout,
+                       gpr_time_0(GPR_TIMESPAN)) != 0) {
+        *per_method_deadline =
+            gpr_time_add(calld->call_start_time, calld->method_params->timeout);
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+static void apply_final_configuration_locked(grpc_exec_ctx *exec_ctx,
+                                             grpc_call_element *elem) {
+  /* apply service-config level configuration to the call (now that we're
+   * certain it exists) */
+  call_data *calld = elem->call_data;
+  channel_data *chand = elem->channel_data;
+  gpr_timespec per_method_deadline;
+  if (set_call_method_params_from_service_config_locked(exec_ctx, elem,
+                                                        &per_method_deadline)) {
+    // If the deadline from the service config is shorter than the one
+    // from the client API, reset the deadline timer.
+    if (chand->deadline_checking_enabled &&
+        gpr_time_cmp(per_method_deadline, calld->deadline) < 0) {
+      calld->deadline = per_method_deadline;
+      grpc_deadline_state_reset(exec_ctx, elem, calld->deadline);
+    }
+  }
+}
+
 static void subchannel_ready_locked(grpc_exec_ctx *exec_ctx, void *arg,
                                     grpc_error *error) {
   grpc_call_element *elem = arg;
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
-  GPR_ASSERT(calld->creation_phase ==
-             GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL);
+  GPR_ASSERT(calld->pick_pending);
+  calld->pick_pending = false;
   grpc_polling_entity_del_from_pollset_set(exec_ctx, calld->pollent,
                                            chand->interested_parties);
-  calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
   if (calld->connected_subchannel == NULL) {
     gpr_atm_no_barrier_store(&calld->subchannel_call, 1);
-    fail_locked(exec_ctx, calld, GRPC_ERROR_CREATE_REFERENCING(
-                                     "Failed to create subchannel", &error, 1));
+    fail_locked(exec_ctx, calld,
+                GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                    "Failed to create subchannel", &error, 1));
   } else if (GET_CALL(calld) == CANCELLED_CALL) {
     /* already cancelled before subchannel became ready */
-    grpc_error *cancellation_error = GRPC_ERROR_CREATE_REFERENCING(
-        "Cancelled before creating subchannel", &error, 1);
+    grpc_error *cancellation_error =
+        GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+            "Cancelled before creating subchannel", &error, 1);
     /* if due to deadline, attach the deadline exceeded status to the error */
     if (gpr_time_cmp(calld->deadline, gpr_now(GPR_CLOCK_MONOTONIC)) < 0) {
       cancellation_error =
@@ -754,17 +933,23 @@ static void subchannel_ready_locked(grpc_exec_ctx *exec_ctx, void *arg,
   } else {
     /* Create call on subchannel. */
     grpc_subchannel_call *subchannel_call = NULL;
+    const grpc_connected_subchannel_call_args call_args = {
+        .pollent = calld->pollent,
+        .path = calld->path,
+        .start_time = calld->call_start_time,
+        .deadline = calld->deadline,
+        .arena = calld->arena,
+        .context = calld->subchannel_call_context};
     grpc_error *new_error = grpc_connected_subchannel_create_call(
-        exec_ctx, calld->connected_subchannel, calld->pollent, calld->path,
-        calld->call_start_time, calld->deadline, &subchannel_call);
+        exec_ctx, calld->connected_subchannel, &call_args, &subchannel_call);
+    gpr_atm_rel_store(&calld->subchannel_call,
+                      (gpr_atm)(uintptr_t)subchannel_call);
     if (new_error != GRPC_ERROR_NONE) {
       new_error = grpc_error_add_child(new_error, error);
-      subchannel_call = CANCELLED_CALL;
       fail_locked(exec_ctx, calld, new_error);
+    } else {
+      retry_waiting_locked(exec_ctx, calld);
     }
-    gpr_atm_rel_store(&calld->subchannel_call,
-                      (gpr_atm)(uintptr_t)subchannel_call);
-    retry_waiting_locked(exec_ctx, calld);
   }
   GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel");
 }
@@ -783,6 +968,7 @@ typedef struct {
   grpc_metadata_batch *initial_metadata;
   uint32_t initial_metadata_flags;
   grpc_connected_subchannel **connected_subchannel;
+  grpc_call_context_element *subchannel_call_context;
   grpc_closure *on_ready;
   grpc_call_element *elem;
   grpc_closure closure;
@@ -794,8 +980,8 @@ typedef struct {
 static bool pick_subchannel_locked(
     grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
     grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags,
-    grpc_connected_subchannel **connected_subchannel, grpc_closure *on_ready,
-    grpc_error *error);
+    grpc_connected_subchannel **connected_subchannel,
+    grpc_call_context_element *subchannel_call_context, grpc_closure *on_ready);
 
 static void continue_picking_locked(grpc_exec_ctx *exec_ctx, void *arg,
                                     grpc_error *error) {
@@ -807,50 +993,51 @@ static void continue_picking_locked(grpc_exec_ctx *exec_ctx, void *arg,
   } else {
     if (pick_subchannel_locked(exec_ctx, cpa->elem, cpa->initial_metadata,
                                cpa->initial_metadata_flags,
-                               cpa->connected_subchannel, cpa->on_ready,
-                               GRPC_ERROR_NONE)) {
+                               cpa->connected_subchannel,
+                               cpa->subchannel_call_context, cpa->on_ready)) {
       grpc_closure_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_NONE);
     }
   }
   gpr_free(cpa);
 }
 
+static void cancel_pick_locked(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+                               grpc_error *error) {
+  channel_data *chand = elem->channel_data;
+  call_data *calld = elem->call_data;
+  if (chand->lb_policy != NULL) {
+    grpc_lb_policy_cancel_pick_locked(exec_ctx, chand->lb_policy,
+                                      &calld->connected_subchannel,
+                                      GRPC_ERROR_REF(error));
+  }
+  for (grpc_closure *closure = chand->waiting_for_config_closures.head;
+       closure != NULL; closure = closure->next_data.next) {
+    continue_picking_args *cpa = closure->cb_arg;
+    if (cpa->connected_subchannel == &calld->connected_subchannel) {
+      cpa->connected_subchannel = NULL;
+      grpc_closure_sched(exec_ctx, cpa->on_ready,
+                         GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                             "Pick cancelled", &error, 1));
+    }
+  }
+  GRPC_ERROR_UNREF(error);
+}
+
 static bool pick_subchannel_locked(
     grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
     grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags,
-    grpc_connected_subchannel **connected_subchannel, grpc_closure *on_ready,
-    grpc_error *error) {
+    grpc_connected_subchannel **connected_subchannel,
+    grpc_call_context_element *subchannel_call_context,
+    grpc_closure *on_ready) {
   GPR_TIMER_BEGIN("pick_subchannel", 0);
 
   channel_data *chand = elem->channel_data;
   call_data *calld = elem->call_data;
-  continue_picking_args *cpa;
-  grpc_closure *closure;
 
   GPR_ASSERT(connected_subchannel);
 
-  if (initial_metadata == NULL) {
-    if (chand->lb_policy != NULL) {
-      grpc_lb_policy_cancel_pick_locked(exec_ctx, chand->lb_policy,
-                                        connected_subchannel,
-                                        GRPC_ERROR_REF(error));
-    }
-    for (closure = chand->waiting_for_config_closures.head; closure != NULL;
-         closure = closure->next_data.next) {
-      cpa = closure->cb_arg;
-      if (cpa->connected_subchannel == connected_subchannel) {
-        cpa->connected_subchannel = NULL;
-        grpc_closure_sched(
-            exec_ctx, cpa->on_ready,
-            GRPC_ERROR_CREATE_REFERENCING("Pick cancelled", &error, 1));
-      }
-    }
-    GPR_TIMER_END("pick_subchannel", 0);
-    GRPC_ERROR_UNREF(error);
-    return true;
-  }
-  GPR_ASSERT(error == GRPC_ERROR_NONE);
   if (chand->lb_policy != NULL) {
+    apply_final_configuration_locked(exec_ctx, elem);
     grpc_lb_policy *lb_policy = chand->lb_policy;
     GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel");
     // If the application explicitly set wait_for_ready, use that.
@@ -871,13 +1058,30 @@ static bool pick_subchannel_locked(
       }
     }
     const grpc_lb_policy_pick_args inputs = {
-        initial_metadata, initial_metadata_flags, &calld->lb_token_mdelem,
-        gpr_inf_future(GPR_CLOCK_MONOTONIC)};
-    const bool result = grpc_lb_policy_pick_locked(
-        exec_ctx, lb_policy, &inputs, connected_subchannel, NULL, on_ready);
+        initial_metadata, initial_metadata_flags, &calld->lb_token_mdelem};
+
+    // Wrap the user-provided callback in order to hold a strong reference to
+    // the LB policy for the duration of the pick.
+    wrapped_on_pick_closure_arg *w_on_pick_arg =
+        gpr_zalloc(sizeof(*w_on_pick_arg));
+    grpc_closure_init(&w_on_pick_arg->wrapper_closure,
+                      wrapped_on_pick_closure_cb, w_on_pick_arg,
+                      grpc_schedule_on_exec_ctx);
+    w_on_pick_arg->wrapped_closure = on_ready;
+    GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel_wrapping");
+    w_on_pick_arg->lb_policy = lb_policy;
+    const bool pick_done = grpc_lb_policy_pick_locked(
+        exec_ctx, lb_policy, &inputs, connected_subchannel,
+        subchannel_call_context, NULL, &w_on_pick_arg->wrapper_closure);
+    if (pick_done) {
+      /* synchronous grpc_lb_policy_pick call. Unref the LB policy. */
+      GRPC_LB_POLICY_UNREF(exec_ctx, w_on_pick_arg->lb_policy,
+                           "pick_subchannel_wrapping");
+      gpr_free(w_on_pick_arg);
+    }
     GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "pick_subchannel");
     GPR_TIMER_END("pick_subchannel", 0);
-    return result;
+    return pick_done;
   }
   if (chand->resolver != NULL && !chand->started_resolving) {
     chand->started_resolving = true;
@@ -887,10 +1091,11 @@ static bool pick_subchannel_locked(
                               &chand->on_resolver_result_changed);
   }
   if (chand->resolver != NULL) {
-    cpa = gpr_malloc(sizeof(*cpa));
+    continue_picking_args *cpa = gpr_malloc(sizeof(*cpa));
     cpa->initial_metadata = initial_metadata;
     cpa->initial_metadata_flags = initial_metadata_flags;
     cpa->connected_subchannel = connected_subchannel;
+    cpa->subchannel_call_context = subchannel_call_context;
     cpa->on_ready = on_ready;
     cpa->elem = elem;
     grpc_closure_init(&cpa->closure, continue_picking_locked, cpa,
@@ -898,16 +1103,17 @@ static bool pick_subchannel_locked(
     grpc_closure_list_append(&chand->waiting_for_config_closures, &cpa->closure,
                              GRPC_ERROR_NONE);
   } else {
-    grpc_closure_sched(exec_ctx, on_ready, GRPC_ERROR_CREATE("Disconnected"));
+    grpc_closure_sched(exec_ctx, on_ready,
+                       GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected"));
   }
 
   GPR_TIMER_END("pick_subchannel", 0);
   return false;
 }
 
-static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx,
-                                                   grpc_transport_stream_op *op,
-                                                   grpc_call_element *elem) {
+static void start_transport_stream_op_batch_locked_inner(
+    grpc_exec_ctx *exec_ctx, grpc_transport_stream_op_batch *op,
+    grpc_call_element *elem) {
   channel_data *chand = elem->channel_data;
   call_data *calld = elem->call_data;
   grpc_subchannel_call *call;
@@ -915,7 +1121,7 @@ static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx,
   /* need to recheck that another thread hasn't set the call */
   call = GET_CALL(calld);
   if (call == CANCELLED_CALL) {
-    grpc_transport_stream_op_finish_with_failure(
+    grpc_transport_stream_op_batch_finish_with_failure(
         exec_ctx, op, GRPC_ERROR_REF(calld->cancel_error));
     /* early out */
     return;
@@ -926,11 +1132,11 @@ static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx,
     return;
   }
   /* if this is a cancellation, then we can raise our cancelled flag */
-  if (op->cancel_error != GRPC_ERROR_NONE) {
+  if (op->cancel_stream) {
     if (!gpr_atm_rel_cas(&calld->subchannel_call, 0,
                          (gpr_atm)(uintptr_t)CANCELLED_CALL)) {
       /* recurse to retry */
-      start_transport_stream_op_locked_inner(exec_ctx, op, elem);
+      start_transport_stream_op_batch_locked_inner(exec_ctx, op, elem);
       /* early out */
       return;
     } else {
@@ -939,39 +1145,40 @@ static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx,
          cancelled before any ops are passed down (e.g., if the deadline
          is in the past when the call starts), we can return the right
          error to the caller when the first op does get passed down. */
-      calld->cancel_error = GRPC_ERROR_REF(op->cancel_error);
-      switch (calld->creation_phase) {
-        case GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING:
-          fail_locked(exec_ctx, calld, GRPC_ERROR_REF(op->cancel_error));
-          break;
-        case GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL:
-          pick_subchannel_locked(exec_ctx, elem, NULL, 0,
-                                 &calld->connected_subchannel, NULL,
-                                 GRPC_ERROR_REF(op->cancel_error));
-          break;
+      calld->cancel_error =
+          GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error);
+      if (calld->pick_pending) {
+        cancel_pick_locked(
+            exec_ctx, elem,
+            GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error));
+      } else {
+        fail_locked(exec_ctx, calld,
+                    GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error));
       }
-      grpc_transport_stream_op_finish_with_failure(
-          exec_ctx, op, GRPC_ERROR_REF(op->cancel_error));
+      grpc_transport_stream_op_batch_finish_with_failure(
+          exec_ctx, op,
+          GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error));
       /* early out */
       return;
     }
   }
   /* if we don't have a subchannel, try to get one */
-  if (calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING &&
-      calld->connected_subchannel == NULL &&
-      op->send_initial_metadata != NULL) {
-    calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL;
+  if (!calld->pick_pending && calld->connected_subchannel == NULL &&
+      op->send_initial_metadata) {
+    calld->pick_pending = true;
     grpc_closure_init(&calld->next_step, subchannel_ready_locked, elem,
                       grpc_combiner_scheduler(chand->combiner, true));
     GRPC_CALL_STACK_REF(calld->owning_call, "pick_subchannel");
     /* If a subchannel is not available immediately, the polling entity from
        call_data should be provided to channel_data's interested_parties, so
        that IO of the lb_policy and resolver could be done under it. */
-    if (pick_subchannel_locked(exec_ctx, elem, op->send_initial_metadata,
-                               op->send_initial_metadata_flags,
-                               &calld->connected_subchannel, &calld->next_step,
-                               GRPC_ERROR_NONE)) {
-      calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
+    if (pick_subchannel_locked(
+            exec_ctx, elem,
+            op->payload->send_initial_metadata.send_initial_metadata,
+            op->payload->send_initial_metadata.send_initial_metadata_flags,
+            &calld->connected_subchannel, calld->subchannel_call_context,
+            &calld->next_step)) {
+      calld->pick_pending = false;
       GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel");
     } else {
       grpc_polling_entity_add_to_pollset_set(exec_ctx, calld->pollent,
@@ -979,22 +1186,27 @@ static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx,
     }
   }
   /* if we've got a subchannel, then let's ask it to create a call */
-  if (calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING &&
-      calld->connected_subchannel != NULL) {
+  if (!calld->pick_pending && calld->connected_subchannel != NULL) {
     grpc_subchannel_call *subchannel_call = NULL;
+    const grpc_connected_subchannel_call_args call_args = {
+        .pollent = calld->pollent,
+        .path = calld->path,
+        .start_time = calld->call_start_time,
+        .deadline = calld->deadline,
+        .arena = calld->arena,
+        .context = calld->subchannel_call_context};
     grpc_error *error = grpc_connected_subchannel_create_call(
-        exec_ctx, calld->connected_subchannel, calld->pollent, calld->path,
-        calld->call_start_time, calld->deadline, &subchannel_call);
+        exec_ctx, calld->connected_subchannel, &call_args, &subchannel_call);
+    gpr_atm_rel_store(&calld->subchannel_call,
+                      (gpr_atm)(uintptr_t)subchannel_call);
     if (error != GRPC_ERROR_NONE) {
-      subchannel_call = CANCELLED_CALL;
       fail_locked(exec_ctx, calld, GRPC_ERROR_REF(error));
-      grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error);
+      grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, op, error);
+    } else {
+      retry_waiting_locked(exec_ctx, calld);
+      /* recurse to retry */
+      start_transport_stream_op_batch_locked_inner(exec_ctx, op, elem);
     }
-    gpr_atm_rel_store(&calld->subchannel_call,
-                      (gpr_atm)(uintptr_t)subchannel_call);
-    retry_waiting_locked(exec_ctx, calld);
-    /* recurse to retry */
-    start_transport_stream_op_locked_inner(exec_ctx, op, elem);
     /* early out */
     return;
   }
@@ -1002,19 +1214,48 @@ static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx,
   add_waiting_locked(calld, op);
 }
 
-static void start_transport_stream_op_locked(grpc_exec_ctx *exec_ctx, void *arg,
-                                             grpc_error *error_ignored) {
-  GPR_TIMER_BEGIN("start_transport_stream_op_locked", 0);
+static void on_complete(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+  grpc_call_element *elem = arg;
+  call_data *calld = elem->call_data;
+  if (calld->retry_throttle_data != NULL) {
+    if (error == GRPC_ERROR_NONE) {
+      grpc_server_retry_throttle_data_record_success(
+          calld->retry_throttle_data);
+    } else {
+      // TODO(roth): In a subsequent PR, check the return value here and
+      // decide whether or not to retry.  Note that we should only
+      // record failures whose statuses match the configured retryable
+      // or non-fatal status codes.
+      grpc_server_retry_throttle_data_record_failure(
+          calld->retry_throttle_data);
+    }
+  }
+  grpc_closure_run(exec_ctx, calld->original_on_complete,
+                   GRPC_ERROR_REF(error));
+}
+
+static void start_transport_stream_op_batch_locked(grpc_exec_ctx *exec_ctx,
+                                                   void *arg,
+                                                   grpc_error *error_ignored) {
+  GPR_TIMER_BEGIN("start_transport_stream_op_batch_locked", 0);
 
-  grpc_transport_stream_op *op = arg;
-  grpc_call_element *elem = op->handler_private.args[0];
+  grpc_transport_stream_op_batch *op = arg;
+  grpc_call_element *elem = op->handler_private.extra_arg;
   call_data *calld = elem->call_data;
 
-  start_transport_stream_op_locked_inner(exec_ctx, op, elem);
+  if (op->recv_trailing_metadata) {
+    GPR_ASSERT(op->on_complete != NULL);
+    calld->original_on_complete = op->on_complete;
+    grpc_closure_init(&calld->on_complete, on_complete, elem,
+                      grpc_schedule_on_exec_ctx);
+    op->on_complete = &calld->on_complete;
+  }
+
+  start_transport_stream_op_batch_locked_inner(exec_ctx, op, elem);
 
   GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call,
-                        "start_transport_stream_op");
-  GPR_TIMER_END("start_transport_stream_op_locked", 0);
+                        "start_transport_stream_op_batch");
+  GPR_TIMER_END("start_transport_stream_op_batch_locked", 0);
 }
 
 /* The logic here is fairly complicated, due to (a) the fact that we
@@ -1025,149 +1266,59 @@ static void start_transport_stream_op_locked(grpc_exec_ctx *exec_ctx, void *arg,
    We use double-checked locking to initially see if initialization has been
    performed. If it has not, we acquire the combiner and perform initialization.
    If it has, we proceed on the fast path. */
-static void cc_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
-                                         grpc_call_element *elem,
-                                         grpc_transport_stream_op *op) {
+static void cc_start_transport_stream_op_batch(
+    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+    grpc_transport_stream_op_batch *op) {
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
   GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
-  grpc_deadline_state_client_start_transport_stream_op(exec_ctx, elem, op);
+  if (chand->deadline_checking_enabled) {
+    grpc_deadline_state_client_start_transport_stream_op_batch(exec_ctx, elem,
+                                                               op);
+  }
   /* try to (atomically) get the call */
   grpc_subchannel_call *call = GET_CALL(calld);
-  GPR_TIMER_BEGIN("cc_start_transport_stream_op", 0);
+  GPR_TIMER_BEGIN("cc_start_transport_stream_op_batch", 0);
   if (call == CANCELLED_CALL) {
-    grpc_transport_stream_op_finish_with_failure(
+    grpc_transport_stream_op_batch_finish_with_failure(
         exec_ctx, op, GRPC_ERROR_REF(calld->cancel_error));
-    GPR_TIMER_END("cc_start_transport_stream_op", 0);
+    GPR_TIMER_END("cc_start_transport_stream_op_batch", 0);
     /* early out */
     return;
   }
   if (call != NULL) {
     grpc_subchannel_call_process_op(exec_ctx, call, op);
-    GPR_TIMER_END("cc_start_transport_stream_op", 0);
+    GPR_TIMER_END("cc_start_transport_stream_op_batch", 0);
     /* early out */
     return;
   }
   /* we failed; lock and figure out what to do */
-  GRPC_CALL_STACK_REF(calld->owning_call, "start_transport_stream_op");
-  op->handler_private.args[0] = elem;
+  GRPC_CALL_STACK_REF(calld->owning_call, "start_transport_stream_op_batch");
+  op->handler_private.extra_arg = elem;
   grpc_closure_sched(
       exec_ctx,
       grpc_closure_init(&op->handler_private.closure,
-                        start_transport_stream_op_locked, op,
+                        start_transport_stream_op_batch_locked, op,
                         grpc_combiner_scheduler(chand->combiner, false)),
       GRPC_ERROR_NONE);
-  GPR_TIMER_END("cc_start_transport_stream_op", 0);
-}
-
-// Sets calld->method_params.
-// If the method params specify a timeout, populates
-// *per_method_deadline and returns true.
-static bool set_call_method_params_from_service_config_locked(
-    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-    gpr_timespec *per_method_deadline) {
-  channel_data *chand = elem->channel_data;
-  call_data *calld = elem->call_data;
-  if (chand->method_params_table != NULL) {
-    calld->method_params = grpc_method_config_table_get(
-        exec_ctx, chand->method_params_table, calld->path);
-    if (calld->method_params != NULL) {
-      method_parameters_ref(calld->method_params);
-      if (gpr_time_cmp(calld->method_params->timeout,
-                       gpr_time_0(GPR_TIMESPAN)) != 0) {
-        *per_method_deadline =
-            gpr_time_add(calld->call_start_time, calld->method_params->timeout);
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-// Gets data from the service config.  Invoked when the resolver returns
-// its initial result.
-static void read_service_config_locked(grpc_exec_ctx *exec_ctx, void *arg,
-                                       grpc_error *error) {
-  grpc_call_element *elem = arg;
-  call_data *calld = elem->call_data;
-  // If this is an error, there's no point in looking at the service config.
-  if (error == GRPC_ERROR_NONE) {
-    gpr_timespec per_method_deadline;
-    if (set_call_method_params_from_service_config_locked(
-            exec_ctx, elem, &per_method_deadline)) {
-      // If the deadline from the service config is shorter than the one
-      // from the client API, reset the deadline timer.
-      if (gpr_time_cmp(per_method_deadline, calld->deadline) < 0) {
-        calld->deadline = per_method_deadline;
-        grpc_deadline_state_reset(exec_ctx, elem, calld->deadline);
-      }
-    }
-  }
-  GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "read_service_config");
-}
-
-static void initial_read_service_config_locked(grpc_exec_ctx *exec_ctx,
-                                               void *arg,
-                                               grpc_error *error_ignored) {
-  grpc_call_element *elem = arg;
-  channel_data *chand = elem->channel_data;
-  call_data *calld = elem->call_data;
-  // If the resolver has already returned results, then we can access
-  // the service config parameters immediately.  Otherwise, we need to
-  // defer that work until the resolver returns an initial result.
-  if (chand->lb_policy != NULL) {
-    // We already have a resolver result, so check for service config.
-    gpr_timespec per_method_deadline;
-    if (set_call_method_params_from_service_config_locked(
-            exec_ctx, elem, &per_method_deadline)) {
-      calld->deadline = gpr_time_min(calld->deadline, per_method_deadline);
-    }
-  } else {
-    // We don't yet have a resolver result, so register a callback to
-    // get the service config data once the resolver returns.
-    // Take a reference to the call stack to be owned by the callback.
-    GRPC_CALL_STACK_REF(calld->owning_call, "read_service_config");
-    grpc_closure_init(&calld->read_service_config, read_service_config_locked,
-                      elem, grpc_combiner_scheduler(chand->combiner, false));
-    grpc_closure_list_append(&chand->waiting_for_config_closures,
-                             &calld->read_service_config, GRPC_ERROR_NONE);
-  }
-  // Start the deadline timer with the current deadline value.  If we
-  // do not yet have service config data, then the timer may be reset
-  // later.
-  grpc_deadline_state_start(exec_ctx, elem, calld->deadline);
-  GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call,
-                        "initial_read_service_config");
+  GPR_TIMER_END("cc_start_transport_stream_op_batch", 0);
 }
 
 /* Constructor for call_data */
 static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_call_element *elem,
                                      const grpc_call_element_args *args) {
-  channel_data *chand = elem->channel_data;
   call_data *calld = elem->call_data;
+  channel_data *chand = elem->channel_data;
   // Initialize data members.
-  grpc_deadline_state_init(exec_ctx, elem, args->call_stack);
   calld->path = grpc_slice_ref_internal(args->path);
   calld->call_start_time = args->start_time;
   calld->deadline = gpr_convert_clock_type(args->deadline, GPR_CLOCK_MONOTONIC);
-  calld->method_params = NULL;
-  calld->cancel_error = GRPC_ERROR_NONE;
-  gpr_atm_rel_store(&calld->subchannel_call, 0);
-  calld->connected_subchannel = NULL;
-  calld->waiting_ops = NULL;
-  calld->waiting_ops_count = 0;
-  calld->waiting_ops_capacity = 0;
-  calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
   calld->owning_call = args->call_stack;
-  calld->pollent = NULL;
-  GRPC_CALL_STACK_REF(calld->owning_call, "initial_read_service_config");
-  grpc_closure_sched(
-      exec_ctx,
-      grpc_closure_init(&calld->read_service_config,
-                        initial_read_service_config_locked, elem,
-                        grpc_combiner_scheduler(chand->combiner, false)),
-      GRPC_ERROR_NONE);
+  calld->arena = args->arena;
+  if (chand->deadline_checking_enabled) {
+    grpc_deadline_state_init(exec_ctx, elem, args->call_stack, calld->deadline);
+  }
   return GRPC_ERROR_NONE;
 }
 
@@ -1175,9 +1326,12 @@ static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
 static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
                                  grpc_call_element *elem,
                                  const grpc_call_final_info *final_info,
-                                 void *and_free_memory) {
+                                 grpc_closure *then_schedule_closure) {
   call_data *calld = elem->call_data;
-  grpc_deadline_state_destroy(exec_ctx, elem);
+  channel_data *chand = elem->channel_data;
+  if (chand->deadline_checking_enabled) {
+    grpc_deadline_state_destroy(exec_ctx, elem);
+  }
   grpc_slice_unref_internal(exec_ctx, calld->path);
   if (calld->method_params != NULL) {
     method_parameters_unref(calld->method_params);
@@ -1185,16 +1339,24 @@ static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
   GRPC_ERROR_UNREF(calld->cancel_error);
   grpc_subchannel_call *call = GET_CALL(calld);
   if (call != NULL && call != CANCELLED_CALL) {
+    grpc_subchannel_call_set_cleanup_closure(call, then_schedule_closure);
+    then_schedule_closure = NULL;
     GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "client_channel_destroy_call");
   }
-  GPR_ASSERT(calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING);
+  GPR_ASSERT(!calld->pick_pending);
   GPR_ASSERT(calld->waiting_ops_count == 0);
   if (calld->connected_subchannel != NULL) {
     GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, calld->connected_subchannel,
                                     "picked");
   }
+  for (size_t i = 0; i < GRPC_CONTEXT_COUNT; ++i) {
+    if (calld->subchannel_call_context[i].value != NULL) {
+      calld->subchannel_call_context[i].destroy(
+          calld->subchannel_call_context[i].value);
+    }
+  }
   gpr_free(calld->waiting_ops);
-  gpr_free(and_free_memory);
+  grpc_closure_sched(exec_ctx, then_schedule_closure, GRPC_ERROR_NONE);
 }
 
 static void cc_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
@@ -1209,7 +1371,7 @@ static void cc_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
  */
 
 const grpc_channel_filter grpc_client_channel_filter = {
-    cc_start_transport_stream_op,
+    cc_start_transport_stream_op_batch,
     cc_start_transport_op,
     sizeof(call_data),
     cc_init_call_elem,
@@ -1288,12 +1450,12 @@ static void watch_connectivity_state_locked(grpc_exec_ctx *exec_ctx, void *arg,
 
 void grpc_client_channel_watch_connectivity_state(
     grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_pollset *pollset,
-    grpc_connectivity_state *state, grpc_closure *on_complete) {
+    grpc_connectivity_state *state, grpc_closure *closure) {
   channel_data *chand = elem->channel_data;
   external_connectivity_watcher *w = gpr_malloc(sizeof(*w));
   w->chand = chand;
   w->pollset = pollset;
-  w->on_complete = on_complete;
+  w->on_complete = closure;
   w->state = state;
   grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties, pollset);
   GRPC_CHANNEL_STACK_REF(w->chand->owning_stack,
diff --git a/src/core/ext/client_channel/client_channel.h b/src/core/ext/filters/client_channel/client_channel.h
similarity index 88%
rename from src/core/ext/client_channel/client_channel.h
rename to src/core/ext/filters/client_channel/client_channel.h
index 5e6e64e58bc1ea7722702fc1c69b21a4339d7a8f..8d2490ea55d7be7d60da68e86d3c23ea1fcd9f82 100644
--- a/src/core/ext/client_channel/client_channel.h
+++ b/src/core/ext/filters/client_channel/client_channel.h
@@ -31,11 +31,11 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_CLIENT_CHANNEL_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_CLIENT_CHANNEL_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_H
 
-#include "src/core/ext/client_channel/client_channel_factory.h"
-#include "src/core/ext/client_channel/resolver.h"
+#include "src/core/ext/filters/client_channel/client_channel_factory.h"
+#include "src/core/ext/filters/client_channel/resolver.h"
 #include "src/core/lib/channel/channel_stack.h"
 
 // Channel arg key for server URI string.
@@ -61,4 +61,4 @@ void grpc_client_channel_watch_connectivity_state(
 grpc_subchannel_call *grpc_client_channel_get_subchannel_call(
     grpc_call_element *elem);
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_CLIENT_CHANNEL_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_H */
diff --git a/src/core/ext/client_channel/client_channel_factory.c b/src/core/ext/filters/client_channel/client_channel_factory.c
similarity index 97%
rename from src/core/ext/client_channel/client_channel_factory.c
rename to src/core/ext/filters/client_channel/client_channel_factory.c
index d2707a155668de891a765eca024198fc26cb1553..44e83b54b57a6fc09a0a3ad80e864ba89d906071 100644
--- a/src/core/ext/client_channel/client_channel_factory.c
+++ b/src/core/ext/filters/client_channel/client_channel_factory.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/ext/client_channel/client_channel_factory.h"
+#include "src/core/ext/filters/client_channel/client_channel_factory.h"
 
 void grpc_client_channel_factory_ref(grpc_client_channel_factory* factory) {
   factory->vtable->ref(factory);
diff --git a/src/core/ext/client_channel/client_channel_factory.h b/src/core/ext/filters/client_channel/client_channel_factory.h
similarity index 93%
rename from src/core/ext/client_channel/client_channel_factory.h
rename to src/core/ext/filters/client_channel/client_channel_factory.h
index bf2764b5370f8d2e0b2540a4580145aaf9f47923..2355588f1876d6f20dcf18b63ef98d90f9fefa86 100644
--- a/src/core/ext/client_channel/client_channel_factory.h
+++ b/src/core/ext/filters/client_channel/client_channel_factory.h
@@ -31,12 +31,12 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_CLIENT_CHANNEL_FACTORY_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_CLIENT_CHANNEL_FACTORY_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_FACTORY_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_FACTORY_H
 
 #include <grpc/impl/codegen/grpc_types.h>
 
-#include "src/core/ext/client_channel/subchannel.h"
+#include "src/core/ext/filters/client_channel/subchannel.h"
 #include "src/core/lib/channel/channel_stack.h"
 
 // Channel arg key for client channel factory.
@@ -89,4 +89,4 @@ grpc_channel *grpc_client_channel_factory_create_channel(
 grpc_arg grpc_client_channel_factory_create_channel_arg(
     grpc_client_channel_factory *factory);
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_CLIENT_CHANNEL_FACTORY_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_FACTORY_H */
diff --git a/src/core/ext/client_channel/client_channel_plugin.c b/src/core/ext/filters/client_channel/client_channel_plugin.c
similarity index 80%
rename from src/core/ext/client_channel/client_channel_plugin.c
rename to src/core/ext/filters/client_channel/client_channel_plugin.c
index 6f9df3e386e379bd0d4999aa5f6a4ea35de11f64..0e3eae6615a2dadd042e7fd69430a691f575d073 100644
--- a/src/core/ext/client_channel/client_channel_plugin.c
+++ b/src/core/ext/filters/client_channel/client_channel_plugin.c
@@ -31,19 +31,22 @@
  *
  */
 
+#include <grpc/support/port_platform.h>
+
 #include <limits.h>
 #include <stdbool.h>
 #include <string.h>
 
 #include <grpc/support/alloc.h>
 
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/client_channel/http_connect_handshaker.h"
-#include "src/core/ext/client_channel/http_proxy.h"
-#include "src/core/ext/client_channel/lb_policy_registry.h"
-#include "src/core/ext/client_channel/proxy_mapper_registry.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
-#include "src/core/ext/client_channel/subchannel_index.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
+#include "src/core/ext/filters/client_channel/http_proxy.h"
+#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/retry_throttle.h"
+#include "src/core/ext/filters/client_channel/subchannel_index.h"
 #include "src/core/lib/surface/channel_init.h"
 
 static bool append_filter(grpc_exec_ctx *exec_ctx,
@@ -64,7 +67,7 @@ static bool set_default_host_if_unset(grpc_exec_ctx *exec_ctx,
     }
   }
   char *default_authority = grpc_get_default_authority(
-      grpc_channel_stack_builder_get_target(builder));
+      exec_ctx, grpc_channel_stack_builder_get_target(builder));
   if (default_authority != NULL) {
     grpc_arg arg;
     arg.type = GRPC_ARG_STRING;
@@ -82,13 +85,15 @@ static bool set_default_host_if_unset(grpc_exec_ctx *exec_ctx,
 void grpc_client_channel_init(void) {
   grpc_lb_policy_registry_init();
   grpc_resolver_registry_init();
+  grpc_retry_throttle_map_init();
   grpc_proxy_mapper_registry_init();
   grpc_register_http_proxy_mapper();
   grpc_subchannel_index_init();
   grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MIN,
                                    set_default_host_if_unset, NULL);
-  grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, append_filter,
-                                   (void *)&grpc_client_channel_filter);
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, append_filter,
+      (void *)&grpc_client_channel_filter);
   grpc_http_connect_register_handshaker_factory();
 }
 
@@ -96,6 +101,7 @@ void grpc_client_channel_shutdown(void) {
   grpc_subchannel_index_shutdown();
   grpc_channel_init_shutdown();
   grpc_proxy_mapper_registry_shutdown();
+  grpc_retry_throttle_map_shutdown();
   grpc_resolver_registry_shutdown();
   grpc_lb_policy_registry_shutdown();
 }
diff --git a/src/core/ext/client_channel/connector.c b/src/core/ext/filters/client_channel/connector.c
similarity index 97%
rename from src/core/ext/client_channel/connector.c
rename to src/core/ext/filters/client_channel/connector.c
index 7a720fd1bd22063e8cce685c4238aeb957f0d5df..51c1d7ece7f20bff755c1a89d7ff79574e3da38f 100644
--- a/src/core/ext/client_channel/connector.c
+++ b/src/core/ext/filters/client_channel/connector.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/ext/client_channel/connector.h"
+#include "src/core/ext/filters/client_channel/connector.h"
 
 grpc_connector* grpc_connector_ref(grpc_connector* connector) {
   connector->vtable->ref(connector);
diff --git a/src/core/ext/client_channel/connector.h b/src/core/ext/filters/client_channel/connector.h
similarity index 93%
rename from src/core/ext/client_channel/connector.h
rename to src/core/ext/filters/client_channel/connector.h
index 9bff41f003f8795ac2e084579e6ef3cf959c8631..23040c3e234eb0712c8a067165c71177f982de77 100644
--- a/src/core/ext/client_channel/connector.h
+++ b/src/core/ext/filters/client_channel/connector.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_CONNECTOR_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_CONNECTOR_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONNECTOR_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONNECTOR_H
 
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/iomgr/resolve_address.h"
@@ -48,8 +48,6 @@ struct grpc_connector {
 typedef struct {
   /** set of pollsets interested in this connection */
   grpc_pollset_set *interested_parties;
-  /** initial connect string to send */
-  grpc_slice initial_connect_string;
   /** deadline for connection */
   gpr_timespec deadline;
   /** channel arguments (to be passed to transport) */
@@ -87,4 +85,4 @@ void grpc_connector_connect(grpc_exec_ctx *exec_ctx, grpc_connector *connector,
 void grpc_connector_shutdown(grpc_exec_ctx *exec_ctx, grpc_connector *connector,
                              grpc_error *why);
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_CONNECTOR_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONNECTOR_H */
diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/filters/client_channel/http_connect_handshaker.c
similarity index 97%
rename from src/core/ext/client_channel/http_connect_handshaker.c
rename to src/core/ext/filters/client_channel/http_connect_handshaker.c
index 58ab233f1b8e89b8af55e8265d8f4d93838c8e6c..c09a863d00832c28e04f69777a5da0879bc7af66 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.c
+++ b/src/core/ext/filters/client_channel/http_connect_handshaker.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/ext/client_channel/http_connect_handshaker.h"
+#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
 
 #include <string.h>
 
@@ -40,9 +40,9 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
-#include "src/core/ext/client_channel/uri_parser.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/uri_parser.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/handshaker_registry.h"
 #include "src/core/lib/http/format_request.h"
@@ -116,7 +116,7 @@ static void handshake_failed_locked(grpc_exec_ctx* exec_ctx,
     // If we were shut down after an endpoint operation succeeded but
     // before the endpoint callback was invoked, we need to generate our
     // own error.
-    error = GRPC_ERROR_CREATE("Handshaker shutdown");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshaker shutdown");
   }
   if (!handshaker->shutdown) {
     // TODO(ctiller): It is currently necessary to shutdown endpoints
@@ -226,7 +226,7 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
     char* msg;
     gpr_asprintf(&msg, "HTTP proxy returned response code %d",
                  handshaker->http_response.status);
-    error = GRPC_ERROR_CREATE(msg);
+    error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     handshake_failed_locked(exec_ctx, handshaker, error);
     goto done;
diff --git a/src/core/ext/client_channel/http_connect_handshaker.h b/src/core/ext/filters/client_channel/http_connect_handshaker.h
similarity index 90%
rename from src/core/ext/client_channel/http_connect_handshaker.h
rename to src/core/ext/filters/client_channel/http_connect_handshaker.h
index 3059d551e34391a027b8c032c58ec017caf23fa7..6d7c204d71c34e66151322f8cc6ed2a66ed8b821 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.h
+++ b/src/core/ext/filters/client_channel/http_connect_handshaker.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_CONNECT_HANDSHAKER_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_CONNECT_HANDSHAKER_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HTTP_CONNECT_HANDSHAKER_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HTTP_CONNECT_HANDSHAKER_H
 
 /// Channel arg indicating the server in HTTP CONNECT request (string).
 /// The presence of this arg triggers the use of HTTP CONNECT.
@@ -46,4 +46,4 @@
 /// Registers handshaker factory.
 void grpc_http_connect_register_handshaker_factory();
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_CONNECT_HANDSHAKER_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HTTP_CONNECT_HANDSHAKER_H */
diff --git a/src/core/ext/client_channel/http_proxy.c b/src/core/ext/filters/client_channel/http_proxy.c
similarity index 88%
rename from src/core/ext/client_channel/http_proxy.c
rename to src/core/ext/filters/client_channel/http_proxy.c
index bbe4ff550c6539dc4d9f9c4ebc9cc4a6abb32d5f..f8a2d06b8a8f3af72a7aebbb715e7ac3cfd9689a 100644
--- a/src/core/ext/client_channel/http_proxy.c
+++ b/src/core/ext/filters/client_channel/http_proxy.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/ext/client_channel/http_proxy.h"
+#include "src/core/ext/filters/client_channel/http_proxy.h"
 
 #include <stdbool.h>
 #include <string.h>
@@ -40,16 +40,17 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/ext/client_channel/http_connect_handshaker.h"
-#include "src/core/ext/client_channel/proxy_mapper_registry.h"
-#include "src/core/ext/client_channel/uri_parser.h"
+#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
+#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
+#include "src/core/ext/filters/client_channel/uri_parser.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/support/env.h"
 
-static char* grpc_get_http_proxy_server() {
+static char* grpc_get_http_proxy_server(grpc_exec_ctx* exec_ctx) {
   char* uri_str = gpr_getenv("http_proxy");
   if (uri_str == NULL) return NULL;
-  grpc_uri* uri = grpc_uri_parse(uri_str, false /* suppress_errors */);
+  grpc_uri* uri =
+      grpc_uri_parse(exec_ctx, uri_str, false /* suppress_errors */);
   char* proxy_name = NULL;
   if (uri == NULL || uri->authority == NULL) {
     gpr_log(GPR_ERROR, "cannot parse value of 'http_proxy' env var");
@@ -76,9 +77,10 @@ static bool proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
                                   const grpc_channel_args* args,
                                   char** name_to_resolve,
                                   grpc_channel_args** new_args) {
-  *name_to_resolve = grpc_get_http_proxy_server();
+  *name_to_resolve = grpc_get_http_proxy_server(exec_ctx);
   if (*name_to_resolve == NULL) return false;
-  grpc_uri* uri = grpc_uri_parse(server_uri, false /* suppress_errors */);
+  grpc_uri* uri =
+      grpc_uri_parse(exec_ctx, server_uri, false /* suppress_errors */);
   if (uri == NULL || uri->path[0] == '\0') {
     gpr_log(GPR_ERROR,
             "'http_proxy' environment variable set, but cannot "
diff --git a/src/core/ext/client_channel/http_proxy.h b/src/core/ext/filters/client_channel/http_proxy.h
similarity index 90%
rename from src/core/ext/client_channel/http_proxy.h
rename to src/core/ext/filters/client_channel/http_proxy.h
index c8882b1ef183955c5322fe7f765e610ab59b065d..f0df74bbda2b12432cfbda2da15ba0f99f793c35 100644
--- a/src/core/ext/client_channel/http_proxy.h
+++ b/src/core/ext/filters/client_channel/http_proxy.h
@@ -31,9 +31,9 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_PROXY_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_PROXY_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HTTP_PROXY_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HTTP_PROXY_H
 
 void grpc_register_http_proxy_mapper();
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_PROXY_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HTTP_PROXY_H */
diff --git a/src/core/ext/client_channel/lb_policy.c b/src/core/ext/filters/client_channel/lb_policy.c
similarity index 97%
rename from src/core/ext/client_channel/lb_policy.c
rename to src/core/ext/filters/client_channel/lb_policy.c
index aba51add53c73999eaa5ba36ede40b14012fbe40..112ba406581efc5b76c32b4beee970452d7a7aec 100644
--- a/src/core/ext/client_channel/lb_policy.c
+++ b/src/core/ext/filters/client_channel/lb_policy.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/ext/client_channel/lb_policy.h"
+#include "src/core/ext/filters/client_channel/lb_policy.h"
 #include "src/core/lib/iomgr/combiner.h"
 
 #define WEAK_REF_BITS 16
@@ -119,9 +119,10 @@ void grpc_lb_policy_weak_unref(grpc_exec_ctx *exec_ctx,
 int grpc_lb_policy_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
                                const grpc_lb_policy_pick_args *pick_args,
                                grpc_connected_subchannel **target,
+                               grpc_call_context_element *context,
                                void **user_data, grpc_closure *on_complete) {
   return policy->vtable->pick_locked(exec_ctx, policy, pick_args, target,
-                                     user_data, on_complete);
+                                     context, user_data, on_complete);
 }
 
 void grpc_lb_policy_cancel_pick_locked(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/ext/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h
similarity index 94%
rename from src/core/ext/client_channel/lb_policy.h
rename to src/core/ext/filters/client_channel/lb_policy.h
index 3405709c2cf10118fae53f5c7a6e20e98072eee9..184b2ef720c2453ad91ef311d4b21b804f9d3adb 100644
--- a/src/core/ext/client_channel/lb_policy.h
+++ b/src/core/ext/filters/client_channel/lb_policy.h
@@ -31,10 +31,10 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_LB_POLICY_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_LB_POLICY_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_H
 
-#include "src/core/ext/client_channel/subchannel.h"
+#include "src/core/ext/filters/client_channel/subchannel.h"
 #include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/transport/connectivity_state.h"
 
@@ -43,9 +43,6 @@
 typedef struct grpc_lb_policy grpc_lb_policy;
 typedef struct grpc_lb_policy_vtable grpc_lb_policy_vtable;
 
-typedef void (*grpc_lb_completion)(void *cb_arg, grpc_subchannel *subchannel,
-                                   grpc_status_code status, const char *errmsg);
-
 struct grpc_lb_policy {
   const grpc_lb_policy_vtable *vtable;
   gpr_atm ref_pair;
@@ -65,8 +62,6 @@ typedef struct grpc_lb_policy_pick_args {
   uint32_t initial_metadata_flags;
   /** Storage for LB token in \a initial_metadata, or NULL if not used */
   grpc_linked_mdelem *lb_token_mdelem_storage;
-  /** Deadline for the call to the LB server */
-  gpr_timespec deadline;
 } grpc_lb_policy_pick_args;
 
 struct grpc_lb_policy_vtable {
@@ -76,7 +71,8 @@ struct grpc_lb_policy_vtable {
   /** \see grpc_lb_policy_pick */
   int (*pick_locked)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
                      const grpc_lb_policy_pick_args *pick_args,
-                     grpc_connected_subchannel **target, void **user_data,
+                     grpc_connected_subchannel **target,
+                     grpc_call_context_element *context, void **user_data,
                      grpc_closure *on_complete);
 
   /** \see grpc_lb_policy_cancel_pick */
@@ -156,6 +152,8 @@ void grpc_lb_policy_init(grpc_lb_policy *policy,
     \a target will be set to the selected subchannel, or NULL on failure.
     Upon success, \a user_data will be set to whatever opaque information
     may need to be propagated from the LB policy, or NULL if not needed.
+    \a context will be populated with context to pass to the subchannel
+    call, if needed.
 
     If the pick succeeds and a result is known immediately, a non-zero
     value will be returned.  Otherwise, \a on_complete will be invoked
@@ -167,6 +165,7 @@ void grpc_lb_policy_init(grpc_lb_policy *policy,
 int grpc_lb_policy_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
                                const grpc_lb_policy_pick_args *pick_args,
                                grpc_connected_subchannel **target,
+                               grpc_call_context_element *context,
                                void **user_data, grpc_closure *on_complete);
 
 /** Perform a connected subchannel ping (see \a grpc_connected_subchannel_ping)
@@ -206,4 +205,4 @@ grpc_connectivity_state grpc_lb_policy_check_connectivity_locked(
     grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
     grpc_error **connectivity_error);
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_LB_POLICY_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_H */
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c b/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c
new file mode 100644
index 0000000000000000000000000000000000000000..67baa46de71aa11bbf714633152620e7ac05e7b2
--- /dev/null
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c
@@ -0,0 +1,153 @@
+/*
+ *
+ * Copyright 2017, 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/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h"
+
+#include <grpc/support/atm.h>
+#include <grpc/support/log.h>
+
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h"
+#include "src/core/lib/iomgr/error.h"
+#include "src/core/lib/profiling/timers.h"
+
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
+                                     grpc_channel_element *elem,
+                                     grpc_channel_element_args *args) {
+  return GRPC_ERROR_NONE;
+}
+
+static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
+                                 grpc_channel_element *elem) {}
+
+typedef struct {
+  // Stats object to update.
+  grpc_grpclb_client_stats *client_stats;
+  // State for intercepting send_initial_metadata.
+  grpc_closure on_complete_for_send;
+  grpc_closure *original_on_complete_for_send;
+  bool send_initial_metadata_succeeded;
+  // State for intercepting recv_initial_metadata.
+  grpc_closure recv_initial_metadata_ready;
+  grpc_closure *original_recv_initial_metadata_ready;
+  bool recv_initial_metadata_succeeded;
+} call_data;
+
+static void on_complete_for_send(grpc_exec_ctx *exec_ctx, void *arg,
+                                 grpc_error *error) {
+  call_data *calld = arg;
+  if (error == GRPC_ERROR_NONE) {
+    calld->send_initial_metadata_succeeded = true;
+  }
+  grpc_closure_run(exec_ctx, calld->original_on_complete_for_send,
+                   GRPC_ERROR_REF(error));
+}
+
+static void recv_initial_metadata_ready(grpc_exec_ctx *exec_ctx, void *arg,
+                                        grpc_error *error) {
+  call_data *calld = arg;
+  if (error == GRPC_ERROR_NONE) {
+    calld->recv_initial_metadata_succeeded = true;
+  }
+  grpc_closure_run(exec_ctx, calld->original_recv_initial_metadata_ready,
+                   GRPC_ERROR_REF(error));
+}
+
+static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
+                                  grpc_call_element *elem,
+                                  const grpc_call_element_args *args) {
+  call_data *calld = elem->call_data;
+  // Get stats object from context and take a ref.
+  GPR_ASSERT(args->context != NULL);
+  GPR_ASSERT(args->context[GRPC_GRPCLB_CLIENT_STATS].value != NULL);
+  calld->client_stats = grpc_grpclb_client_stats_ref(
+      args->context[GRPC_GRPCLB_CLIENT_STATS].value);
+  // Record call started.
+  grpc_grpclb_client_stats_add_call_started(calld->client_stats);
+  return GRPC_ERROR_NONE;
+}
+
+static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+                              const grpc_call_final_info *final_info,
+                              grpc_closure *ignored) {
+  call_data *calld = elem->call_data;
+  // Record call finished, optionally setting client_failed_to_send and
+  // received.
+  grpc_grpclb_client_stats_add_call_finished(
+      false /* drop_for_rate_limiting */, false /* drop_for_load_balancing */,
+      !calld->send_initial_metadata_succeeded /* client_failed_to_send */,
+      calld->recv_initial_metadata_succeeded /* known_received */,
+      calld->client_stats);
+  // All done, so unref the stats object.
+  grpc_grpclb_client_stats_unref(calld->client_stats);
+}
+
+static void start_transport_stream_op_batch(
+    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+    grpc_transport_stream_op_batch *batch) {
+  call_data *calld = elem->call_data;
+  GPR_TIMER_BEGIN("clr_start_transport_stream_op_batch", 0);
+  // Intercept send_initial_metadata.
+  if (batch->send_initial_metadata) {
+    calld->original_on_complete_for_send = batch->on_complete;
+    grpc_closure_init(&calld->on_complete_for_send, on_complete_for_send, calld,
+                      grpc_schedule_on_exec_ctx);
+    batch->on_complete = &calld->on_complete_for_send;
+  }
+  // Intercept recv_initial_metadata.
+  if (batch->recv_initial_metadata) {
+    calld->original_recv_initial_metadata_ready =
+        batch->payload->recv_initial_metadata.recv_initial_metadata_ready;
+    grpc_closure_init(&calld->recv_initial_metadata_ready,
+                      recv_initial_metadata_ready, calld,
+                      grpc_schedule_on_exec_ctx);
+    batch->payload->recv_initial_metadata.recv_initial_metadata_ready =
+        &calld->recv_initial_metadata_ready;
+  }
+  // Chain to next filter.
+  grpc_call_next_op(exec_ctx, elem, batch);
+  GPR_TIMER_END("clr_start_transport_stream_op_batch", 0);
+}
+
+const grpc_channel_filter grpc_client_load_reporting_filter = {
+    start_transport_stream_op_batch,
+    grpc_channel_next_op,
+    sizeof(call_data),
+    init_call_elem,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
+    destroy_call_elem,
+    0,  // sizeof(channel_data)
+    init_channel_elem,
+    destroy_channel_elem,
+    grpc_call_next_get_peer,
+    grpc_channel_next_get_info,
+    "client_load_reporting"};
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h
new file mode 100644
index 0000000000000000000000000000000000000000..28b313d874085338f0ab5be952b7ec4d30a776c6
--- /dev/null
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright 2017, 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_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_CLIENT_LOAD_REPORTING_FILTER_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_CLIENT_LOAD_REPORTING_FILTER_H
+
+#include "src/core/lib/channel/channel_stack.h"
+
+extern const grpc_channel_filter grpc_client_load_reporting_filter;
+
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_CLIENT_LOAD_REPORTING_FILTER_H \
+          */
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
similarity index 76%
rename from src/core/ext/lb_policy/grpclb/grpclb.c
rename to src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
index aea0fcc33d89792ef6f5e7edf0befd06e9142fb2..695be4fdf27ed9867b14a7ebf5a448655bdd6dea 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
@@ -95,8 +95,7 @@
    headers. Therefore, sockaddr.h must always be included first */
 #include "src/core/lib/iomgr/sockaddr.h"
 
-#include <errno.h>
-
+#include <limits.h>
 #include <string.h>
 
 #include <grpc/byte_buffer_reader.h>
@@ -106,15 +105,18 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
 
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/client_channel/client_channel_factory.h"
-#include "src/core/ext/client_channel/lb_policy_factory.h"
-#include "src/core/ext/client_channel/lb_policy_registry.h"
-#include "src/core/ext/client_channel/parse_address.h"
-#include "src/core/ext/lb_policy/grpclb/grpclb.h"
-#include "src/core/ext/lb_policy/grpclb/grpclb_channel.h"
-#include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel_factory.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h"
+#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/parse_address.h"
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/iomgr/combiner.h"
 #include "src/core/lib/iomgr/sockaddr.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -126,6 +128,7 @@
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/surface/channel.h"
+#include "src/core/lib/surface/channel_init.h"
 #include "src/core/lib/transport/static_metadata.h"
 
 #define GRPC_GRPCLB_MIN_CONNECT_TIMEOUT_SECONDS 20
@@ -147,6 +150,10 @@ static grpc_error *initial_metadata_add_lb_token(
                                       lb_token_mdelem_storage, lb_token);
 }
 
+static void destroy_client_stats(void *arg) {
+  grpc_grpclb_client_stats_unref(arg);
+}
+
 typedef struct wrapped_rr_closure_arg {
   /* the closure instance using this struct as argument */
   grpc_closure wrapper_closure;
@@ -163,6 +170,13 @@ typedef struct wrapped_rr_closure_arg {
    * initial metadata */
   grpc_connected_subchannel **target;
 
+  /* the context to be populated for the subchannel call */
+  grpc_call_context_element *context;
+
+  /* Stats for client-side load reporting. Note that this holds a
+   * reference, which must be either passed on via context or unreffed. */
+  grpc_grpclb_client_stats *client_stats;
+
   /* the LB token associated with the pick */
   grpc_mdelem lb_token;
 
@@ -202,6 +216,12 @@ static void wrapped_rr_closure(grpc_exec_ctx *exec_ctx, void *arg,
                 (void *)*wc_arg->target, (void *)wc_arg->rr_policy);
         abort();
       }
+      // Pass on client stats via context. Passes ownership of the reference.
+      GPR_ASSERT(wc_arg->client_stats != NULL);
+      wc_arg->context[GRPC_GRPCLB_CLIENT_STATS].value = wc_arg->client_stats;
+      wc_arg->context[GRPC_GRPCLB_CLIENT_STATS].destroy = destroy_client_stats;
+    } else {
+      grpc_grpclb_client_stats_unref(wc_arg->client_stats);
     }
     if (grpc_lb_glb_trace) {
       gpr_log(GPR_INFO, "Unreffing RR %p", (void *)wc_arg->rr_policy);
@@ -237,6 +257,7 @@ typedef struct pending_pick {
 static void add_pending_pick(pending_pick **root,
                              const grpc_lb_policy_pick_args *pick_args,
                              grpc_connected_subchannel **target,
+                             grpc_call_context_element *context,
                              grpc_closure *on_complete) {
   pending_pick *pp = gpr_zalloc(sizeof(*pp));
   pp->next = *root;
@@ -244,6 +265,7 @@ static void add_pending_pick(pending_pick **root,
   pp->target = target;
   pp->wrapped_on_complete_arg.wrapped_closure = on_complete;
   pp->wrapped_on_complete_arg.target = target;
+  pp->wrapped_on_complete_arg.context = context;
   pp->wrapped_on_complete_arg.initial_metadata = pick_args->initial_metadata;
   pp->wrapped_on_complete_arg.lb_token_mdelem_storage =
       pick_args->lb_token_mdelem_storage;
@@ -287,8 +309,8 @@ typedef struct glb_lb_policy {
   grpc_client_channel_factory *cc_factory;
   grpc_channel_args *args;
 
-  /** deadline for the LB's call */
-  gpr_timespec deadline;
+  /** timeout in milliseconds for the LB call. 0 means no deadline. */
+  int lb_call_timeout_ms;
 
   /** for communicating with the LB server */
   grpc_channel *lb_channel;
@@ -316,6 +338,10 @@ typedef struct glb_lb_policy {
   /************************************************************/
   /*  client data associated with the LB server communication */
   /************************************************************/
+
+  /* Finished sending initial request. */
+  grpc_closure lb_on_sent_initial_request;
+
   /* Status from the LB server has been received. This signals the end of the LB
    * call. */
   grpc_closure lb_on_server_status_received;
@@ -348,6 +374,23 @@ typedef struct glb_lb_policy {
 
   /** LB call retry timer */
   grpc_timer lb_call_retry_timer;
+
+  bool initial_request_sent;
+  bool seen_initial_response;
+
+  /* Stats for client-side load reporting. Should be unreffed and
+   * recreated whenever lb_call is replaced. */
+  grpc_grpclb_client_stats *client_stats;
+  /* Interval and timer for next client load report. */
+  gpr_timespec client_stats_report_interval;
+  grpc_timer client_load_report_timer;
+  bool client_load_report_timer_pending;
+  bool last_client_load_report_counters_were_zero;
+  /* Closure used for either the load report timer or the callback for
+   * completion of sending the load report. */
+  grpc_closure client_load_report_closure;
+  /* Client load report message payload. */
+  grpc_byte_buffer *client_load_report_payload;
 } glb_lb_policy;
 
 /* Keeps track and reacts to changes in connectivity of the RR instance */
@@ -552,8 +595,8 @@ static bool pick_from_internal_rr_locked(
     grpc_connected_subchannel **target, wrapped_rr_closure_arg *wc_arg) {
   GPR_ASSERT(rr_policy != NULL);
   const bool pick_done = grpc_lb_policy_pick_locked(
-      exec_ctx, rr_policy, pick_args, target, (void **)&wc_arg->lb_token,
-      &wc_arg->wrapper_closure);
+      exec_ctx, rr_policy, pick_args, target, wc_arg->context,
+      (void **)&wc_arg->lb_token, &wc_arg->wrapper_closure);
   if (pick_done) {
     /* synchronous grpc_lb_policy_pick call. Unref the RR policy. */
     if (grpc_lb_glb_trace) {
@@ -567,7 +610,12 @@ static bool pick_from_internal_rr_locked(
                                   pick_args->lb_token_mdelem_storage,
                                   GRPC_MDELEM_REF(wc_arg->lb_token));
 
-    gpr_free(wc_arg);
+    // Pass on client stats via context. Passes ownership of the reference.
+    GPR_ASSERT(wc_arg->client_stats != NULL);
+    wc_arg->context[GRPC_GRPCLB_CLIENT_STATS].value = wc_arg->client_stats;
+    wc_arg->context[GRPC_GRPCLB_CLIENT_STATS].destroy = destroy_client_stats;
+
+    gpr_free(wc_arg->free_when_done);
   }
   /* else, the pending pick will be registered and taken care of by the
    * pending pick list inside the RR policy (glb_policy->rr_policy).
@@ -690,6 +738,8 @@ static void rr_handover_locked(grpc_exec_ctx *exec_ctx,
     glb_policy->pending_picks = pp->next;
     GRPC_LB_POLICY_REF(glb_policy->rr_policy, "rr_handover_pending_pick");
     pp->wrapped_on_complete_arg.rr_policy = glb_policy->rr_policy;
+    pp->wrapped_on_complete_arg.client_stats =
+        grpc_grpclb_client_stats_ref(glb_policy->client_stats);
     if (grpc_lb_glb_trace) {
       gpr_log(GPR_INFO, "Pending pick about to PICK from 0x%" PRIxPTR "",
               (intptr_t)glb_policy->rr_policy);
@@ -750,18 +800,11 @@ static void destroy_balancer_name(grpc_exec_ctx *exec_ctx,
   gpr_free(balancer_name);
 }
 
-static void *copy_balancer_name(void *balancer_name) {
-  return gpr_strdup(balancer_name);
-}
-
 static grpc_slice_hash_table_entry targets_info_entry_create(
     const char *address, const char *balancer_name) {
-  static const grpc_slice_hash_table_vtable vtable = {destroy_balancer_name,
-                                                      copy_balancer_name};
   grpc_slice_hash_table_entry entry;
   entry.key = grpc_slice_from_copied_string(address);
-  entry.value = (void *)balancer_name;
-  entry.vtable = &vtable;
+  entry.value = gpr_strdup(balancer_name);
   return entry;
 }
 
@@ -825,11 +868,8 @@ static char *get_lb_uri_target_addresses(grpc_exec_ctx *exec_ctx,
                uri_path);
   gpr_free(uri_path);
 
-  *targets_info =
-      grpc_slice_hash_table_create(num_grpclb_addrs, targets_info_entries);
-  for (size_t i = 0; i < num_grpclb_addrs; i++) {
-    grpc_slice_unref_internal(exec_ctx, targets_info_entries[i].key);
-  }
+  *targets_info = grpc_slice_hash_table_create(
+      num_grpclb_addrs, targets_info_entries, destroy_balancer_name);
   gpr_free(targets_info_entries);
 
   return target_uri_str;
@@ -841,13 +881,15 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
   /* Count the number of gRPC-LB addresses. There must be at least one.
    * TODO(roth): For now, we ignore non-balancer addresses, but in the
    * future, we may change the behavior such that we fall back to using
-   * the non-balancer addresses if we cannot reach any balancers. At that
-   * time, this should be changed to allow a list with no balancer addresses,
-   * since the resolver might fail to return a balancer address even when
-   * this is the right LB policy to use. */
+   * the non-balancer addresses if we cannot reach any balancers. In the
+   * fallback case, we should use the LB policy indicated by
+   * GRPC_ARG_LB_POLICY_NAME (although if that specifies grpclb or is
+   * unset, we should default to pick_first). */
   const grpc_arg *arg =
       grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES);
-  GPR_ASSERT(arg != NULL && arg->type == GRPC_ARG_POINTER);
+  if (arg == NULL || arg->type != GRPC_ARG_POINTER) {
+    return NULL;
+  }
   grpc_lb_addresses *addresses = arg->value.pointer.p;
   size_t num_grpclb_addrs = 0;
   for (size_t i = 0; i < addresses->num_addresses; ++i) {
@@ -861,7 +903,7 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
   arg = grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI);
   GPR_ASSERT(arg != NULL);
   GPR_ASSERT(arg->type == GRPC_ARG_STRING);
-  grpc_uri *uri = grpc_uri_parse(arg->value.string, true);
+  grpc_uri *uri = grpc_uri_parse(exec_ctx, arg->value.string, true);
   GPR_ASSERT(uri->path[0] != '\0');
   glb_policy->server_name =
       gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path);
@@ -872,9 +914,22 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
   grpc_uri_destroy(uri);
 
   glb_policy->cc_factory = args->client_channel_factory;
-  glb_policy->args = grpc_channel_args_copy(args->args);
   GPR_ASSERT(glb_policy->cc_factory != NULL);
 
+  arg = grpc_channel_args_find(args->args, GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS);
+  glb_policy->lb_call_timeout_ms =
+      grpc_channel_arg_get_integer(arg, (grpc_integer_options){0, 0, INT_MAX});
+
+  // Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args,
+  // since we use this to trigger the client_load_reporting filter.
+  grpc_arg new_arg;
+  new_arg.key = GRPC_ARG_LB_POLICY_NAME;
+  new_arg.type = GRPC_ARG_STRING;
+  new_arg.value.string = "grpclb";
+  static const char *args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME};
+  glb_policy->args = grpc_channel_args_copy_and_add_and_remove(
+      args->args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1);
+
   grpc_slice_hash_table *targets_info = NULL;
   /* Create a client channel over them to communicate with a LB service */
   char *lb_service_target_addresses =
@@ -888,6 +943,8 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
   grpc_channel_args_destroy(exec_ctx, lb_channel_args);
   gpr_free(lb_service_target_addresses);
   if (glb_policy->lb_channel == NULL) {
+    gpr_free((void *)glb_policy->server_name);
+    grpc_channel_args_destroy(exec_ctx, glb_policy->args);
     gpr_free(glb_policy);
     return NULL;
   }
@@ -903,6 +960,9 @@ static void glb_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
   GPR_ASSERT(glb_policy->pending_pings == NULL);
   gpr_free((void *)glb_policy->server_name);
   grpc_channel_args_destroy(exec_ctx, glb_policy->args);
+  if (glb_policy->client_stats != NULL) {
+    grpc_grpclb_client_stats_unref(glb_policy->client_stats);
+  }
   grpc_channel_destroy(glb_policy->lb_channel);
   glb_policy->lb_channel = NULL;
   grpc_connectivity_state_destroy(exec_ctx, &glb_policy->state_tracker);
@@ -925,7 +985,7 @@ static void glb_shutdown_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
   }
   grpc_connectivity_state_set(
       exec_ctx, &glb_policy->state_tracker, GRPC_CHANNEL_SHUTDOWN,
-      GRPC_ERROR_CREATE("Channel Shutdown"), "glb_shutdown");
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel Shutdown"), "glb_shutdown");
   /* We need a copy of the lb_call pointer because we can't cancell the call
    * while holding glb_policy->mu: lb_on_server_status_received, invoked due to
    * the cancel, needs to acquire that same lock */
@@ -965,9 +1025,9 @@ static void glb_cancel_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     pending_pick *next = pp->next;
     if (pp->target == target) {
       *target = NULL;
-      grpc_closure_sched(
-          exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
-          GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1));
+      grpc_closure_sched(exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
+                         GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                             "Pick Cancelled", &error, 1));
     } else {
       pp->next = glb_policy->pending_picks;
       glb_policy->pending_picks = pp;
@@ -989,9 +1049,9 @@ static void glb_cancel_picks_locked(grpc_exec_ctx *exec_ctx,
     pending_pick *next = pp->next;
     if ((pp->pick_args.initial_metadata_flags & initial_metadata_flags_mask) ==
         initial_metadata_flags_eq) {
-      grpc_closure_sched(
-          exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
-          GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1));
+      grpc_closure_sched(exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
+                         GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                             "Pick Cancelled", &error, 1));
     } else {
       pp->next = glb_policy->pending_picks;
       glb_policy->pending_picks = pp;
@@ -1019,19 +1079,19 @@ static void glb_exit_idle_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
 
 static int glb_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
                            const grpc_lb_policy_pick_args *pick_args,
-                           grpc_connected_subchannel **target, void **user_data,
+                           grpc_connected_subchannel **target,
+                           grpc_call_context_element *context, void **user_data,
                            grpc_closure *on_complete) {
   if (pick_args->lb_token_mdelem_storage == NULL) {
     *target = NULL;
-    grpc_closure_sched(
-        exec_ctx, on_complete,
-        GRPC_ERROR_CREATE("No mdelem storage for the LB token. Load reporting "
-                          "won't work without it. Failing"));
+    grpc_closure_sched(exec_ctx, on_complete,
+                       GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                           "No mdelem storage for the LB token. Load reporting "
+                           "won't work without it. Failing"));
     return 0;
   }
 
   glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
-  glb_policy->deadline = pick_args->deadline;
   bool pick_done;
 
   if (glb_policy->rr_policy != NULL) {
@@ -1047,6 +1107,10 @@ static int glb_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
                       grpc_schedule_on_exec_ctx);
     wc_arg->rr_policy = glb_policy->rr_policy;
     wc_arg->target = target;
+    wc_arg->context = context;
+    GPR_ASSERT(glb_policy->client_stats != NULL);
+    wc_arg->client_stats =
+        grpc_grpclb_client_stats_ref(glb_policy->client_stats);
     wc_arg->wrapped_closure = on_complete;
     wc_arg->lb_token_mdelem_storage = pick_args->lb_token_mdelem_storage;
     wc_arg->initial_metadata = pick_args->initial_metadata;
@@ -1060,7 +1124,7 @@ static int glb_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
               "picks",
               (void *)(glb_policy));
     }
-    add_pending_pick(&glb_policy->pending_picks, pick_args, target,
+    add_pending_pick(&glb_policy->pending_picks, pick_args, target, context,
                      on_complete);
 
     if (!glb_policy->started_picking) {
@@ -1101,6 +1165,104 @@ static void glb_notify_on_state_change_locked(grpc_exec_ctx *exec_ctx,
       exec_ctx, &glb_policy->state_tracker, current, notify);
 }
 
+static void send_client_load_report_locked(grpc_exec_ctx *exec_ctx, void *arg,
+                                           grpc_error *error);
+
+static void schedule_next_client_load_report(grpc_exec_ctx *exec_ctx,
+                                             glb_lb_policy *glb_policy) {
+  const gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
+  const gpr_timespec next_client_load_report_time =
+      gpr_time_add(now, glb_policy->client_stats_report_interval);
+  grpc_closure_init(&glb_policy->client_load_report_closure,
+                    send_client_load_report_locked, glb_policy,
+                    grpc_combiner_scheduler(glb_policy->base.combiner, false));
+  grpc_timer_init(exec_ctx, &glb_policy->client_load_report_timer,
+                  next_client_load_report_time,
+                  &glb_policy->client_load_report_closure, now);
+}
+
+static void client_load_report_done_locked(grpc_exec_ctx *exec_ctx, void *arg,
+                                           grpc_error *error) {
+  glb_lb_policy *glb_policy = arg;
+  grpc_byte_buffer_destroy(glb_policy->client_load_report_payload);
+  glb_policy->client_load_report_payload = NULL;
+  if (error != GRPC_ERROR_NONE || glb_policy->lb_call == NULL) {
+    glb_policy->client_load_report_timer_pending = false;
+    GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &glb_policy->base,
+                              "client_load_report");
+    return;
+  }
+  schedule_next_client_load_report(exec_ctx, glb_policy);
+}
+
+static void do_send_client_load_report_locked(grpc_exec_ctx *exec_ctx,
+                                              glb_lb_policy *glb_policy) {
+  grpc_op op;
+  memset(&op, 0, sizeof(op));
+  op.op = GRPC_OP_SEND_MESSAGE;
+  op.data.send_message.send_message = glb_policy->client_load_report_payload;
+  grpc_closure_init(&glb_policy->client_load_report_closure,
+                    client_load_report_done_locked, glb_policy,
+                    grpc_combiner_scheduler(glb_policy->base.combiner, false));
+  grpc_call_error call_error = grpc_call_start_batch_and_execute(
+      exec_ctx, glb_policy->lb_call, &op, 1,
+      &glb_policy->client_load_report_closure);
+  GPR_ASSERT(GRPC_CALL_OK == call_error);
+}
+
+static bool load_report_counters_are_zero(grpc_grpclb_request *request) {
+  return request->client_stats.num_calls_started == 0 &&
+         request->client_stats.num_calls_finished == 0 &&
+         request->client_stats.num_calls_finished_with_drop_for_rate_limiting ==
+             0 &&
+         request->client_stats
+                 .num_calls_finished_with_drop_for_load_balancing == 0 &&
+         request->client_stats.num_calls_finished_with_client_failed_to_send ==
+             0 &&
+         request->client_stats.num_calls_finished_known_received == 0;
+}
+
+static void send_client_load_report_locked(grpc_exec_ctx *exec_ctx, void *arg,
+                                           grpc_error *error) {
+  glb_lb_policy *glb_policy = arg;
+  if (error == GRPC_ERROR_CANCELLED || glb_policy->lb_call == NULL) {
+    glb_policy->client_load_report_timer_pending = false;
+    GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &glb_policy->base,
+                              "client_load_report");
+    return;
+  }
+  // Construct message payload.
+  GPR_ASSERT(glb_policy->client_load_report_payload == NULL);
+  grpc_grpclb_request *request =
+      grpc_grpclb_load_report_request_create(glb_policy->client_stats);
+  // Skip client load report if the counters were all zero in the last
+  // report and they are still zero in this one.
+  if (load_report_counters_are_zero(request)) {
+    if (glb_policy->last_client_load_report_counters_were_zero) {
+      grpc_grpclb_request_destroy(request);
+      schedule_next_client_load_report(exec_ctx, glb_policy);
+      return;
+    }
+    glb_policy->last_client_load_report_counters_were_zero = true;
+  } else {
+    glb_policy->last_client_load_report_counters_were_zero = false;
+  }
+  grpc_slice request_payload_slice = grpc_grpclb_request_encode(request);
+  glb_policy->client_load_report_payload =
+      grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+  grpc_slice_unref_internal(exec_ctx, request_payload_slice);
+  grpc_grpclb_request_destroy(request);
+  // If we've already sent the initial request, then we can go ahead and
+  // sent the load report.  Otherwise, we need to wait until the initial
+  // request has been sent to send this
+  // (see lb_on_sent_initial_request_locked() below).
+  if (glb_policy->initial_request_sent) {
+    do_send_client_load_report_locked(exec_ctx, glb_policy);
+  }
+}
+
+static void lb_on_sent_initial_request_locked(grpc_exec_ctx *exec_ctx,
+                                              void *arg, grpc_error *error);
 static void lb_on_server_status_received_locked(grpc_exec_ctx *exec_ctx,
                                                 void *arg, grpc_error *error);
 static void lb_on_response_received_locked(grpc_exec_ctx *exec_ctx, void *arg,
@@ -1115,11 +1277,23 @@ static void lb_call_init_locked(grpc_exec_ctx *exec_ctx,
    * glb_policy->base.interested_parties, which is comprised of the polling
    * entities from \a client_channel. */
   grpc_slice host = grpc_slice_from_copied_string(glb_policy->server_name);
+  gpr_timespec deadline =
+      glb_policy->lb_call_timeout_ms == 0
+          ? gpr_inf_future(GPR_CLOCK_MONOTONIC)
+          : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+                         gpr_time_from_millis(glb_policy->lb_call_timeout_ms,
+                                              GPR_TIMESPAN));
   glb_policy->lb_call = grpc_channel_create_pollset_set_call(
       exec_ctx, glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS,
       glb_policy->base.interested_parties,
       GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD,
-      &host, glb_policy->deadline, NULL);
+      &host, deadline, NULL);
+  grpc_slice_unref_internal(exec_ctx, host);
+
+  if (glb_policy->client_stats != NULL) {
+    grpc_grpclb_client_stats_unref(glb_policy->client_stats);
+  }
+  glb_policy->client_stats = grpc_grpclb_client_stats_create();
 
   grpc_metadata_array_init(&glb_policy->lb_initial_metadata_recv);
   grpc_metadata_array_init(&glb_policy->lb_trailing_metadata_recv);
@@ -1132,6 +1306,9 @@ static void lb_call_init_locked(grpc_exec_ctx *exec_ctx,
   grpc_slice_unref_internal(exec_ctx, request_payload_slice);
   grpc_grpclb_request_destroy(request);
 
+  grpc_closure_init(&glb_policy->lb_on_sent_initial_request,
+                    lb_on_sent_initial_request_locked, glb_policy,
+                    grpc_combiner_scheduler(glb_policy->base.combiner, false));
   grpc_closure_init(&glb_policy->lb_on_server_status_received,
                     lb_on_server_status_received_locked, glb_policy,
                     grpc_combiner_scheduler(glb_policy->base.combiner, false));
@@ -1145,12 +1322,16 @@ static void lb_call_init_locked(grpc_exec_ctx *exec_ctx,
                    GRPC_GRPCLB_RECONNECT_JITTER,
                    GRPC_GRPCLB_MIN_CONNECT_TIMEOUT_SECONDS * 1000,
                    GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS * 1000);
+
+  glb_policy->initial_request_sent = false;
+  glb_policy->seen_initial_response = false;
+  glb_policy->last_client_load_report_counters_were_zero = false;
 }
 
 static void lb_call_destroy_locked(grpc_exec_ctx *exec_ctx,
                                    glb_lb_policy *glb_policy) {
   GPR_ASSERT(glb_policy->lb_call != NULL);
-  grpc_call_destroy(glb_policy->lb_call);
+  grpc_call_unref(glb_policy->lb_call);
   glb_policy->lb_call = NULL;
 
   grpc_metadata_array_destroy(&glb_policy->lb_initial_metadata_recv);
@@ -1158,6 +1339,10 @@ static void lb_call_destroy_locked(grpc_exec_ctx *exec_ctx,
 
   grpc_byte_buffer_destroy(glb_policy->lb_request_payload);
   grpc_slice_unref_internal(exec_ctx, glb_policy->lb_call_status_details);
+
+  if (!glb_policy->client_load_report_timer_pending) {
+    grpc_timer_cancel(exec_ctx, &glb_policy->client_load_report_timer);
+  }
 }
 
 /*
@@ -1186,21 +1371,27 @@ static void query_for_backends_locked(grpc_exec_ctx *exec_ctx,
   op->flags = 0;
   op->reserved = NULL;
   op++;
-
   op->op = GRPC_OP_RECV_INITIAL_METADATA;
   op->data.recv_initial_metadata.recv_initial_metadata =
       &glb_policy->lb_initial_metadata_recv;
   op->flags = 0;
   op->reserved = NULL;
   op++;
-
   GPR_ASSERT(glb_policy->lb_request_payload != NULL);
   op->op = GRPC_OP_SEND_MESSAGE;
   op->data.send_message.send_message = glb_policy->lb_request_payload;
   op->flags = 0;
   op->reserved = NULL;
   op++;
+  /* take a weak ref (won't prevent calling of \a glb_shutdown if the strong ref
+   * count goes to zero) to be unref'd in lb_on_sent_initial_request_locked() */
+  GRPC_LB_POLICY_WEAK_REF(&glb_policy->base, "lb_on_server_status_received");
+  call_error = grpc_call_start_batch_and_execute(
+      exec_ctx, glb_policy->lb_call, ops, (size_t)(op - ops),
+      &glb_policy->lb_on_sent_initial_request);
+  GPR_ASSERT(GRPC_CALL_OK == call_error);
 
+  op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata =
       &glb_policy->lb_trailing_metadata_recv;
@@ -1232,6 +1423,19 @@ static void query_for_backends_locked(grpc_exec_ctx *exec_ctx,
   GPR_ASSERT(GRPC_CALL_OK == call_error);
 }
 
+static void lb_on_sent_initial_request_locked(grpc_exec_ctx *exec_ctx,
+                                              void *arg, grpc_error *error) {
+  glb_lb_policy *glb_policy = arg;
+  glb_policy->initial_request_sent = true;
+  // If we attempted to send a client load report before the initial
+  // request was sent, send the load report now.
+  if (glb_policy->client_load_report_payload != NULL) {
+    do_send_client_load_report_locked(exec_ctx, glb_policy);
+  }
+  GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &glb_policy->base,
+                            "lb_on_response_received_locked");
+}
+
 static void lb_on_response_received_locked(grpc_exec_ctx *exec_ctx, void *arg,
                                            grpc_error *error) {
   glb_lb_policy *glb_policy = arg;
@@ -1247,57 +1451,91 @@ static void lb_on_response_received_locked(grpc_exec_ctx *exec_ctx, void *arg,
     grpc_byte_buffer_reader_init(&bbr, glb_policy->lb_response_payload);
     grpc_slice response_slice = grpc_byte_buffer_reader_readall(&bbr);
     grpc_byte_buffer_destroy(glb_policy->lb_response_payload);
-    grpc_grpclb_serverlist *serverlist =
-        grpc_grpclb_response_parse_serverlist(response_slice);
-    if (serverlist != NULL) {
-      GPR_ASSERT(glb_policy->lb_call != NULL);
-      grpc_slice_unref_internal(exec_ctx, response_slice);
-      if (grpc_lb_glb_trace) {
-        gpr_log(GPR_INFO, "Serverlist with %lu servers received",
-                (unsigned long)serverlist->num_servers);
-        for (size_t i = 0; i < serverlist->num_servers; ++i) {
-          grpc_resolved_address addr;
-          parse_server(serverlist->servers[i], &addr);
-          char *ipport;
-          grpc_sockaddr_to_string(&ipport, &addr, false);
-          gpr_log(GPR_INFO, "Serverlist[%lu]: %s", (unsigned long)i, ipport);
-          gpr_free(ipport);
+
+    grpc_grpclb_initial_response *response = NULL;
+    if (!glb_policy->seen_initial_response &&
+        (response = grpc_grpclb_initial_response_parse(response_slice)) !=
+            NULL) {
+      if (response->has_client_stats_report_interval) {
+        glb_policy->client_stats_report_interval =
+            gpr_time_max(gpr_time_from_seconds(1, GPR_TIMESPAN),
+                         grpc_grpclb_duration_to_timespec(
+                             &response->client_stats_report_interval));
+        if (grpc_lb_glb_trace) {
+          gpr_log(GPR_INFO,
+                  "received initial LB response message; "
+                  "client load reporting interval = %" PRId64 ".%09d sec",
+                  glb_policy->client_stats_report_interval.tv_sec,
+                  glb_policy->client_stats_report_interval.tv_nsec);
         }
+        /* take a weak ref (won't prevent calling of \a glb_shutdown() if the
+         * strong ref count goes to zero) to be unref'd in
+         * send_client_load_report() */
+        glb_policy->client_load_report_timer_pending = true;
+        GRPC_LB_POLICY_WEAK_REF(&glb_policy->base, "client_load_report");
+        schedule_next_client_load_report(exec_ctx, glb_policy);
+      } else if (grpc_lb_glb_trace) {
+        gpr_log(GPR_INFO,
+                "received initial LB response message; "
+                "client load reporting NOT enabled");
       }
+      grpc_grpclb_initial_response_destroy(response);
+      glb_policy->seen_initial_response = true;
+    } else {
+      grpc_grpclb_serverlist *serverlist =
+          grpc_grpclb_response_parse_serverlist(response_slice);
+      if (serverlist != NULL) {
+        GPR_ASSERT(glb_policy->lb_call != NULL);
+        if (grpc_lb_glb_trace) {
+          gpr_log(GPR_INFO, "Serverlist with %lu servers received",
+                  (unsigned long)serverlist->num_servers);
+          for (size_t i = 0; i < serverlist->num_servers; ++i) {
+            grpc_resolved_address addr;
+            parse_server(serverlist->servers[i], &addr);
+            char *ipport;
+            grpc_sockaddr_to_string(&ipport, &addr, false);
+            gpr_log(GPR_INFO, "Serverlist[%lu]: %s", (unsigned long)i, ipport);
+            gpr_free(ipport);
+          }
+        }
 
-      /* update serverlist */
-      if (serverlist->num_servers > 0) {
-        if (grpc_grpclb_serverlist_equals(glb_policy->serverlist, serverlist)) {
+        /* update serverlist */
+        if (serverlist->num_servers > 0) {
+          if (grpc_grpclb_serverlist_equals(glb_policy->serverlist,
+                                            serverlist)) {
+            if (grpc_lb_glb_trace) {
+              gpr_log(GPR_INFO,
+                      "Incoming server list identical to current, ignoring.");
+            }
+            grpc_grpclb_destroy_serverlist(serverlist);
+          } else { /* new serverlist */
+            if (glb_policy->serverlist != NULL) {
+              /* dispose of the old serverlist */
+              grpc_grpclb_destroy_serverlist(glb_policy->serverlist);
+            }
+            /* and update the copy in the glb_lb_policy instance. This
+             * serverlist instance will be destroyed either upon the next
+             * update or in glb_destroy() */
+            glb_policy->serverlist = serverlist;
+
+            rr_handover_locked(exec_ctx, glb_policy);
+          }
+        } else {
           if (grpc_lb_glb_trace) {
             gpr_log(GPR_INFO,
-                    "Incoming server list identical to current, ignoring.");
+                    "Received empty server list. Picks will stay pending until "
+                    "a response with > 0 servers is received");
           }
           grpc_grpclb_destroy_serverlist(serverlist);
-        } else { /* new serverlist */
-          if (glb_policy->serverlist != NULL) {
-            /* dispose of the old serverlist */
-            grpc_grpclb_destroy_serverlist(glb_policy->serverlist);
-          }
-          /* and update the copy in the glb_lb_policy instance. This serverlist
-           * instance will be destroyed either upon the next update or in
-           * glb_destroy() */
-          glb_policy->serverlist = serverlist;
-
-          rr_handover_locked(exec_ctx, glb_policy);
-        }
-      } else {
-        if (grpc_lb_glb_trace) {
-          gpr_log(GPR_INFO,
-                  "Received empty server list. Picks will stay pending until a "
-                  "response with > 0 servers is received");
         }
+      } else { /* serverlist == NULL */
+        gpr_log(GPR_ERROR, "Invalid LB response received: '%s'. Ignoring.",
+                grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX));
       }
-    } else { /* serverlist == NULL */
-      gpr_log(GPR_ERROR, "Invalid LB response received: '%s'. Ignoring.",
-              grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX));
-      grpc_slice_unref_internal(exec_ctx, response_slice);
     }
 
+    grpc_slice_unref_internal(exec_ctx, response_slice);
+
     if (!glb_policy->shutting_down) {
       /* keep listening for serverlist updates */
       op->op = GRPC_OP_RECV_MESSAGE;
@@ -1409,9 +1647,29 @@ grpc_lb_policy_factory *grpc_glb_lb_factory_create() {
 }
 
 /* Plugin registration */
+
+// Only add client_load_reporting filter if the grpclb LB policy is used.
+static bool maybe_add_client_load_reporting_filter(
+    grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder, void *arg) {
+  const grpc_channel_args *args =
+      grpc_channel_stack_builder_get_channel_arguments(builder);
+  const grpc_arg *channel_arg =
+      grpc_channel_args_find(args, GRPC_ARG_LB_POLICY_NAME);
+  if (channel_arg != NULL && channel_arg->type == GRPC_ARG_STRING &&
+      strcmp(channel_arg->value.string, "grpclb") == 0) {
+    return grpc_channel_stack_builder_append_filter(
+        builder, (const grpc_channel_filter *)arg, NULL, NULL);
+  }
+  return true;
+}
+
 void grpc_lb_policy_grpclb_init() {
   grpc_register_lb_policy(grpc_glb_lb_factory_create());
   grpc_register_tracer("glb", &grpc_lb_glb_trace);
+  grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL,
+                                   GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+                                   maybe_add_client_load_reporting_filter,
+                                   (void *)&grpc_client_load_reporting_filter);
 }
 
 void grpc_lb_policy_grpclb_shutdown() {}
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h
similarity index 86%
rename from src/core/ext/lb_policy/grpclb/grpclb.h
rename to src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h
index ff23f3a54586f39f45a5146a9a1b55fca5c21c08..b069fae2f80b9e531e3253fc10564bfcae791c63 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.h
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h
@@ -31,14 +31,14 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_H
-#define GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_H
 
-#include "src/core/ext/client_channel/lb_policy_factory.h"
+#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
 
 /** Returns a load balancing factory for the glb policy, which tries to connect
  * to a load balancing server to decide the next successfully connected
  * subchannel to pick. */
 grpc_lb_policy_factory *grpc_glb_lb_factory_create();
 
-#endif /* GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_H */
diff --git a/src/core/ext/lb_policy/grpclb/grpclb_channel.c b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c
similarity index 96%
rename from src/core/ext/lb_policy/grpclb/grpclb_channel.c
rename to src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c
index 1b8bbab1b69954c0e34878a78b8857a537245c69..d6201f23879e7bbaf81919468fb4f5a677eac6d0 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb_channel.c
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c
@@ -34,8 +34,8 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/lb_policy/grpclb/grpclb_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/support/string.h"
diff --git a/src/core/ext/lb_policy/grpclb/grpclb_channel.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
similarity index 88%
rename from src/core/ext/lb_policy/grpclb/grpclb_channel.h
rename to src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
index f66082d78ee887e3c1fa5d48babde91b15ec3038..9730c971d97c7c09399cf0bf744756a91cd1515f 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb_channel.h
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
@@ -31,10 +31,10 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H
-#define GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H
 
-#include "src/core/ext/client_channel/lb_policy_factory.h"
+#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
 #include "src/core/lib/slice/slice_hash_table.h"
 
 /** Create the channel used for communicating with an LB service.
@@ -53,4 +53,5 @@ grpc_channel_args *get_lb_channel_args(grpc_exec_ctx *exec_ctx,
                                        grpc_slice_hash_table *targets_info,
                                        const grpc_channel_args *args);
 
-#endif /* GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H \
+          */
diff --git a/src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c
similarity index 97%
rename from src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c
rename to src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c
index 2fee5f1b8eababb0532d9b4919c62343c25192a9..a145cba63caafe581300496b3ced3c9277a8fb04 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c
@@ -34,8 +34,8 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/lb_policy/grpclb/grpclb_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/security/credentials/credentials.h"
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c
new file mode 100644
index 0000000000000000000000000000000000000000..444c03b9aabf4cca851ed670390d78c097346f9c
--- /dev/null
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c
@@ -0,0 +1,133 @@
+/*
+ *
+ * Copyright 2017, 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/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h"
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/atm.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/useful.h>
+
+#include "src/core/lib/channel/channel_args.h"
+
+#define GRPC_ARG_GRPCLB_CLIENT_STATS "grpc.grpclb_client_stats"
+
+struct grpc_grpclb_client_stats {
+  gpr_refcount refs;
+  gpr_atm num_calls_started;
+  gpr_atm num_calls_finished;
+  gpr_atm num_calls_finished_with_drop_for_rate_limiting;
+  gpr_atm num_calls_finished_with_drop_for_load_balancing;
+  gpr_atm num_calls_finished_with_client_failed_to_send;
+  gpr_atm num_calls_finished_known_received;
+};
+
+grpc_grpclb_client_stats* grpc_grpclb_client_stats_create() {
+  grpc_grpclb_client_stats* client_stats = gpr_zalloc(sizeof(*client_stats));
+  gpr_ref_init(&client_stats->refs, 1);
+  return client_stats;
+}
+
+grpc_grpclb_client_stats* grpc_grpclb_client_stats_ref(
+    grpc_grpclb_client_stats* client_stats) {
+  gpr_ref(&client_stats->refs);
+  return client_stats;
+}
+
+void grpc_grpclb_client_stats_unref(grpc_grpclb_client_stats* client_stats) {
+  if (gpr_unref(&client_stats->refs)) {
+    gpr_free(client_stats);
+  }
+}
+
+void grpc_grpclb_client_stats_add_call_started(
+    grpc_grpclb_client_stats* client_stats) {
+  gpr_atm_full_fetch_add(&client_stats->num_calls_started, (gpr_atm)1);
+}
+
+void grpc_grpclb_client_stats_add_call_finished(
+    bool finished_with_drop_for_rate_limiting,
+    bool finished_with_drop_for_load_balancing,
+    bool finished_with_client_failed_to_send, bool finished_known_received,
+    grpc_grpclb_client_stats* client_stats) {
+  gpr_atm_full_fetch_add(&client_stats->num_calls_finished, (gpr_atm)1);
+  if (finished_with_drop_for_rate_limiting) {
+    gpr_atm_full_fetch_add(
+        &client_stats->num_calls_finished_with_drop_for_rate_limiting,
+        (gpr_atm)1);
+  }
+  if (finished_with_drop_for_load_balancing) {
+    gpr_atm_full_fetch_add(
+        &client_stats->num_calls_finished_with_drop_for_load_balancing,
+        (gpr_atm)1);
+  }
+  if (finished_with_client_failed_to_send) {
+    gpr_atm_full_fetch_add(
+        &client_stats->num_calls_finished_with_client_failed_to_send,
+        (gpr_atm)1);
+  }
+  if (finished_known_received) {
+    gpr_atm_full_fetch_add(&client_stats->num_calls_finished_known_received,
+                           (gpr_atm)1);
+  }
+}
+
+static void atomic_get_and_reset_counter(int64_t* value, gpr_atm* counter) {
+  *value = (int64_t)gpr_atm_acq_load(counter);
+  gpr_atm_full_fetch_add(counter, (gpr_atm)(-*value));
+}
+
+void grpc_grpclb_client_stats_get(
+    grpc_grpclb_client_stats* client_stats, int64_t* num_calls_started,
+    int64_t* num_calls_finished,
+    int64_t* num_calls_finished_with_drop_for_rate_limiting,
+    int64_t* num_calls_finished_with_drop_for_load_balancing,
+    int64_t* num_calls_finished_with_client_failed_to_send,
+    int64_t* num_calls_finished_known_received) {
+  atomic_get_and_reset_counter(num_calls_started,
+                               &client_stats->num_calls_started);
+  atomic_get_and_reset_counter(num_calls_finished,
+                               &client_stats->num_calls_finished);
+  atomic_get_and_reset_counter(
+      num_calls_finished_with_drop_for_rate_limiting,
+      &client_stats->num_calls_finished_with_drop_for_rate_limiting);
+  atomic_get_and_reset_counter(
+      num_calls_finished_with_drop_for_load_balancing,
+      &client_stats->num_calls_finished_with_drop_for_load_balancing);
+  atomic_get_and_reset_counter(
+      num_calls_finished_with_client_failed_to_send,
+      &client_stats->num_calls_finished_with_client_failed_to_send);
+  atomic_get_and_reset_counter(
+      num_calls_finished_known_received,
+      &client_stats->num_calls_finished_known_received);
+}
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
new file mode 100644
index 0000000000000000000000000000000000000000..0af4a919f807c77cbd8683dd20343adb77765c78
--- /dev/null
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
@@ -0,0 +1,65 @@
+/*
+ *
+ * Copyright 2017, 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_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CLIENT_STATS_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CLIENT_STATS_H
+
+#include <stdbool.h>
+
+#include <grpc/impl/codegen/grpc_types.h>
+
+typedef struct grpc_grpclb_client_stats grpc_grpclb_client_stats;
+
+grpc_grpclb_client_stats* grpc_grpclb_client_stats_create();
+grpc_grpclb_client_stats* grpc_grpclb_client_stats_ref(
+    grpc_grpclb_client_stats* client_stats);
+void grpc_grpclb_client_stats_unref(grpc_grpclb_client_stats* client_stats);
+
+void grpc_grpclb_client_stats_add_call_started(
+    grpc_grpclb_client_stats* client_stats);
+void grpc_grpclb_client_stats_add_call_finished(
+    bool finished_with_drop_for_rate_limiting,
+    bool finished_with_drop_for_load_balancing,
+    bool finished_with_client_failed_to_send, bool finished_known_received,
+    grpc_grpclb_client_stats* client_stats);
+
+void grpc_grpclb_client_stats_get(
+    grpc_grpclb_client_stats* client_stats, int64_t* num_calls_started,
+    int64_t* num_calls_finished,
+    int64_t* num_calls_finished_with_drop_for_rate_limiting,
+    int64_t* num_calls_finished_with_drop_for_load_balancing,
+    int64_t* num_calls_finished_with_client_failed_to_send,
+    int64_t* num_calls_finished_known_received);
+
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CLIENT_STATS_H \
+          */
diff --git a/src/core/ext/lb_policy/grpclb/load_balancer_api.c b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c
similarity index 80%
rename from src/core/ext/lb_policy/grpclb/load_balancer_api.c
rename to src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c
index 3c4604c4022f20a9f5b25ea37808eb6a7205678a..81b6932faeb15089445d8767049b16fbfafa2ff8 100644
--- a/src/core/ext/lb_policy/grpclb/load_balancer_api.c
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h"
 #include "third_party/nanopb/pb_decode.h"
 #include "third_party/nanopb/pb_encode.h"
 
@@ -80,15 +80,45 @@ static bool decode_serverlist(pb_istream_t *stream, const pb_field_t *field,
 
 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;
+  req->has_client_stats = false;
+  req->has_initial_request = true;
+  req->initial_request.has_name = true;
   strncpy(req->initial_request.name, lb_service_name,
           GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH);
   return req;
 }
 
+static void populate_timestamp(gpr_timespec timestamp,
+                               struct _grpc_lb_v1_Timestamp *timestamp_pb) {
+  timestamp_pb->has_seconds = true;
+  timestamp_pb->seconds = timestamp.tv_sec;
+  timestamp_pb->has_nanos = true;
+  timestamp_pb->nanos = timestamp.tv_nsec;
+}
+
+grpc_grpclb_request *grpc_grpclb_load_report_request_create(
+    grpc_grpclb_client_stats *client_stats) {
+  grpc_grpclb_request *req = gpr_zalloc(sizeof(grpc_grpclb_request));
+  req->has_client_stats = true;
+  req->client_stats.has_timestamp = true;
+  populate_timestamp(gpr_now(GPR_CLOCK_REALTIME), &req->client_stats.timestamp);
+  req->client_stats.has_num_calls_started = true;
+  req->client_stats.has_num_calls_finished = true;
+  req->client_stats.has_num_calls_finished_with_drop_for_rate_limiting = true;
+  req->client_stats.has_num_calls_finished_with_drop_for_load_balancing = true;
+  req->client_stats.has_num_calls_finished_with_client_failed_to_send = true;
+  req->client_stats.has_num_calls_finished_with_client_failed_to_send = true;
+  req->client_stats.has_num_calls_finished_known_received = true;
+  grpc_grpclb_client_stats_get(
+      client_stats, &req->client_stats.num_calls_started,
+      &req->client_stats.num_calls_finished,
+      &req->client_stats.num_calls_finished_with_drop_for_rate_limiting,
+      &req->client_stats.num_calls_finished_with_drop_for_load_balancing,
+      &req->client_stats.num_calls_finished_with_client_failed_to_send,
+      &req->client_stats.num_calls_finished_known_received);
+  return req;
+}
+
 grpc_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request) {
   size_t encoded_length;
   pb_ostream_t sizestream;
@@ -98,7 +128,7 @@ grpc_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request) {
   pb_encode(&sizestream, grpc_lb_v1_LoadBalanceRequest_fields, request);
   encoded_length = sizestream.bytes_written;
 
-  slice = grpc_slice_malloc(encoded_length);
+  slice = GRPC_SLICE_MALLOC(encoded_length);
   outputstream =
       pb_ostream_from_buffer(GRPC_SLICE_START_PTR(slice), encoded_length);
   GPR_ASSERT(pb_encode(&outputstream, grpc_lb_v1_LoadBalanceRequest_fields,
@@ -122,6 +152,9 @@ grpc_grpclb_initial_response *grpc_grpclb_initial_response_parse(
     gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream));
     return NULL;
   }
+
+  if (!res.has_initial_response) return NULL;
+
   grpc_grpclb_initial_response *initial_res =
       gpr_malloc(sizeof(grpc_grpclb_initial_response));
   memcpy(initial_res, &res.initial_response,
@@ -243,6 +276,15 @@ int grpc_grpclb_duration_compare(const grpc_grpclb_duration *lhs,
   return 0;
 }
 
+gpr_timespec grpc_grpclb_duration_to_timespec(
+    grpc_grpclb_duration *duration_pb) {
+  gpr_timespec duration;
+  duration.tv_sec = duration_pb->has_seconds ? duration_pb->seconds : 0;
+  duration.tv_nsec = duration_pb->has_nanos ? duration_pb->nanos : 0;
+  duration.clock_type = GPR_TIMESPAN;
+  return duration;
+}
+
 void grpc_grpclb_initial_response_destroy(
     grpc_grpclb_initial_response *response) {
   gpr_free(response);
diff --git a/src/core/ext/lb_policy/grpclb/load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
similarity index 84%
rename from src/core/ext/lb_policy/grpclb/load_balancer_api.h
rename to src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
index b4c967e426657d076dadac6a05ce83f188adb3af..06873821bd3127fba0b94abee944b90afb962b4c 100644
--- a/src/core/ext/lb_policy/grpclb/load_balancer_api.h
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
@@ -31,13 +31,14 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_LB_POLICY_GRPCLB_LOAD_BALANCER_API_H
-#define GRPC_CORE_EXT_LB_POLICY_GRPCLB_LOAD_BALANCER_API_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_LOAD_BALANCER_API_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_LOAD_BALANCER_API_H
 
 #include <grpc/slice_buffer.h>
 
-#include "src/core/ext/client_channel/lb_policy_factory.h"
-#include "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
+#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -58,6 +59,8 @@ typedef struct 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);
+grpc_grpclb_request *grpc_grpclb_load_report_request_create(
+    grpc_grpclb_client_stats *client_stats);
 
 /** Protocol Buffers v3-encode \a request */
 grpc_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request);
@@ -93,6 +96,9 @@ void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist);
 int grpc_grpclb_duration_compare(const grpc_grpclb_duration *lhs,
                                  const grpc_grpclb_duration *rhs);
 
+gpr_timespec grpc_grpclb_duration_to_timespec(
+    grpc_grpclb_duration *duration_pb);
+
 /** Destroy \a initial_response */
 void grpc_grpclb_initial_response_destroy(
     grpc_grpclb_initial_response *response);
@@ -101,4 +107,5 @@ void grpc_grpclb_initial_response_destroy(
 }
 #endif
 
-#endif /* GRPC_CORE_EXT_LB_POLICY_GRPCLB_LOAD_BALANCER_API_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_LOAD_BALANCER_API_H \
+          */
diff --git a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c b/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
similarity index 57%
rename from src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
rename to src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
index e352e0396f8f5de3abd72e0f2b66418599f1ee95..fb119c7fc889e5e9f370f31fee5bfb12f93b0fbe 100644
--- a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
@@ -1,7 +1,7 @@
 /* Automatically generated nanopb constant definitions */
 /* Generated by nanopb-0.3.7-dev */
 
-#include "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
 
 /* @@protoc_insertion_point(includes) */
 #if PB_PROTO_HEADER_VERSION != 30
@@ -16,6 +16,12 @@ const pb_field_t grpc_lb_v1_Duration_fields[3] = {
     PB_LAST_FIELD
 };
 
+const pb_field_t grpc_lb_v1_Timestamp_fields[3] = {
+    PB_FIELD(  1, INT64   , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_Timestamp, seconds, seconds, 0),
+    PB_FIELD(  2, INT32   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_Timestamp, nanos, seconds, 0),
+    PB_LAST_FIELD
+};
+
 const pb_field_t grpc_lb_v1_LoadBalanceRequest_fields[3] = {
     PB_FIELD(  1, MESSAGE , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_LoadBalanceRequest, initial_request, initial_request, &grpc_lb_v1_InitialLoadBalanceRequest_fields),
     PB_FIELD(  2, MESSAGE , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_LoadBalanceRequest, client_stats, initial_request, &grpc_lb_v1_ClientStats_fields),
@@ -27,10 +33,14 @@ const pb_field_t grpc_lb_v1_InitialLoadBalanceRequest_fields[2] = {
     PB_LAST_FIELD
 };
 
-const pb_field_t grpc_lb_v1_ClientStats_fields[4] = {
-    PB_FIELD(  1, INT64   , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_ClientStats, total_requests, total_requests, 0),
-    PB_FIELD(  2, INT64   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_ClientStats, client_rpc_errors, total_requests, 0),
-    PB_FIELD(  3, INT64   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_ClientStats, dropped_requests, client_rpc_errors, 0),
+const pb_field_t grpc_lb_v1_ClientStats_fields[8] = {
+    PB_FIELD(  1, MESSAGE , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_ClientStats, timestamp, timestamp, &grpc_lb_v1_Timestamp_fields),
+    PB_FIELD(  2, INT64   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_ClientStats, num_calls_started, timestamp, 0),
+    PB_FIELD(  3, INT64   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_ClientStats, num_calls_finished, num_calls_started, 0),
+    PB_FIELD(  4, INT64   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_ClientStats, num_calls_finished_with_drop_for_rate_limiting, num_calls_finished, 0),
+    PB_FIELD(  5, INT64   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_ClientStats, num_calls_finished_with_drop_for_load_balancing, num_calls_finished_with_drop_for_rate_limiting, 0),
+    PB_FIELD(  6, INT64   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_ClientStats, num_calls_finished_with_client_failed_to_send, num_calls_finished_with_drop_for_load_balancing, 0),
+    PB_FIELD(  7, INT64   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_ClientStats, num_calls_finished_known_received, num_calls_finished_with_client_failed_to_send, 0),
     PB_LAST_FIELD
 };
 
@@ -52,11 +62,12 @@ const pb_field_t grpc_lb_v1_ServerList_fields[3] = {
     PB_LAST_FIELD
 };
 
-const pb_field_t grpc_lb_v1_Server_fields[5] = {
+const pb_field_t grpc_lb_v1_Server_fields[6] = {
     PB_FIELD(  1, BYTES   , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_Server, ip_address, ip_address, 0),
     PB_FIELD(  2, INT32   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_Server, port, ip_address, 0),
     PB_FIELD(  3, STRING  , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_Server, load_balance_token, port, 0),
-    PB_FIELD(  4, BOOL    , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_Server, drop_request, load_balance_token, 0),
+    PB_FIELD(  4, BOOL    , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_Server, drop_for_rate_limiting, load_balance_token, 0),
+    PB_FIELD(  5, BOOL    , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_Server, drop_for_load_balancing, drop_for_rate_limiting, 0),
     PB_LAST_FIELD
 };
 
@@ -70,7 +81,7 @@ const pb_field_t grpc_lb_v1_Server_fields[5] = {
  * 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_v1_LoadBalanceRequest, initial_request) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 65536 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 65536 && pb_membersize(grpc_lb_v1_ServerList, servers) < 65536 && pb_membersize(grpc_lb_v1_ServerList, expiration_interval) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_lb_v1_Duration_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server)
+PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 65536 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 65536 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 65536 && pb_membersize(grpc_lb_v1_ServerList, servers) < 65536 && pb_membersize(grpc_lb_v1_ServerList, expiration_interval) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_lb_v1_Duration_grpc_lb_v1_Timestamp_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server)
 #endif
 
 #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
@@ -81,7 +92,7 @@ PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request)
  * numbers or field sizes that are larger than what can fit in the default
  * 8 bit descriptors.
  */
-PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v1_ServerList, servers) < 256 && pb_membersize(grpc_lb_v1_ServerList, expiration_interval) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_lb_v1_Duration_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server)
+PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v1_ServerList, servers) < 256 && pb_membersize(grpc_lb_v1_ServerList, expiration_interval) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_lb_v1_Duration_grpc_lb_v1_Timestamp_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server)
 #endif
 
 
diff --git a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
similarity index 69%
rename from src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
rename to src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
index 725aa7e386f9384732df22e49811c12c37581a67..d3ae919ec27e345798c843dfc438659cde177557 100644
--- a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
@@ -14,16 +14,6 @@ extern "C" {
 #endif
 
 /* Struct definitions */
-typedef struct _grpc_lb_v1_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;
-/* @@protoc_insertion_point(struct:grpc_lb_v1_ClientStats) */
-} grpc_lb_v1_ClientStats;
-
 typedef struct _grpc_lb_v1_Duration {
     bool has_seconds;
     int64_t seconds;
@@ -46,11 +36,39 @@ typedef struct _grpc_lb_v1_Server {
     int32_t port;
     bool has_load_balance_token;
     char load_balance_token[50];
-    bool has_drop_request;
-    bool drop_request;
+    bool has_drop_for_rate_limiting;
+    bool drop_for_rate_limiting;
+    bool has_drop_for_load_balancing;
+    bool drop_for_load_balancing;
 /* @@protoc_insertion_point(struct:grpc_lb_v1_Server) */
 } grpc_lb_v1_Server;
 
+typedef struct _grpc_lb_v1_Timestamp {
+    bool has_seconds;
+    int64_t seconds;
+    bool has_nanos;
+    int32_t nanos;
+/* @@protoc_insertion_point(struct:grpc_lb_v1_Timestamp) */
+} grpc_lb_v1_Timestamp;
+
+typedef struct _grpc_lb_v1_ClientStats {
+    bool has_timestamp;
+    grpc_lb_v1_Timestamp timestamp;
+    bool has_num_calls_started;
+    int64_t num_calls_started;
+    bool has_num_calls_finished;
+    int64_t num_calls_finished;
+    bool has_num_calls_finished_with_drop_for_rate_limiting;
+    int64_t num_calls_finished_with_drop_for_rate_limiting;
+    bool has_num_calls_finished_with_drop_for_load_balancing;
+    int64_t num_calls_finished_with_drop_for_load_balancing;
+    bool has_num_calls_finished_with_client_failed_to_send;
+    int64_t num_calls_finished_with_client_failed_to_send;
+    bool has_num_calls_finished_known_received;
+    int64_t num_calls_finished_known_received;
+/* @@protoc_insertion_point(struct:grpc_lb_v1_ClientStats) */
+} grpc_lb_v1_ClientStats;
+
 typedef struct _grpc_lb_v1_InitialLoadBalanceResponse {
     bool has_load_balancer_delegate;
     char load_balancer_delegate[64];
@@ -59,6 +77,13 @@ typedef struct _grpc_lb_v1_InitialLoadBalanceResponse {
 /* @@protoc_insertion_point(struct:grpc_lb_v1_InitialLoadBalanceResponse) */
 } grpc_lb_v1_InitialLoadBalanceResponse;
 
+typedef struct _grpc_lb_v1_ServerList {
+    pb_callback_t servers;
+    bool has_expiration_interval;
+    grpc_lb_v1_Duration expiration_interval;
+/* @@protoc_insertion_point(struct:grpc_lb_v1_ServerList) */
+} grpc_lb_v1_ServerList;
+
 typedef struct _grpc_lb_v1_LoadBalanceRequest {
     bool has_initial_request;
     grpc_lb_v1_InitialLoadBalanceRequest initial_request;
@@ -67,13 +92,6 @@ typedef struct _grpc_lb_v1_LoadBalanceRequest {
 /* @@protoc_insertion_point(struct:grpc_lb_v1_LoadBalanceRequest) */
 } grpc_lb_v1_LoadBalanceRequest;
 
-typedef struct _grpc_lb_v1_ServerList {
-    pb_callback_t servers;
-    bool has_expiration_interval;
-    grpc_lb_v1_Duration expiration_interval;
-/* @@protoc_insertion_point(struct:grpc_lb_v1_ServerList) */
-} grpc_lb_v1_ServerList;
-
 typedef struct _grpc_lb_v1_LoadBalanceResponse {
     bool has_initial_response;
     grpc_lb_v1_InitialLoadBalanceResponse initial_response;
@@ -86,61 +104,72 @@ typedef struct _grpc_lb_v1_LoadBalanceResponse {
 
 /* Initializer values for message structs */
 #define grpc_lb_v1_Duration_init_default         {false, 0, false, 0}
+#define grpc_lb_v1_Timestamp_init_default        {false, 0, false, 0}
 #define grpc_lb_v1_LoadBalanceRequest_init_default {false, grpc_lb_v1_InitialLoadBalanceRequest_init_default, false, grpc_lb_v1_ClientStats_init_default}
 #define grpc_lb_v1_InitialLoadBalanceRequest_init_default {false, ""}
-#define grpc_lb_v1_ClientStats_init_default      {false, 0, false, 0, false, 0}
+#define grpc_lb_v1_ClientStats_init_default      {false, grpc_lb_v1_Timestamp_init_default, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
 #define grpc_lb_v1_LoadBalanceResponse_init_default {false, grpc_lb_v1_InitialLoadBalanceResponse_init_default, false, grpc_lb_v1_ServerList_init_default}
 #define grpc_lb_v1_InitialLoadBalanceResponse_init_default {false, "", false, grpc_lb_v1_Duration_init_default}
 #define grpc_lb_v1_ServerList_init_default       {{{NULL}, NULL}, false, grpc_lb_v1_Duration_init_default}
-#define grpc_lb_v1_Server_init_default           {false, {0, {0}}, false, 0, false, "", false, 0}
+#define grpc_lb_v1_Server_init_default           {false, {0, {0}}, false, 0, false, "", false, 0, false, 0}
 #define grpc_lb_v1_Duration_init_zero            {false, 0, false, 0}
+#define grpc_lb_v1_Timestamp_init_zero           {false, 0, false, 0}
 #define grpc_lb_v1_LoadBalanceRequest_init_zero  {false, grpc_lb_v1_InitialLoadBalanceRequest_init_zero, false, grpc_lb_v1_ClientStats_init_zero}
 #define grpc_lb_v1_InitialLoadBalanceRequest_init_zero {false, ""}
-#define grpc_lb_v1_ClientStats_init_zero         {false, 0, false, 0, false, 0}
+#define grpc_lb_v1_ClientStats_init_zero         {false, grpc_lb_v1_Timestamp_init_zero, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
 #define grpc_lb_v1_LoadBalanceResponse_init_zero {false, grpc_lb_v1_InitialLoadBalanceResponse_init_zero, false, grpc_lb_v1_ServerList_init_zero}
 #define grpc_lb_v1_InitialLoadBalanceResponse_init_zero {false, "", false, grpc_lb_v1_Duration_init_zero}
 #define grpc_lb_v1_ServerList_init_zero          {{{NULL}, NULL}, false, grpc_lb_v1_Duration_init_zero}
-#define grpc_lb_v1_Server_init_zero              {false, {0, {0}}, false, 0, false, "", false, 0}
+#define grpc_lb_v1_Server_init_zero              {false, {0, {0}}, false, 0, false, "", false, 0, false, 0}
 
 /* Field tags (for use in manual encoding/decoding) */
-#define grpc_lb_v1_ClientStats_total_requests_tag 1
-#define grpc_lb_v1_ClientStats_client_rpc_errors_tag 2
-#define grpc_lb_v1_ClientStats_dropped_requests_tag 3
 #define grpc_lb_v1_Duration_seconds_tag          1
 #define grpc_lb_v1_Duration_nanos_tag            2
 #define grpc_lb_v1_InitialLoadBalanceRequest_name_tag 1
 #define grpc_lb_v1_Server_ip_address_tag         1
 #define grpc_lb_v1_Server_port_tag               2
 #define grpc_lb_v1_Server_load_balance_token_tag 3
-#define grpc_lb_v1_Server_drop_request_tag       4
+#define grpc_lb_v1_Server_drop_for_rate_limiting_tag 4
+#define grpc_lb_v1_Server_drop_for_load_balancing_tag 5
+#define grpc_lb_v1_Timestamp_seconds_tag         1
+#define grpc_lb_v1_Timestamp_nanos_tag           2
+#define grpc_lb_v1_ClientStats_timestamp_tag     1
+#define grpc_lb_v1_ClientStats_num_calls_started_tag 2
+#define grpc_lb_v1_ClientStats_num_calls_finished_tag 3
+#define grpc_lb_v1_ClientStats_num_calls_finished_with_drop_for_rate_limiting_tag 4
+#define grpc_lb_v1_ClientStats_num_calls_finished_with_drop_for_load_balancing_tag 5
+#define grpc_lb_v1_ClientStats_num_calls_finished_with_client_failed_to_send_tag 6
+#define grpc_lb_v1_ClientStats_num_calls_finished_known_received_tag 7
 #define grpc_lb_v1_InitialLoadBalanceResponse_load_balancer_delegate_tag 1
 #define grpc_lb_v1_InitialLoadBalanceResponse_client_stats_report_interval_tag 2
-#define grpc_lb_v1_LoadBalanceRequest_initial_request_tag 1
-#define grpc_lb_v1_LoadBalanceRequest_client_stats_tag 2
 #define grpc_lb_v1_ServerList_servers_tag        1
 #define grpc_lb_v1_ServerList_expiration_interval_tag 3
+#define grpc_lb_v1_LoadBalanceRequest_initial_request_tag 1
+#define grpc_lb_v1_LoadBalanceRequest_client_stats_tag 2
 #define grpc_lb_v1_LoadBalanceResponse_initial_response_tag 1
 #define grpc_lb_v1_LoadBalanceResponse_server_list_tag 2
 
 /* Struct field encoding specification for nanopb */
 extern const pb_field_t grpc_lb_v1_Duration_fields[3];
+extern const pb_field_t grpc_lb_v1_Timestamp_fields[3];
 extern const pb_field_t grpc_lb_v1_LoadBalanceRequest_fields[3];
 extern const pb_field_t grpc_lb_v1_InitialLoadBalanceRequest_fields[2];
-extern const pb_field_t grpc_lb_v1_ClientStats_fields[4];
+extern const pb_field_t grpc_lb_v1_ClientStats_fields[8];
 extern const pb_field_t grpc_lb_v1_LoadBalanceResponse_fields[3];
 extern const pb_field_t grpc_lb_v1_InitialLoadBalanceResponse_fields[3];
 extern const pb_field_t grpc_lb_v1_ServerList_fields[3];
-extern const pb_field_t grpc_lb_v1_Server_fields[5];
+extern const pb_field_t grpc_lb_v1_Server_fields[6];
 
 /* Maximum encoded size of messages (where known) */
 #define grpc_lb_v1_Duration_size                 22
-#define grpc_lb_v1_LoadBalanceRequest_size       169
+#define grpc_lb_v1_Timestamp_size                22
+#define grpc_lb_v1_LoadBalanceRequest_size       226
 #define grpc_lb_v1_InitialLoadBalanceRequest_size 131
-#define grpc_lb_v1_ClientStats_size              33
+#define grpc_lb_v1_ClientStats_size              90
 #define grpc_lb_v1_LoadBalanceResponse_size      (98 + grpc_lb_v1_ServerList_size)
 #define grpc_lb_v1_InitialLoadBalanceResponse_size 90
 /* grpc_lb_v1_ServerList_size depends on runtime parameters */
-#define grpc_lb_v1_Server_size                   83
+#define grpc_lb_v1_Server_size                   85
 
 /* Message IDs (where set with "msgid" option) */
 #ifdef PB_MSGID
diff --git a/src/core/ext/lb_policy/pick_first/pick_first.c b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c
similarity index 93%
rename from src/core/ext/lb_policy/pick_first/pick_first.c
rename to src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c
index e2a66d16bd7cebd37be6c056a1c8671e821c5c2f..b1c5dfc61ca864a396a1e8fc56ebacc871d7cf4f 100644
--- a/src/core/ext/lb_policy/pick_first/pick_first.c
+++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c
@@ -35,8 +35,8 @@
 
 #include <grpc/support/alloc.h>
 
-#include "src/core/ext/client_channel/lb_policy_registry.h"
-#include "src/core/ext/client_channel/subchannel.h"
+#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/subchannel.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/combiner.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -101,7 +101,7 @@ static void pf_shutdown_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
   p->pending_picks = NULL;
   grpc_connectivity_state_set(
       exec_ctx, &p->state_tracker, GRPC_CHANNEL_SHUTDOWN,
-      GRPC_ERROR_CREATE("Channel shutdown"), "shutdown");
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"), "shutdown");
   /* cancel subscription */
   if (p->selected != NULL) {
     grpc_connected_subchannel_notify_on_state_change(
@@ -131,9 +131,9 @@ static void pf_cancel_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     pending_pick *next = pp->next;
     if (pp->target == target) {
       *target = NULL;
-      grpc_closure_sched(
-          exec_ctx, pp->on_complete,
-          GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1));
+      grpc_closure_sched(exec_ctx, pp->on_complete,
+                         GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                             "Pick Cancelled", &error, 1));
       gpr_free(pp);
     } else {
       pp->next = p->pending_picks;
@@ -156,9 +156,9 @@ static void pf_cancel_picks_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     pending_pick *next = pp->next;
     if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
         initial_metadata_flags_eq) {
-      grpc_closure_sched(
-          exec_ctx, pp->on_complete,
-          GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1));
+      grpc_closure_sched(exec_ctx, pp->on_complete,
+                         GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                             "Pick Cancelled", &error, 1));
       gpr_free(pp);
     } else {
       pp->next = p->pending_picks;
@@ -189,7 +189,8 @@ static void pf_exit_idle_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
 
 static int pf_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
                           const grpc_lb_policy_pick_args *pick_args,
-                          grpc_connected_subchannel **target, void **user_data,
+                          grpc_connected_subchannel **target,
+                          grpc_call_context_element *context, void **user_data,
                           grpc_closure *on_complete) {
   pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
   pending_pick *pp;
@@ -325,8 +326,8 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
         if (p->num_subchannels == 0) {
           grpc_connectivity_state_set(
               exec_ctx, &p->state_tracker, GRPC_CHANNEL_SHUTDOWN,
-              GRPC_ERROR_CREATE_REFERENCING("Pick first exhausted channels",
-                                            &error, 1),
+              GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                  "Pick first exhausted channels", &error, 1),
               "no_more_channels");
           while ((pp = p->pending_picks)) {
             p->pending_picks = pp->next;
@@ -373,7 +374,8 @@ static void pf_ping_one_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
   if (p->selected) {
     grpc_connected_subchannel_ping(exec_ctx, p->selected, closure);
   } else {
-    grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_CREATE("Not connected"));
+    grpc_closure_sched(exec_ctx, closure,
+                       GRPC_ERROR_CREATE_FROM_STATIC_STRING("Not connected"));
   }
 }
 
@@ -401,7 +403,9 @@ static grpc_lb_policy *create_pick_first(grpc_exec_ctx *exec_ctx,
    * addresses, since we don't know how to handle them. */
   const grpc_arg *arg =
       grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES);
-  GPR_ASSERT(arg != NULL && arg->type == GRPC_ARG_POINTER);
+  if (arg == NULL || arg->type != GRPC_ARG_POINTER) {
+    return NULL;
+  }
   grpc_lb_addresses *addresses = arg->value.pointer.p;
   size_t num_addrs = 0;
   for (size_t i = 0; i < addresses->num_addresses; i++) {
@@ -423,11 +427,13 @@ static grpc_lb_policy *create_pick_first(grpc_exec_ctx *exec_ctx,
               "This LB policy doesn't support user data. It will be ignored");
     }
 
+    static const char *keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS};
     memset(&sc_args, 0, sizeof(grpc_subchannel_args));
     grpc_arg addr_arg =
         grpc_create_subchannel_address_arg(&addresses->addresses[i].address);
-    grpc_channel_args *new_args =
-        grpc_channel_args_copy_and_add(args->args, &addr_arg, 1);
+    grpc_channel_args *new_args = grpc_channel_args_copy_and_add_and_remove(
+        args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg,
+        1);
     gpr_free(addr_arg.value.string);
     sc_args.args = new_args;
     grpc_subchannel *subchannel = grpc_client_channel_factory_create_subchannel(
diff --git a/src/core/ext/lb_policy/round_robin/round_robin.c b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c
similarity index 95%
rename from src/core/ext/lb_policy/round_robin/round_robin.c
rename to src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c
index f2d1d46179a882883c38d859132204e40b27f8d2..4c17f9c08284c16b24ab6eb3f50e62ed9e0670b2 100644
--- a/src/core/ext/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c
@@ -63,8 +63,8 @@
 
 #include <grpc/support/alloc.h>
 
-#include "src/core/ext/client_channel/lb_policy_registry.h"
-#include "src/core/ext/client_channel/subchannel.h"
+#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/subchannel.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/debug/trace.h"
 #include "src/core/lib/iomgr/combiner.h"
@@ -320,13 +320,14 @@ static void rr_shutdown_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
   while ((pp = p->pending_picks)) {
     p->pending_picks = pp->next;
     *pp->target = NULL;
-    grpc_closure_sched(exec_ctx, pp->on_complete,
-                       GRPC_ERROR_CREATE("Channel Shutdown"));
+    grpc_closure_sched(
+        exec_ctx, pp->on_complete,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel Shutdown"));
     gpr_free(pp);
   }
   grpc_connectivity_state_set(
       exec_ctx, &p->state_tracker, GRPC_CHANNEL_SHUTDOWN,
-      GRPC_ERROR_CREATE("Channel Shutdown"), "rr_shutdown");
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel Shutdown"), "rr_shutdown");
   for (i = 0; i < p->num_subchannels; i++) {
     subchannel_data *sd = p->subchannels[i];
     grpc_subchannel_notify_on_state_change(exec_ctx, sd->subchannel, NULL, NULL,
@@ -345,9 +346,9 @@ static void rr_cancel_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     pending_pick *next = pp->next;
     if (pp->target == target) {
       *target = NULL;
-      grpc_closure_sched(
-          exec_ctx, pp->on_complete,
-          GRPC_ERROR_CREATE_REFERENCING("Pick cancelled", &error, 1));
+      grpc_closure_sched(exec_ctx, pp->on_complete,
+                         GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                             "Pick cancelled", &error, 1));
       gpr_free(pp);
     } else {
       pp->next = p->pending_picks;
@@ -371,9 +372,9 @@ static void rr_cancel_picks_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
         initial_metadata_flags_eq) {
       *pp->target = NULL;
-      grpc_closure_sched(
-          exec_ctx, pp->on_complete,
-          GRPC_ERROR_CREATE_REFERENCING("Pick cancelled", &error, 1));
+      grpc_closure_sched(exec_ctx, pp->on_complete,
+                         GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                             "Pick cancelled", &error, 1));
       gpr_free(pp);
     } else {
       pp->next = p->pending_picks;
@@ -413,7 +414,8 @@ static void rr_exit_idle_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
 
 static int rr_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
                           const grpc_lb_policy_pick_args *pick_args,
-                          grpc_connected_subchannel **target, void **user_data,
+                          grpc_connected_subchannel **target,
+                          grpc_call_context_element *context, void **user_data,
                           grpc_closure *on_complete) {
   round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
   pending_pick *pp;
@@ -661,8 +663,8 @@ static void rr_ping_one_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     grpc_connected_subchannel_ping(exec_ctx, target, closure);
     GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, target, "rr_picked");
   } else {
-    grpc_closure_sched(exec_ctx, closure,
-                       GRPC_ERROR_CREATE("Round Robin not connected"));
+    grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                              "Round Robin not connected"));
   }
 }
 
@@ -690,7 +692,9 @@ static grpc_lb_policy *round_robin_create(grpc_exec_ctx *exec_ctx,
    * addresses, since we don't know how to handle them. */
   const grpc_arg *arg =
       grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES);
-  GPR_ASSERT(arg != NULL && arg->type == GRPC_ARG_POINTER);
+  if (arg == NULL || arg->type != GRPC_ARG_POINTER) {
+    return NULL;
+  }
   grpc_lb_addresses *addresses = arg->value.pointer.p;
   size_t num_addrs = 0;
   for (size_t i = 0; i < addresses->num_addresses; i++) {
@@ -709,11 +713,13 @@ static grpc_lb_policy *round_robin_create(grpc_exec_ctx *exec_ctx,
     /* Skip balancer addresses, since we only know how to handle backends. */
     if (addresses->addresses[i].is_balancer) continue;
 
+    static const char *keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS};
     memset(&sc_args, 0, sizeof(grpc_subchannel_args));
     grpc_arg addr_arg =
         grpc_create_subchannel_address_arg(&addresses->addresses[i].address);
-    grpc_channel_args *new_args =
-        grpc_channel_args_copy_and_add(args->args, &addr_arg, 1);
+    grpc_channel_args *new_args = grpc_channel_args_copy_and_add_and_remove(
+        args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg,
+        1);
     gpr_free(addr_arg.value.string);
     sc_args.args = new_args;
     grpc_subchannel *subchannel = grpc_client_channel_factory_create_subchannel(
diff --git a/src/core/ext/client_channel/lb_policy_factory.c b/src/core/ext/filters/client_channel/lb_policy_factory.c
similarity index 82%
rename from src/core/ext/client_channel/lb_policy_factory.c
rename to src/core/ext/filters/client_channel/lb_policy_factory.c
index 7af9bb04112818bf74a72591fede31ac97f886a0..89b8bf895155d260098bf5222d1c89c426ffe9be 100644
--- a/src/core/ext/client_channel/lb_policy_factory.c
+++ b/src/core/ext/filters/client_channel/lb_policy_factory.c
@@ -36,16 +36,18 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/ext/client_channel/lb_policy_factory.h"
+#include "src/core/lib/channel/channel_args.h"
+
+#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/ext/filters/client_channel/parse_address.h"
 
 grpc_lb_addresses* grpc_lb_addresses_create(
     size_t num_addresses, const grpc_lb_user_data_vtable* user_data_vtable) {
-  grpc_lb_addresses* addresses = gpr_malloc(sizeof(grpc_lb_addresses));
+  grpc_lb_addresses* addresses = gpr_zalloc(sizeof(grpc_lb_addresses));
   addresses->num_addresses = num_addresses;
   addresses->user_data_vtable = user_data_vtable;
   const size_t addresses_size = sizeof(grpc_lb_address) * num_addresses;
-  addresses->addresses = gpr_malloc(addresses_size);
-  memset(addresses->addresses, 0, addresses_size);
+  addresses->addresses = gpr_zalloc(addresses_size);
   return addresses;
 }
 
@@ -69,7 +71,7 @@ grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses) {
 
 void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index,
                                    void* address, size_t address_len,
-                                   bool is_balancer, char* balancer_name,
+                                   bool is_balancer, const char* balancer_name,
                                    void* user_data) {
   GPR_ASSERT(index < addresses->num_addresses);
   if (user_data != NULL) GPR_ASSERT(addresses->user_data_vtable != NULL);
@@ -77,10 +79,22 @@ void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index,
   memcpy(target->address.addr, address, address_len);
   target->address.len = address_len;
   target->is_balancer = is_balancer;
-  target->balancer_name = balancer_name;
+  target->balancer_name = gpr_strdup(balancer_name);
   target->user_data = user_data;
 }
 
+bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses* addresses,
+                                            size_t index, const grpc_uri* uri,
+                                            bool is_balancer,
+                                            const char* balancer_name,
+                                            void* user_data) {
+  grpc_resolved_address address;
+  if (!grpc_parse_uri(uri, &address)) return false;
+  grpc_lb_addresses_set_address(addresses, index, address.addr, address.len,
+                                is_balancer, balancer_name, user_data);
+  return true;
+}
+
 int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1,
                           const grpc_lb_addresses* addresses2) {
   if (addresses1->num_addresses > addresses2->num_addresses) return 1;
@@ -147,6 +161,15 @@ grpc_arg grpc_lb_addresses_create_channel_arg(
   return arg;
 }
 
+grpc_lb_addresses* grpc_lb_addresses_find_channel_arg(
+    const grpc_channel_args* channel_args) {
+  const grpc_arg* lb_addresses_arg =
+      grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES);
+  if (lb_addresses_arg == NULL || lb_addresses_arg->type != GRPC_ARG_POINTER)
+    return NULL;
+  return lb_addresses_arg->value.pointer.p;
+}
+
 void grpc_lb_policy_factory_ref(grpc_lb_policy_factory* factory) {
   factory->vtable->ref(factory);
 }
diff --git a/src/core/ext/client_channel/lb_policy_factory.h b/src/core/ext/filters/client_channel/lb_policy_factory.h
similarity index 81%
rename from src/core/ext/client_channel/lb_policy_factory.h
rename to src/core/ext/filters/client_channel/lb_policy_factory.h
index 27c12c0d73dd8697ec719605ca5633debb0ac044..9d6c0fc1398c35150a31ed479e91515c73ac176d 100644
--- a/src/core/ext/client_channel/lb_policy_factory.h
+++ b/src/core/ext/filters/client_channel/lb_policy_factory.h
@@ -31,15 +31,16 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_LB_POLICY_FACTORY_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_LB_POLICY_FACTORY_H
-
-#include "src/core/ext/client_channel/client_channel_factory.h"
-#include "src/core/ext/client_channel/lb_policy.h"
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_FACTORY_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_FACTORY_H
 
 #include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 
+#include "src/core/ext/filters/client_channel/client_channel_factory.h"
+#include "src/core/ext/filters/client_channel/lb_policy.h"
+#include "src/core/ext/filters/client_channel/uri_parser.h"
+
 // Channel arg key for grpc_lb_addresses.
 #define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses"
 
@@ -88,9 +89,18 @@ grpc_lb_addresses *grpc_lb_addresses_copy(const grpc_lb_addresses *addresses);
  * Takes ownership of \a balancer_name. */
 void grpc_lb_addresses_set_address(grpc_lb_addresses *addresses, size_t index,
                                    void *address, size_t address_len,
-                                   bool is_balancer, char *balancer_name,
+                                   bool is_balancer, const char *balancer_name,
                                    void *user_data);
 
+/** Sets the value of the address at index \a index of \a addresses from \a uri.
+ * Returns true upon success, false otherwise. Takes ownership of \a
+ * balancer_name. */
+bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses *addresses,
+                                            size_t index, const grpc_uri *uri,
+                                            bool is_balancer,
+                                            const char *balancer_name,
+                                            void *user_data);
+
 /** Compares \a addresses1 and \a addresses2. */
 int grpc_lb_addresses_cmp(const grpc_lb_addresses *addresses1,
                           const grpc_lb_addresses *addresses2);
@@ -103,6 +113,10 @@ void grpc_lb_addresses_destroy(grpc_exec_ctx *exec_ctx,
 grpc_arg grpc_lb_addresses_create_channel_arg(
     const grpc_lb_addresses *addresses);
 
+/** Returns the \a grpc_lb_addresses instance in \a channel_args or NULL */
+grpc_lb_addresses *grpc_lb_addresses_find_channel_arg(
+    const grpc_channel_args *channel_args);
+
 /** Arguments passed to LB policies. */
 typedef struct grpc_lb_policy_args {
   grpc_client_channel_factory *client_channel_factory;
@@ -131,4 +145,4 @@ grpc_lb_policy *grpc_lb_policy_factory_create_lb_policy(
     grpc_exec_ctx *exec_ctx, grpc_lb_policy_factory *factory,
     grpc_lb_policy_args *args);
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_LB_POLICY_FACTORY_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_FACTORY_H */
diff --git a/src/core/ext/client_channel/lb_policy_registry.c b/src/core/ext/filters/client_channel/lb_policy_registry.c
similarity index 97%
rename from src/core/ext/client_channel/lb_policy_registry.c
rename to src/core/ext/filters/client_channel/lb_policy_registry.c
index 90c149d947b2e06c22ad00431c906d0b88f6db0c..1376673bcab4783888710773d1baf4fcaf74d308 100644
--- a/src/core/ext/client_channel/lb_policy_registry.c
+++ b/src/core/ext/filters/client_channel/lb_policy_registry.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/ext/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
 
 #include <string.h>
 
diff --git a/src/core/ext/client_channel/lb_policy_registry.h b/src/core/ext/filters/client_channel/lb_policy_registry.h
similarity index 89%
rename from src/core/ext/client_channel/lb_policy_registry.h
rename to src/core/ext/filters/client_channel/lb_policy_registry.h
index 21c468e02107656a3a99c287f1d67bddbba96f30..dfdec1347fa3f4520c7e92436be6926369b32335 100644
--- a/src/core/ext/client_channel/lb_policy_registry.h
+++ b/src/core/ext/filters/client_channel/lb_policy_registry.h
@@ -31,10 +31,10 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_LB_POLICY_REGISTRY_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_LB_POLICY_REGISTRY_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_REGISTRY_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_REGISTRY_H
 
-#include "src/core/ext/client_channel/lb_policy_factory.h"
+#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
 
 /** Initialize the registry and set \a default_factory as the factory to be
@@ -52,4 +52,4 @@ void grpc_register_lb_policy(grpc_lb_policy_factory *factory);
 grpc_lb_policy *grpc_lb_policy_create(grpc_exec_ctx *exec_ctx, const char *name,
                                       grpc_lb_policy_args *args);
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_LB_POLICY_REGISTRY_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_REGISTRY_H */
diff --git a/src/core/ext/client_channel/parse_address.c b/src/core/ext/filters/client_channel/parse_address.c
similarity index 60%
rename from src/core/ext/client_channel/parse_address.c
rename to src/core/ext/filters/client_channel/parse_address.c
index 8e4da03de07b4dd5d97cf81f45921090fb8179e3..edc6ce697d858516357d204830c38cd2bb3cec0f 100644
--- a/src/core/ext/client_channel/parse_address.c
+++ b/src/core/ext/filters/client_channel/parse_address.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/ext/client_channel/parse_address.h"
+#include "src/core/ext/filters/client_channel/parse_address.h"
 #include "src/core/lib/iomgr/sockaddr.h"
 
 #include <stdio.h>
@@ -44,10 +44,16 @@
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
+#include "src/core/lib/support/string.h"
 
 #ifdef GRPC_HAVE_UNIX_SOCKET
 
-int parse_unix(grpc_uri *uri, grpc_resolved_address *resolved_addr) {
+bool grpc_parse_unix(const grpc_uri *uri,
+                     grpc_resolved_address *resolved_addr) {
+  if (strcmp("unix", uri->scheme) != 0) {
+    gpr_log(GPR_ERROR, "Expected 'unix' scheme, got '%s'", uri->scheme);
+    return false;
+  }
   struct sockaddr_un *un = (struct sockaddr_un *)resolved_addr->addr;
   const size_t maxlen = sizeof(un->sun_path);
   const size_t path_len = strnlen(uri->path, maxlen);
@@ -60,21 +66,29 @@ int parse_unix(grpc_uri *uri, grpc_resolved_address *resolved_addr) {
 
 #else /* GRPC_HAVE_UNIX_SOCKET */
 
-int parse_unix(grpc_uri *uri, grpc_resolved_address *resolved_addr) { abort(); }
+bool grpc_parse_unix(const grpc_uri *uri,
+                     grpc_resolved_address *resolved_addr) {
+  abort();
+}
 
 #endif /* GRPC_HAVE_UNIX_SOCKET */
 
-int parse_ipv4(grpc_uri *uri, grpc_resolved_address *resolved_addr) {
+bool grpc_parse_ipv4(const grpc_uri *uri,
+                     grpc_resolved_address *resolved_addr) {
+  if (strcmp("ipv4", uri->scheme) != 0) {
+    gpr_log(GPR_ERROR, "Expected 'ipv4' scheme, got '%s'", uri->scheme);
+    return false;
+  }
   const char *host_port = uri->path;
   char *host;
   char *port;
   int port_num;
-  int result = 0;
+  bool result = false;
   struct sockaddr_in *in = (struct sockaddr_in *)resolved_addr->addr;
 
   if (*host_port == '/') ++host_port;
   if (!gpr_split_host_port(host_port, &host, &port)) {
-    return 0;
+    return false;
   }
 
   memset(resolved_addr, 0, sizeof(grpc_resolved_address));
@@ -97,14 +111,19 @@ int parse_ipv4(grpc_uri *uri, grpc_resolved_address *resolved_addr) {
     goto done;
   }
 
-  result = 1;
+  result = true;
 done:
   gpr_free(host);
   gpr_free(port);
   return result;
 }
 
-int parse_ipv6(grpc_uri *uri, grpc_resolved_address *resolved_addr) {
+bool grpc_parse_ipv6(const grpc_uri *uri,
+                     grpc_resolved_address *resolved_addr) {
+  if (strcmp("ipv6", uri->scheme) != 0) {
+    gpr_log(GPR_ERROR, "Expected 'ipv6' scheme, got '%s'", uri->scheme);
+    return false;
+  }
   const char *host_port = uri->path;
   char *host;
   char *port;
@@ -120,9 +139,33 @@ int parse_ipv6(grpc_uri *uri, grpc_resolved_address *resolved_addr) {
   memset(in6, 0, sizeof(*in6));
   resolved_addr->len = sizeof(*in6);
   in6->sin6_family = AF_INET6;
-  if (inet_pton(AF_INET6, host, &in6->sin6_addr) == 0) {
-    gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host);
-    goto done;
+
+  /* Handle the RFC6874 syntax for IPv6 zone identifiers. */
+  char *host_end = (char *)gpr_memrchr(host, '%', strlen(host));
+  if (host_end != NULL) {
+    GPR_ASSERT(host_end >= host);
+    char host_without_scope[INET6_ADDRSTRLEN];
+    size_t host_without_scope_len = (size_t)(host_end - host);
+    uint32_t sin6_scope_id = 0;
+    strncpy(host_without_scope, host, host_without_scope_len);
+    host_without_scope[host_without_scope_len] = '\0';
+    if (inet_pton(AF_INET6, host_without_scope, &in6->sin6_addr) == 0) {
+      gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host_without_scope);
+      goto done;
+    }
+    if (gpr_parse_bytes_to_uint32(host_end + 1,
+                                  strlen(host) - host_without_scope_len - 1,
+                                  &sin6_scope_id) == 0) {
+      gpr_log(GPR_ERROR, "invalid ipv6 scope id: '%s'", host_end + 1);
+      goto done;
+    }
+    // Handle "sin6_scope_id" being type "u_long". See grpc issue ##10027.
+    in6->sin6_scope_id = sin6_scope_id;
+  } else {
+    if (inet_pton(AF_INET6, host, &in6->sin6_addr) == 0) {
+      gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host);
+      goto done;
+    }
   }
 
   if (port != NULL) {
@@ -143,3 +186,15 @@ done:
   gpr_free(port);
   return result;
 }
+
+bool grpc_parse_uri(const grpc_uri *uri, grpc_resolved_address *resolved_addr) {
+  if (strcmp("unix", uri->scheme) == 0) {
+    return grpc_parse_unix(uri, resolved_addr);
+  } else if (strcmp("ipv4", uri->scheme) == 0) {
+    return grpc_parse_ipv4(uri, resolved_addr);
+  } else if (strcmp("ipv6", uri->scheme) == 0) {
+    return grpc_parse_ipv6(uri, resolved_addr);
+  }
+  gpr_log(GPR_ERROR, "Can't parse scheme '%s'", uri->scheme);
+  return false;
+}
diff --git a/src/core/ext/client_channel/parse_address.h b/src/core/ext/filters/client_channel/parse_address.h
similarity index 63%
rename from src/core/ext/client_channel/parse_address.h
rename to src/core/ext/filters/client_channel/parse_address.h
index bf99c5298a2b0651742f3ebf607656f0cfc727a4..fa7ea33a00baedccf5165667493f126c2554e530 100644
--- a/src/core/ext/client_channel/parse_address.h
+++ b/src/core/ext/filters/client_channel/parse_address.h
@@ -31,24 +31,27 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_PARSE_ADDRESS_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_PARSE_ADDRESS_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_PARSE_ADDRESS_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_PARSE_ADDRESS_H
 
 #include <stddef.h>
 
-#include "src/core/ext/client_channel/uri_parser.h"
+#include "src/core/ext/filters/client_channel/uri_parser.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 
-/** Populate \a addr and \a len from \a uri, whose path is expected to contain a
+/** Populate \a resolved_addr from \a uri, whose path is expected to contain a
  * unix socket path. Returns true upon success. */
-int parse_unix(grpc_uri *uri, grpc_resolved_address *resolved_addr);
+bool grpc_parse_unix(const grpc_uri *uri, grpc_resolved_address *resolved_addr);
 
-/** Populate /a addr and \a len from \a uri, whose path is expected to contain a
- * host:port pair. Returns true upon success. */
-int parse_ipv4(grpc_uri *uri, grpc_resolved_address *resolved_addr);
+/** Populate \a resolved_addr from \a uri, whose path is expected to contain an
+ * IPv4 host:port pair. Returns true upon success. */
+bool grpc_parse_ipv4(const grpc_uri *uri, grpc_resolved_address *resolved_addr);
 
-/** Populate /a addr and \a len from \a uri, whose path is expected to contain a
- * host:port pair. Returns true upon success. */
-int parse_ipv6(grpc_uri *uri, grpc_resolved_address *resolved_addr);
+/** Populate \a resolved_addr from \a uri, whose path is expected to contain an
+ * IPv6 host:port pair. Returns true upon success. */
+bool grpc_parse_ipv6(const grpc_uri *uri, grpc_resolved_address *resolved_addr);
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_PARSE_ADDRESS_H */
+/** Populate \a resolved_addr from \a uri. Returns true upon success. */
+bool grpc_parse_uri(const grpc_uri *uri, grpc_resolved_address *resolved_addr);
+
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_PARSE_ADDRESS_H */
diff --git a/src/core/ext/client_channel/proxy_mapper.c b/src/core/ext/filters/client_channel/proxy_mapper.c
similarity index 97%
rename from src/core/ext/client_channel/proxy_mapper.c
rename to src/core/ext/filters/client_channel/proxy_mapper.c
index f92afe847bfc384594318e17a655c6257c914ddf..6dddd3c6da03c5c2e8a25bebbe1c37aa63e401f5 100644
--- a/src/core/ext/client_channel/proxy_mapper.c
+++ b/src/core/ext/filters/client_channel/proxy_mapper.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/ext/client_channel/proxy_mapper.h"
+#include "src/core/ext/filters/client_channel/proxy_mapper.h"
 
 void grpc_proxy_mapper_init(const grpc_proxy_mapper_vtable* vtable,
                             grpc_proxy_mapper* mapper) {
diff --git a/src/core/ext/client_channel/proxy_mapper.h b/src/core/ext/filters/client_channel/proxy_mapper.h
similarity index 95%
rename from src/core/ext/client_channel/proxy_mapper.h
rename to src/core/ext/filters/client_channel/proxy_mapper.h
index 6e4607fe4d9553a63ee78998b3ed55d8b558ff4a..d0c47d3090fda1b4388a00c6100b24eb5434e315 100644
--- a/src/core/ext/client_channel/proxy_mapper.h
+++ b/src/core/ext/filters/client_channel/proxy_mapper.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_PROXY_MAPPER_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_PROXY_MAPPER_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_PROXY_MAPPER_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_PROXY_MAPPER_H
 
 #include <stdbool.h>
 
@@ -86,4 +86,4 @@ bool grpc_proxy_mapper_map_address(grpc_exec_ctx* exec_ctx,
 
 void grpc_proxy_mapper_destroy(grpc_proxy_mapper* mapper);
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_PROXY_MAPPER_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_PROXY_MAPPER_H */
diff --git a/src/core/ext/client_channel/proxy_mapper_registry.c b/src/core/ext/filters/client_channel/proxy_mapper_registry.c
similarity index 90%
rename from src/core/ext/client_channel/proxy_mapper_registry.c
rename to src/core/ext/filters/client_channel/proxy_mapper_registry.c
index 2c44b9d4903b286a27b7312ad3da4d5e0df65aff..7a39289a844b1521546577dfe3a380f004dd9b9a 100644
--- a/src/core/ext/client_channel/proxy_mapper_registry.c
+++ b/src/core/ext/filters/client_channel/proxy_mapper_registry.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/ext/client_channel/proxy_mapper_registry.h"
+#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
 
 #include <string.h>
 
@@ -94,6 +94,14 @@ static void grpc_proxy_mapper_list_destroy(grpc_proxy_mapper_list* list) {
     grpc_proxy_mapper_destroy(list->list[i]);
   }
   gpr_free(list->list);
+  // Clean up in case we re-initialze later.
+  // TODO(ctiller): This should ideally live in
+  // grpc_proxy_mapper_registry_init().  However, if we did this there,
+  // then we would do it AFTER we start registering proxy mappers from
+  // third-party plugins, so they'd never show up (and would leak memory).
+  // We probably need some sort of dependency system for plugins to fix
+  // this.
+  memset(list, 0, sizeof(*list));
 }
 
 //
@@ -102,9 +110,7 @@ static void grpc_proxy_mapper_list_destroy(grpc_proxy_mapper_list* list) {
 
 static grpc_proxy_mapper_list g_proxy_mapper_list;
 
-void grpc_proxy_mapper_registry_init() {
-  memset(&g_proxy_mapper_list, 0, sizeof(g_proxy_mapper_list));
-}
+void grpc_proxy_mapper_registry_init() {}
 
 void grpc_proxy_mapper_registry_shutdown() {
   grpc_proxy_mapper_list_destroy(&g_proxy_mapper_list);
diff --git a/src/core/ext/client_channel/proxy_mapper_registry.h b/src/core/ext/filters/client_channel/proxy_mapper_registry.h
similarity index 90%
rename from src/core/ext/client_channel/proxy_mapper_registry.h
rename to src/core/ext/filters/client_channel/proxy_mapper_registry.h
index 742b57a2d49a436737eeb1f54d61d0874e8c7b23..8b5686d664c84fed8b11bff717cbabdbe48c4d1c 100644
--- a/src/core/ext/client_channel/proxy_mapper_registry.h
+++ b/src/core/ext/filters/client_channel/proxy_mapper_registry.h
@@ -31,10 +31,10 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_PROXY_MAPPER_REGISTRY_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_PROXY_MAPPER_REGISTRY_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_PROXY_MAPPER_REGISTRY_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_PROXY_MAPPER_REGISTRY_H
 
-#include "src/core/ext/client_channel/proxy_mapper.h"
+#include "src/core/ext/filters/client_channel/proxy_mapper.h"
 
 void grpc_proxy_mapper_registry_init();
 void grpc_proxy_mapper_registry_shutdown();
@@ -56,4 +56,4 @@ bool grpc_proxy_mappers_map_address(grpc_exec_ctx* exec_ctx,
                                     grpc_resolved_address** new_address,
                                     grpc_channel_args** new_args);
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_PROXY_MAPPER_REGISTRY_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_PROXY_MAPPER_REGISTRY_H */
diff --git a/src/core/ext/client_channel/resolver.c b/src/core/ext/filters/client_channel/resolver.c
similarity index 98%
rename from src/core/ext/client_channel/resolver.c
rename to src/core/ext/filters/client_channel/resolver.c
index b1a1faa6c962af594d6a48d5491dd8cd5f5f6a52..cafa2837f3b3f750cba79a9ed75f4bcbe1e0736d 100644
--- a/src/core/ext/client_channel/resolver.c
+++ b/src/core/ext/filters/client_channel/resolver.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/ext/client_channel/resolver.h"
+#include "src/core/ext/filters/client_channel/resolver.h"
 #include "src/core/lib/iomgr/combiner.h"
 
 void grpc_resolver_init(grpc_resolver *resolver,
diff --git a/src/core/ext/client_channel/resolver.h b/src/core/ext/filters/client_channel/resolver.h
similarity index 94%
rename from src/core/ext/client_channel/resolver.h
rename to src/core/ext/filters/client_channel/resolver.h
index bbba424ca5d716ac82e38389cff66b55f772562f..55f9124b3ab5373e081e9d817979bbb954279db8 100644
--- a/src/core/ext/client_channel/resolver.h
+++ b/src/core/ext/filters/client_channel/resolver.h
@@ -31,10 +31,10 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_H
 
-#include "src/core/ext/client_channel/subchannel.h"
+#include "src/core/ext/filters/client_channel/subchannel.h"
 #include "src/core/lib/iomgr/iomgr.h"
 
 typedef struct grpc_resolver grpc_resolver;
@@ -98,4 +98,4 @@ void grpc_resolver_next_locked(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
                                grpc_channel_args **result,
                                grpc_closure *on_complete);
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_H */
diff --git a/src/core/ext/resolver/README.md b/src/core/ext/filters/client_channel/resolver/README.md
similarity index 100%
rename from src/core/ext/resolver/README.md
rename to src/core/ext/filters/client_channel/resolver/README.md
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c
new file mode 100644
index 0000000000000000000000000000000000000000..ffaeeed3242c492d31a56358ab8d742e3ff0e73c
--- /dev/null
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c
@@ -0,0 +1,350 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+#if GRPC_ARES == 1 && !defined(GRPC_UV)
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
+#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/iomgr/combiner.h"
+#include "src/core/lib/iomgr/resolve_address.h"
+#include "src/core/lib/iomgr/timer.h"
+#include "src/core/lib/support/backoff.h"
+#include "src/core/lib/support/env.h"
+#include "src/core/lib/support/string.h"
+
+#define GRPC_DNS_MIN_CONNECT_TIMEOUT_SECONDS 1
+#define GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS 1
+#define GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER 1.6
+#define GRPC_DNS_RECONNECT_MAX_BACKOFF_SECONDS 120
+#define GRPC_DNS_RECONNECT_JITTER 0.2
+
+typedef struct {
+  /** base class: must be first */
+  grpc_resolver base;
+  /** name to resolve (usually the same as target_name) */
+  char *name_to_resolve;
+  /** default port to use */
+  char *default_port;
+  /** channel args. */
+  grpc_channel_args *channel_args;
+  /** pollset_set to drive the name resolution process */
+  grpc_pollset_set *interested_parties;
+
+  /** Closures used by the combiner */
+  grpc_closure dns_ares_on_retry_timer_locked;
+  grpc_closure dns_ares_on_resolved_locked;
+
+  /** Combiner guarding the rest of the state */
+  grpc_combiner *combiner;
+  /** are we currently resolving? */
+  bool resolving;
+  /** which version of the result have we published? */
+  int published_version;
+  /** which version of the result is current? */
+  int resolved_version;
+  /** pending next completion, or NULL */
+  grpc_closure *next_completion;
+  /** target result address for next completion */
+  grpc_channel_args **target_result;
+  /** current (fully resolved) result */
+  grpc_channel_args *resolved_result;
+  /** retry timer */
+  bool have_retry_timer;
+  grpc_timer retry_timer;
+  /** retry backoff state */
+  gpr_backoff backoff_state;
+
+  /** currently resolving addresses */
+  grpc_resolved_addresses *addresses;
+} ares_dns_resolver;
+
+static void dns_ares_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
+
+static void dns_ares_start_resolving_locked(grpc_exec_ctx *exec_ctx,
+                                            ares_dns_resolver *r);
+static void dns_ares_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
+                                              ares_dns_resolver *r);
+
+static void dns_ares_shutdown_locked(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
+static void dns_ares_channel_saw_error_locked(grpc_exec_ctx *exec_ctx,
+                                              grpc_resolver *r);
+static void dns_ares_next_locked(grpc_exec_ctx *exec_ctx, grpc_resolver *r,
+                                 grpc_channel_args **target_result,
+                                 grpc_closure *on_complete);
+
+static const grpc_resolver_vtable dns_ares_resolver_vtable = {
+    dns_ares_destroy, dns_ares_shutdown_locked,
+    dns_ares_channel_saw_error_locked, dns_ares_next_locked};
+
+static void dns_ares_shutdown_locked(grpc_exec_ctx *exec_ctx,
+                                     grpc_resolver *resolver) {
+  ares_dns_resolver *r = (ares_dns_resolver *)resolver;
+  if (r->have_retry_timer) {
+    grpc_timer_cancel(exec_ctx, &r->retry_timer);
+  }
+  if (r->next_completion != NULL) {
+    *r->target_result = NULL;
+    grpc_closure_sched(
+        exec_ctx, r->next_completion,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resolver Shutdown"));
+    r->next_completion = NULL;
+  }
+}
+
+static void dns_ares_channel_saw_error_locked(grpc_exec_ctx *exec_ctx,
+                                              grpc_resolver *resolver) {
+  ares_dns_resolver *r = (ares_dns_resolver *)resolver;
+  if (!r->resolving) {
+    gpr_backoff_reset(&r->backoff_state);
+    dns_ares_start_resolving_locked(exec_ctx, r);
+  }
+}
+
+static void dns_ares_on_retry_timer_locked(grpc_exec_ctx *exec_ctx, void *arg,
+                                           grpc_error *error) {
+  ares_dns_resolver *r = arg;
+  r->have_retry_timer = false;
+  if (error == GRPC_ERROR_NONE) {
+    if (!r->resolving) {
+      dns_ares_start_resolving_locked(exec_ctx, r);
+    }
+  }
+  GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "retry-timer");
+}
+
+static void dns_ares_on_resolved_locked(grpc_exec_ctx *exec_ctx, void *arg,
+                                        grpc_error *error) {
+  ares_dns_resolver *r = arg;
+  grpc_channel_args *result = NULL;
+  GPR_ASSERT(r->resolving);
+  r->resolving = false;
+  if (r->addresses != NULL) {
+    grpc_lb_addresses *addresses = grpc_lb_addresses_create(
+        r->addresses->naddrs, NULL /* user_data_vtable */);
+    for (size_t i = 0; i < r->addresses->naddrs; ++i) {
+      grpc_lb_addresses_set_address(
+          addresses, i, &r->addresses->addrs[i].addr,
+          r->addresses->addrs[i].len, false /* is_balancer */,
+          NULL /* balancer_name */, NULL /* user_data */);
+    }
+    grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(addresses);
+    result = grpc_channel_args_copy_and_add(r->channel_args, &new_arg, 1);
+    grpc_resolved_addresses_destroy(r->addresses);
+    grpc_lb_addresses_destroy(exec_ctx, addresses);
+  } else {
+    gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
+    gpr_timespec next_try = gpr_backoff_step(&r->backoff_state, now);
+    gpr_timespec timeout = gpr_time_sub(next_try, now);
+    gpr_log(GPR_INFO, "dns resolution failed (will retry): %s",
+            grpc_error_string(error));
+    GPR_ASSERT(!r->have_retry_timer);
+    r->have_retry_timer = true;
+    GRPC_RESOLVER_REF(&r->base, "retry-timer");
+    if (gpr_time_cmp(timeout, gpr_time_0(timeout.clock_type)) > 0) {
+      gpr_log(GPR_DEBUG, "retrying in %" PRId64 ".%09d seconds", timeout.tv_sec,
+              timeout.tv_nsec);
+    } else {
+      gpr_log(GPR_DEBUG, "retrying immediately");
+    }
+    grpc_timer_init(exec_ctx, &r->retry_timer, next_try,
+                    &r->dns_ares_on_retry_timer_locked, now);
+  }
+  if (r->resolved_result != NULL) {
+    grpc_channel_args_destroy(exec_ctx, r->resolved_result);
+  }
+  r->resolved_result = result;
+  r->resolved_version++;
+  dns_ares_maybe_finish_next_locked(exec_ctx, r);
+  GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "dns-resolving");
+}
+
+static void dns_ares_next_locked(grpc_exec_ctx *exec_ctx,
+                                 grpc_resolver *resolver,
+                                 grpc_channel_args **target_result,
+                                 grpc_closure *on_complete) {
+  gpr_log(GPR_DEBUG, "dns_ares_next is called.");
+  ares_dns_resolver *r = (ares_dns_resolver *)resolver;
+  GPR_ASSERT(!r->next_completion);
+  r->next_completion = on_complete;
+  r->target_result = target_result;
+  if (r->resolved_version == 0 && !r->resolving) {
+    gpr_backoff_reset(&r->backoff_state);
+    dns_ares_start_resolving_locked(exec_ctx, r);
+  } else {
+    dns_ares_maybe_finish_next_locked(exec_ctx, r);
+  }
+}
+
+static void dns_ares_start_resolving_locked(grpc_exec_ctx *exec_ctx,
+                                            ares_dns_resolver *r) {
+  GRPC_RESOLVER_REF(&r->base, "dns-resolving");
+  GPR_ASSERT(!r->resolving);
+  r->resolving = true;
+  r->addresses = NULL;
+  grpc_resolve_address(exec_ctx, r->name_to_resolve, r->default_port,
+                       r->interested_parties, &r->dns_ares_on_resolved_locked,
+                       &r->addresses);
+}
+
+static void dns_ares_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
+                                              ares_dns_resolver *r) {
+  if (r->next_completion != NULL &&
+      r->resolved_version != r->published_version) {
+    *r->target_result = r->resolved_result == NULL
+                            ? NULL
+                            : grpc_channel_args_copy(r->resolved_result);
+    grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
+    r->next_completion = NULL;
+    r->published_version = r->resolved_version;
+  }
+}
+
+static void dns_ares_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
+  gpr_log(GPR_DEBUG, "dns_ares_destroy");
+  ares_dns_resolver *r = (ares_dns_resolver *)gr;
+  if (r->resolved_result != NULL) {
+    grpc_channel_args_destroy(exec_ctx, r->resolved_result);
+  }
+  grpc_pollset_set_destroy(exec_ctx, r->interested_parties);
+  gpr_free(r->name_to_resolve);
+  gpr_free(r->default_port);
+  grpc_channel_args_destroy(exec_ctx, r->channel_args);
+  gpr_free(r);
+}
+
+static grpc_resolver *dns_ares_create(grpc_exec_ctx *exec_ctx,
+                                      grpc_resolver_args *args,
+                                      const char *default_port) {
+  // Get name from args.
+  const char *path = args->uri->path;
+  if (0 != strcmp(args->uri->authority, "")) {
+    gpr_log(GPR_ERROR, "authority based dns uri's not supported");
+    return NULL;
+  }
+  if (path[0] == '/') ++path;
+  // Create resolver.
+  ares_dns_resolver *r = gpr_zalloc(sizeof(ares_dns_resolver));
+  grpc_resolver_init(&r->base, &dns_ares_resolver_vtable, args->combiner);
+  r->name_to_resolve = gpr_strdup(path);
+  r->default_port = gpr_strdup(default_port);
+  r->channel_args = grpc_channel_args_copy(args->args);
+  r->interested_parties = grpc_pollset_set_create();
+  if (args->pollset_set != NULL) {
+    grpc_pollset_set_add_pollset_set(exec_ctx, r->interested_parties,
+                                     args->pollset_set);
+  }
+  gpr_backoff_init(&r->backoff_state, GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS,
+                   GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER,
+                   GRPC_DNS_RECONNECT_JITTER,
+                   GRPC_DNS_MIN_CONNECT_TIMEOUT_SECONDS * 1000,
+                   GRPC_DNS_RECONNECT_MAX_BACKOFF_SECONDS * 1000);
+  grpc_closure_init(&r->dns_ares_on_retry_timer_locked,
+                    dns_ares_on_retry_timer_locked, r,
+                    grpc_combiner_scheduler(r->base.combiner, false));
+  grpc_closure_init(&r->dns_ares_on_resolved_locked,
+                    dns_ares_on_resolved_locked, r,
+                    grpc_combiner_scheduler(r->base.combiner, false));
+  return &r->base;
+}
+
+/*
+ * FACTORY
+ */
+
+static void dns_ares_factory_ref(grpc_resolver_factory *factory) {}
+
+static void dns_ares_factory_unref(grpc_resolver_factory *factory) {}
+
+static grpc_resolver *dns_factory_create_resolver(
+    grpc_exec_ctx *exec_ctx, grpc_resolver_factory *factory,
+    grpc_resolver_args *args) {
+  return dns_ares_create(exec_ctx, args, "https");
+}
+
+static char *dns_ares_factory_get_default_host_name(
+    grpc_resolver_factory *factory, grpc_uri *uri) {
+  const char *path = uri->path;
+  if (path[0] == '/') ++path;
+  return gpr_strdup(path);
+}
+
+static const grpc_resolver_factory_vtable dns_ares_factory_vtable = {
+    dns_ares_factory_ref, dns_ares_factory_unref, dns_factory_create_resolver,
+    dns_ares_factory_get_default_host_name, "dns"};
+static grpc_resolver_factory dns_resolver_factory = {&dns_ares_factory_vtable};
+
+static grpc_resolver_factory *dns_ares_resolver_factory_create() {
+  return &dns_resolver_factory;
+}
+
+void grpc_resolver_dns_ares_init(void) {
+  char *resolver = gpr_getenv("GRPC_DNS_RESOLVER");
+  /* TODO(zyc): Turn on c-ares based resolver by default after the address
+     sorter and the CNAME support are added. */
+  if (resolver != NULL && gpr_stricmp(resolver, "ares") == 0) {
+    grpc_error *error = grpc_ares_init();
+    if (error != GRPC_ERROR_NONE) {
+      GRPC_LOG_IF_ERROR("ares_library_init() failed", error);
+      return;
+    }
+    grpc_resolve_address = grpc_resolve_address_ares;
+    grpc_register_resolver_type(dns_ares_resolver_factory_create());
+  }
+  gpr_free(resolver);
+}
+
+void grpc_resolver_dns_ares_shutdown(void) {
+  char *resolver = gpr_getenv("GRPC_DNS_RESOLVER");
+  if (resolver != NULL && gpr_stricmp(resolver, "ares") == 0) {
+    grpc_ares_cleanup();
+  }
+  gpr_free(resolver);
+}
+
+#else /* GRPC_ARES == 1 && !defined(GRPC_UV) */
+
+void grpc_resolver_dns_ares_init(void) {}
+
+void grpc_resolver_dns_ares_shutdown(void) {}
+
+#endif /* GRPC_ARES == 1 && !defined(GRPC_UV) */
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
new file mode 100644
index 0000000000000000000000000000000000000000..aa88940021d1561b6dd3ceafddad45d7e7213c5a
--- /dev/null
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
@@ -0,0 +1,66 @@
+/*
+ *
+ * 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_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H
+
+#include <ares.h>
+
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/iomgr/pollset_set.h"
+
+typedef struct grpc_ares_ev_driver grpc_ares_ev_driver;
+
+/* Start \a ev_driver. It will keep working until all IO on its ares_channel is
+   done, or grpc_ares_ev_driver_destroy() is called. It may notify the callbacks
+   bound to its ares_channel when necessary. */
+void grpc_ares_ev_driver_start(grpc_exec_ctx *exec_ctx,
+                               grpc_ares_ev_driver *ev_driver);
+
+/* Returns the ares_channel owned by \a ev_driver. To bind a c-ares query to
+   \a ev_driver, use the ares_channel owned by \a ev_driver as the arg of the
+   query. */
+ares_channel *grpc_ares_ev_driver_get_channel(grpc_ares_ev_driver *ev_driver);
+
+/* Creates a new grpc_ares_ev_driver. Returns GRPC_ERROR_NONE if \a ev_driver is
+   created successfully. */
+grpc_error *grpc_ares_ev_driver_create(grpc_ares_ev_driver **ev_driver,
+                                       grpc_pollset_set *pollset_set);
+
+/* Destroys \a ev_driver asynchronously. Pending lookups made on \a ev_driver
+   will be cancelled and their on_done callbacks will be invoked with a status
+   of ARES_ECANCELLED. */
+void grpc_ares_ev_driver_destroy(grpc_ares_ev_driver *ev_driver);
+
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H \
+          */
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
new file mode 100644
index 0000000000000000000000000000000000000000..1e4f3eb5ab545332d75b893115fba9f77f50610d
--- /dev/null
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
@@ -0,0 +1,319 @@
+/*
+ *
+ * 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 <grpc/support/port_platform.h>
+#include "src/core/lib/iomgr/port.h"
+#if GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET)
+
+#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
+#include "src/core/lib/iomgr/ev_posix.h"
+#include "src/core/lib/iomgr/iomgr_internal.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
+#include "src/core/lib/support/string.h"
+
+typedef struct fd_node {
+  /** the owner of this fd node */
+  grpc_ares_ev_driver *ev_driver;
+  /** the grpc_fd owned by this fd node */
+  grpc_fd *grpc_fd;
+  /** a closure wrapping on_readable_cb, which should be invoked when the
+      grpc_fd in this node becomes readable. */
+  grpc_closure read_closure;
+  /** a closure wrapping on_writable_cb, which should be invoked when the
+      grpc_fd in this node becomes writable. */
+  grpc_closure write_closure;
+  /** next fd node in the list */
+  struct fd_node *next;
+
+  /** mutex guarding the rest of the state */
+  gpr_mu mu;
+  /** if the readable closure has been registered */
+  bool readable_registered;
+  /** if the writable closure has been registered */
+  bool writable_registered;
+} fd_node;
+
+struct grpc_ares_ev_driver {
+  /** the ares_channel owned by this event driver */
+  ares_channel channel;
+  /** pollset set for driving the IO events of the channel */
+  grpc_pollset_set *pollset_set;
+  /** refcount of the event driver */
+  gpr_refcount refs;
+
+  /** mutex guarding the rest of the state */
+  gpr_mu mu;
+  /** a list of grpc_fd that this event driver is currently using. */
+  fd_node *fds;
+  /** is this event driver currently working? */
+  bool working;
+  /** is this event driver being shut down */
+  bool shutting_down;
+};
+
+static void grpc_ares_notify_on_event_locked(grpc_exec_ctx *exec_ctx,
+                                             grpc_ares_ev_driver *ev_driver);
+
+static grpc_ares_ev_driver *grpc_ares_ev_driver_ref(
+    grpc_ares_ev_driver *ev_driver) {
+  gpr_log(GPR_DEBUG, "Ref ev_driver %" PRIuPTR, (uintptr_t)ev_driver);
+  gpr_ref(&ev_driver->refs);
+  return ev_driver;
+}
+
+static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver *ev_driver) {
+  gpr_log(GPR_DEBUG, "Unref ev_driver %" PRIuPTR, (uintptr_t)ev_driver);
+  if (gpr_unref(&ev_driver->refs)) {
+    gpr_log(GPR_DEBUG, "destroy ev_driver %" PRIuPTR, (uintptr_t)ev_driver);
+    GPR_ASSERT(ev_driver->fds == NULL);
+    gpr_mu_destroy(&ev_driver->mu);
+    ares_destroy(ev_driver->channel);
+    gpr_free(ev_driver);
+  }
+}
+
+static void fd_node_destroy(grpc_exec_ctx *exec_ctx, fd_node *fdn) {
+  gpr_log(GPR_DEBUG, "delete fd: %d", grpc_fd_wrapped_fd(fdn->grpc_fd));
+  GPR_ASSERT(!fdn->readable_registered);
+  GPR_ASSERT(!fdn->writable_registered);
+  gpr_mu_destroy(&fdn->mu);
+  grpc_pollset_set_del_fd(exec_ctx, fdn->ev_driver->pollset_set, fdn->grpc_fd);
+  grpc_fd_shutdown(exec_ctx, fdn->grpc_fd,
+                   GRPC_ERROR_CREATE_FROM_STATIC_STRING("fd node destroyed"));
+  grpc_fd_orphan(exec_ctx, fdn->grpc_fd, NULL, NULL, "c-ares query finished");
+  gpr_free(fdn);
+}
+
+grpc_error *grpc_ares_ev_driver_create(grpc_ares_ev_driver **ev_driver,
+                                       grpc_pollset_set *pollset_set) {
+  *ev_driver = gpr_malloc(sizeof(grpc_ares_ev_driver));
+  int status = ares_init(&(*ev_driver)->channel);
+  gpr_log(GPR_DEBUG, "grpc_ares_ev_driver_create");
+  if (status != ARES_SUCCESS) {
+    char *err_msg;
+    gpr_asprintf(&err_msg, "Failed to init ares channel. C-ares error: %s",
+                 ares_strerror(status));
+    grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(err_msg);
+    gpr_free(err_msg);
+    gpr_free(*ev_driver);
+    return err;
+  }
+  gpr_mu_init(&(*ev_driver)->mu);
+  gpr_ref_init(&(*ev_driver)->refs, 1);
+  (*ev_driver)->pollset_set = pollset_set;
+  (*ev_driver)->fds = NULL;
+  (*ev_driver)->working = false;
+  (*ev_driver)->shutting_down = false;
+  return GRPC_ERROR_NONE;
+}
+
+void grpc_ares_ev_driver_destroy(grpc_ares_ev_driver *ev_driver) {
+  // It's not safe to shut down remaining fds here directly, becauses
+  // ares_host_callback does not provide an exec_ctx. We mark the event driver
+  // as being shut down. If the event driver is working,
+  // grpc_ares_notify_on_event_locked will shut down the fds; if it's not
+  // working, there are no fds to shut down.
+  gpr_mu_lock(&ev_driver->mu);
+  ev_driver->shutting_down = true;
+  gpr_mu_unlock(&ev_driver->mu);
+  grpc_ares_ev_driver_unref(ev_driver);
+}
+
+// Search fd in the fd_node list head. This is an O(n) search, the max possible
+// value of n is ARES_GETSOCK_MAXNUM (16). n is typically 1 - 2 in our tests.
+static fd_node *pop_fd_node(fd_node **head, int fd) {
+  fd_node dummy_head;
+  dummy_head.next = *head;
+  fd_node *node = &dummy_head;
+  while (node->next != NULL) {
+    if (grpc_fd_wrapped_fd(node->next->grpc_fd) == fd) {
+      fd_node *ret = node->next;
+      node->next = node->next->next;
+      *head = dummy_head.next;
+      return ret;
+    }
+    node = node->next;
+  }
+  return NULL;
+}
+
+static void on_readable_cb(grpc_exec_ctx *exec_ctx, void *arg,
+                           grpc_error *error) {
+  fd_node *fdn = arg;
+  grpc_ares_ev_driver *ev_driver = fdn->ev_driver;
+  gpr_mu_lock(&fdn->mu);
+  fdn->readable_registered = false;
+  gpr_mu_unlock(&fdn->mu);
+
+  gpr_log(GPR_DEBUG, "readable on %d", grpc_fd_wrapped_fd(fdn->grpc_fd));
+  if (error == GRPC_ERROR_NONE) {
+    ares_process_fd(ev_driver->channel, grpc_fd_wrapped_fd(fdn->grpc_fd),
+                    ARES_SOCKET_BAD);
+  } else {
+    // If error is not GRPC_ERROR_NONE, it means the fd has been shutdown or
+    // timed out. The pending lookups made on this ev_driver will be cancelled
+    // by the following ares_cancel() and the on_done callbacks will be invoked
+    // with a status of ARES_ECANCELLED. The remaining file descriptors in this
+    // ev_driver will be cleaned up in the follwing
+    // grpc_ares_notify_on_event_locked().
+    ares_cancel(ev_driver->channel);
+  }
+  gpr_mu_lock(&ev_driver->mu);
+  grpc_ares_notify_on_event_locked(exec_ctx, ev_driver);
+  gpr_mu_unlock(&ev_driver->mu);
+  grpc_ares_ev_driver_unref(ev_driver);
+}
+
+static void on_writable_cb(grpc_exec_ctx *exec_ctx, void *arg,
+                           grpc_error *error) {
+  fd_node *fdn = arg;
+  grpc_ares_ev_driver *ev_driver = fdn->ev_driver;
+  gpr_mu_lock(&fdn->mu);
+  fdn->writable_registered = false;
+  gpr_mu_unlock(&fdn->mu);
+
+  gpr_log(GPR_DEBUG, "writable on %d", grpc_fd_wrapped_fd(fdn->grpc_fd));
+  if (error == GRPC_ERROR_NONE) {
+    ares_process_fd(ev_driver->channel, ARES_SOCKET_BAD,
+                    grpc_fd_wrapped_fd(fdn->grpc_fd));
+  } else {
+    // If error is not GRPC_ERROR_NONE, it means the fd has been shutdown or
+    // timed out. The pending lookups made on this ev_driver will be cancelled
+    // by the following ares_cancel() and the on_done callbacks will be invoked
+    // with a status of ARES_ECANCELLED. The remaining file descriptors in this
+    // ev_driver will be cleaned up in the follwing
+    // grpc_ares_notify_on_event_locked().
+    ares_cancel(ev_driver->channel);
+  }
+  gpr_mu_lock(&ev_driver->mu);
+  grpc_ares_notify_on_event_locked(exec_ctx, ev_driver);
+  gpr_mu_unlock(&ev_driver->mu);
+  grpc_ares_ev_driver_unref(ev_driver);
+}
+
+ares_channel *grpc_ares_ev_driver_get_channel(grpc_ares_ev_driver *ev_driver) {
+  return &ev_driver->channel;
+}
+
+// Get the file descriptors used by the ev_driver's ares channel, register
+// driver_closure with these filedescriptors.
+static void grpc_ares_notify_on_event_locked(grpc_exec_ctx *exec_ctx,
+                                             grpc_ares_ev_driver *ev_driver) {
+  fd_node *new_list = NULL;
+  if (!ev_driver->shutting_down) {
+    ares_socket_t socks[ARES_GETSOCK_MAXNUM];
+    int socks_bitmask =
+        ares_getsock(ev_driver->channel, socks, ARES_GETSOCK_MAXNUM);
+    for (size_t i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
+      if (ARES_GETSOCK_READABLE(socks_bitmask, i) ||
+          ARES_GETSOCK_WRITABLE(socks_bitmask, i)) {
+        fd_node *fdn = pop_fd_node(&ev_driver->fds, socks[i]);
+        // Create a new fd_node if sock[i] is not in the fd_node list.
+        if (fdn == NULL) {
+          char *fd_name;
+          gpr_asprintf(&fd_name, "ares_ev_driver-%" PRIuPTR, i);
+          fdn = gpr_malloc(sizeof(fd_node));
+          gpr_log(GPR_DEBUG, "new fd: %d", socks[i]);
+          fdn->grpc_fd = grpc_fd_create(socks[i], fd_name);
+          fdn->ev_driver = ev_driver;
+          fdn->readable_registered = false;
+          fdn->writable_registered = false;
+          gpr_mu_init(&fdn->mu);
+          grpc_closure_init(&fdn->read_closure, on_readable_cb, fdn,
+                            grpc_schedule_on_exec_ctx);
+          grpc_closure_init(&fdn->write_closure, on_writable_cb, fdn,
+                            grpc_schedule_on_exec_ctx);
+          grpc_pollset_set_add_fd(exec_ctx, ev_driver->pollset_set,
+                                  fdn->grpc_fd);
+          gpr_free(fd_name);
+        }
+        fdn->next = new_list;
+        new_list = fdn;
+        gpr_mu_lock(&fdn->mu);
+        // Register read_closure if the socket is readable and read_closure has
+        // not been registered with this socket.
+        if (ARES_GETSOCK_READABLE(socks_bitmask, i) &&
+            !fdn->readable_registered) {
+          grpc_ares_ev_driver_ref(ev_driver);
+          gpr_log(GPR_DEBUG, "notify read on: %d",
+                  grpc_fd_wrapped_fd(fdn->grpc_fd));
+          grpc_fd_notify_on_read(exec_ctx, fdn->grpc_fd, &fdn->read_closure);
+          fdn->readable_registered = true;
+        }
+        // Register write_closure if the socket is writable and write_closure
+        // has not been registered with this socket.
+        if (ARES_GETSOCK_WRITABLE(socks_bitmask, i) &&
+            !fdn->writable_registered) {
+          gpr_log(GPR_DEBUG, "notify write on: %d",
+                  grpc_fd_wrapped_fd(fdn->grpc_fd));
+          grpc_ares_ev_driver_ref(ev_driver);
+          grpc_fd_notify_on_write(exec_ctx, fdn->grpc_fd, &fdn->write_closure);
+          fdn->writable_registered = true;
+        }
+        gpr_mu_unlock(&fdn->mu);
+      }
+    }
+  }
+  // Any remaining fds in ev_driver->fds were not returned by ares_getsock() and
+  // are therefore no longer in use, so they can be shut down and removed from
+  // the list.
+  while (ev_driver->fds != NULL) {
+    fd_node *cur = ev_driver->fds;
+    ev_driver->fds = ev_driver->fds->next;
+    fd_node_destroy(exec_ctx, cur);
+  }
+  ev_driver->fds = new_list;
+  // If the ev driver has no working fd, all the tasks are done.
+  if (new_list == NULL) {
+    ev_driver->working = false;
+    gpr_log(GPR_DEBUG, "ev driver stop working");
+  }
+}
+
+void grpc_ares_ev_driver_start(grpc_exec_ctx *exec_ctx,
+                               grpc_ares_ev_driver *ev_driver) {
+  gpr_mu_lock(&ev_driver->mu);
+  if (!ev_driver->working) {
+    ev_driver->working = true;
+    grpc_ares_notify_on_event_locked(exec_ctx, ev_driver);
+  }
+  gpr_mu_unlock(&ev_driver->mu);
+}
+
+#endif /* GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET) */
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
new file mode 100644
index 0000000000000000000000000000000000000000..09c46a66e0b0fd981ab206f855bf1275f6d122a3
--- /dev/null
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
@@ -0,0 +1,289 @@
+/*
+ *
+ * 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 <grpc/support/port_platform.h>
+#if GRPC_ARES == 1 && !defined(GRPC_UV)
+
+#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
+#include "src/core/lib/iomgr/sockaddr.h"
+#include "src/core/lib/iomgr/socket_utils_posix.h"
+
+#include <string.h>
+#include <sys/types.h>
+
+#include <ares.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/time.h>
+#include <grpc/support/useful.h>
+#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
+#include "src/core/lib/iomgr/executor.h"
+#include "src/core/lib/iomgr/iomgr_internal.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
+#include "src/core/lib/support/string.h"
+
+static gpr_once g_basic_init = GPR_ONCE_INIT;
+static gpr_mu g_init_mu;
+
+typedef struct grpc_ares_request {
+  /** following members are set in grpc_resolve_address_ares_impl */
+  /** host to resolve, parsed from the name to resolve */
+  char *host;
+  /** port to fill in sockaddr_in, parsed from the name to resolve */
+  char *port;
+  /** default port to use */
+  char *default_port;
+  /** closure to call when the request completes */
+  grpc_closure *on_done;
+  /** the pointer to receive the resolved addresses */
+  grpc_resolved_addresses **addrs_out;
+  /** the evernt driver used by this request */
+  grpc_ares_ev_driver *ev_driver;
+  /** number of ongoing queries */
+  gpr_refcount pending_queries;
+
+  /** mutex guarding the rest of the state */
+  gpr_mu mu;
+  /** is there at least one successful query, set in on_done_cb */
+  bool success;
+  /** the errors explaining the request failure, set in on_done_cb */
+  grpc_error *error;
+} grpc_ares_request;
+
+static void do_basic_init(void) { gpr_mu_init(&g_init_mu); }
+
+static uint16_t strhtons(const char *port) {
+  if (strcmp(port, "http") == 0) {
+    return htons(80);
+  } else if (strcmp(port, "https") == 0) {
+    return htons(443);
+  }
+  return htons((unsigned short)atoi(port));
+}
+
+static void grpc_ares_request_unref(grpc_exec_ctx *exec_ctx,
+                                    grpc_ares_request *r) {
+  /* If there are no pending queries, invoke on_done callback and destroy the
+     request */
+  if (gpr_unref(&r->pending_queries)) {
+    /* TODO(zyc): Sort results with RFC6724 before invoking on_done. */
+    if (exec_ctx == NULL) {
+      /* A new exec_ctx is created here, as the c-ares interface does not
+         provide one in ares_host_callback. It's safe to schedule on_done with
+         the newly created exec_ctx, since the caller has been warned not to
+         acquire locks in on_done. ares_dns_resolver is using combiner to
+         protect resources needed by on_done. */
+      grpc_exec_ctx new_exec_ctx = GRPC_EXEC_CTX_INIT;
+      grpc_closure_sched(&new_exec_ctx, r->on_done, r->error);
+      grpc_exec_ctx_finish(&new_exec_ctx);
+    } else {
+      grpc_closure_sched(exec_ctx, r->on_done, r->error);
+    }
+    gpr_mu_destroy(&r->mu);
+    grpc_ares_ev_driver_destroy(r->ev_driver);
+    gpr_free(r->host);
+    gpr_free(r->port);
+    gpr_free(r->default_port);
+    gpr_free(r);
+  }
+}
+
+static void on_done_cb(void *arg, int status, int timeouts,
+                       struct hostent *hostent) {
+  grpc_ares_request *r = (grpc_ares_request *)arg;
+  gpr_mu_lock(&r->mu);
+  if (status == ARES_SUCCESS) {
+    GRPC_ERROR_UNREF(r->error);
+    r->error = GRPC_ERROR_NONE;
+    r->success = true;
+    grpc_resolved_addresses **addresses = r->addrs_out;
+    if (*addresses == NULL) {
+      *addresses = gpr_malloc(sizeof(grpc_resolved_addresses));
+      (*addresses)->naddrs = 0;
+      (*addresses)->addrs = NULL;
+    }
+    size_t prev_naddr = (*addresses)->naddrs;
+    size_t i;
+    for (i = 0; hostent->h_addr_list[i] != NULL; i++) {
+    }
+    (*addresses)->naddrs += i;
+    (*addresses)->addrs =
+        gpr_realloc((*addresses)->addrs,
+                    sizeof(grpc_resolved_address) * (*addresses)->naddrs);
+    for (i = prev_naddr; i < (*addresses)->naddrs; i++) {
+      memset(&(*addresses)->addrs[i], 0, sizeof(grpc_resolved_address));
+      if (hostent->h_addrtype == AF_INET6) {
+        (*addresses)->addrs[i].len = sizeof(struct sockaddr_in6);
+        struct sockaddr_in6 *addr =
+            (struct sockaddr_in6 *)&(*addresses)->addrs[i].addr;
+        addr->sin6_family = (sa_family_t)hostent->h_addrtype;
+        addr->sin6_port = strhtons(r->port);
+
+        char output[INET6_ADDRSTRLEN];
+        memcpy(&addr->sin6_addr, hostent->h_addr_list[i - prev_naddr],
+               sizeof(struct in6_addr));
+        ares_inet_ntop(AF_INET6, &addr->sin6_addr, output, INET6_ADDRSTRLEN);
+        gpr_log(GPR_DEBUG,
+                "c-ares resolver gets a AF_INET6 result: \n"
+                "  addr: %s\n  port: %s\n  sin6_scope_id: %d\n",
+                output, r->port, addr->sin6_scope_id);
+      } else {
+        (*addresses)->addrs[i].len = sizeof(struct sockaddr_in);
+        struct sockaddr_in *addr =
+            (struct sockaddr_in *)&(*addresses)->addrs[i].addr;
+        memcpy(&addr->sin_addr, hostent->h_addr_list[i - prev_naddr],
+               sizeof(struct in_addr));
+        addr->sin_family = (sa_family_t)hostent->h_addrtype;
+        addr->sin_port = strhtons(r->port);
+
+        char output[INET_ADDRSTRLEN];
+        ares_inet_ntop(AF_INET, &addr->sin_addr, output, INET_ADDRSTRLEN);
+        gpr_log(GPR_DEBUG,
+                "c-ares resolver gets a AF_INET result: \n"
+                "  addr: %s\n  port: %s\n",
+                output, r->port);
+      }
+    }
+  } else if (!r->success) {
+    char *error_msg;
+    gpr_asprintf(&error_msg, "C-ares status is not ARES_SUCCESS: %s",
+                 ares_strerror(status));
+    grpc_error *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
+    gpr_free(error_msg);
+    if (r->error == GRPC_ERROR_NONE) {
+      r->error = error;
+    } else {
+      r->error = grpc_error_add_child(error, r->error);
+    }
+  }
+  gpr_mu_unlock(&r->mu);
+  grpc_ares_request_unref(NULL, r);
+}
+
+void grpc_resolve_address_ares_impl(grpc_exec_ctx *exec_ctx, const char *name,
+                                    const char *default_port,
+                                    grpc_pollset_set *interested_parties,
+                                    grpc_closure *on_done,
+                                    grpc_resolved_addresses **addrs) {
+  /* TODO(zyc): Enable tracing after #9603 is checked in */
+  /* if (grpc_dns_trace) {
+      gpr_log(GPR_DEBUG, "resolve_address (blocking): name=%s, default_port=%s",
+              name, default_port);
+     } */
+
+  /* parse name, splitting it into host and port parts */
+  char *host;
+  char *port;
+  gpr_split_host_port(name, &host, &port);
+  if (host == NULL) {
+    grpc_error *err = grpc_error_set_str(
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("unparseable host:port"),
+        GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
+    grpc_closure_sched(exec_ctx, on_done, err);
+    goto error_cleanup;
+  } else if (port == NULL) {
+    if (default_port == NULL) {
+      grpc_error *err = grpc_error_set_str(
+          GRPC_ERROR_CREATE_FROM_STATIC_STRING("no port in name"),
+          GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
+      grpc_closure_sched(exec_ctx, on_done, err);
+      goto error_cleanup;
+    }
+    port = gpr_strdup(default_port);
+  }
+
+  grpc_ares_ev_driver *ev_driver;
+  grpc_error *err = grpc_ares_ev_driver_create(&ev_driver, interested_parties);
+  if (err != GRPC_ERROR_NONE) {
+    GRPC_LOG_IF_ERROR("grpc_ares_ev_driver_create() failed", err);
+    goto error_cleanup;
+  }
+
+  grpc_ares_request *r = gpr_malloc(sizeof(grpc_ares_request));
+  gpr_mu_init(&r->mu);
+  r->ev_driver = ev_driver;
+  r->on_done = on_done;
+  r->addrs_out = addrs;
+  r->default_port = gpr_strdup(default_port);
+  r->port = port;
+  r->host = host;
+  r->success = false;
+  r->error = GRPC_ERROR_NONE;
+  ares_channel *channel = grpc_ares_ev_driver_get_channel(r->ev_driver);
+  gpr_ref_init(&r->pending_queries, 2);
+  if (grpc_ipv6_loopback_available()) {
+    gpr_ref(&r->pending_queries);
+    ares_gethostbyname(*channel, r->host, AF_INET6, on_done_cb, r);
+  }
+  ares_gethostbyname(*channel, r->host, AF_INET, on_done_cb, r);
+  /* TODO(zyc): Handle CNAME records here. */
+  grpc_ares_ev_driver_start(exec_ctx, r->ev_driver);
+  grpc_ares_request_unref(exec_ctx, r);
+  return;
+
+error_cleanup:
+  gpr_free(host);
+  gpr_free(port);
+}
+
+void (*grpc_resolve_address_ares)(
+    grpc_exec_ctx *exec_ctx, const char *name, const char *default_port,
+    grpc_pollset_set *interested_parties, grpc_closure *on_done,
+    grpc_resolved_addresses **addrs) = grpc_resolve_address_ares_impl;
+
+grpc_error *grpc_ares_init(void) {
+  gpr_once_init(&g_basic_init, do_basic_init);
+  gpr_mu_lock(&g_init_mu);
+  int status = ares_library_init(ARES_LIB_INIT_ALL);
+  gpr_mu_unlock(&g_init_mu);
+
+  if (status != ARES_SUCCESS) {
+    char *error_msg;
+    gpr_asprintf(&error_msg, "ares_library_init failed: %s",
+                 ares_strerror(status));
+    grpc_error *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
+    gpr_free(error_msg);
+    return error;
+  }
+  return GRPC_ERROR_NONE;
+}
+
+void grpc_ares_cleanup(void) {
+  gpr_mu_lock(&g_init_mu);
+  ares_library_cleanup();
+  gpr_mu_unlock(&g_init_mu);
+}
+
+#endif /* GRPC_ARES == 1 && !defined(GRPC_UV) */
diff --git a/src/node/ext/completion_queue_async_worker.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
similarity index 50%
rename from src/node/ext/completion_queue_async_worker.h
rename to src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
index 6e541167658aefd4c88c92394c0bafe83a2dfb14..3dd40ea2687b7fec3a45d68f21a61206111aea96 100644
--- a/src/node/ext/completion_queue_async_worker.h
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
@@ -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,56 +31,34 @@
  *
  */
 
-#ifndef NET_GRPC_NODE_COMPLETION_QUEUE_ASYNC_WORKER_H_
-#define NET_GRPC_NODE_COMPLETION_QUEUE_ASYNC_WORKER_H_
-#include <nan.h>
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H
 
-#include "grpc/grpc.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/iomgr/iomgr.h"
+#include "src/core/lib/iomgr/polling_entity.h"
+#include "src/core/lib/iomgr/resolve_address.h"
 
-namespace grpc {
-namespace node {
+/* Asynchronously resolve addr. Use \a default_port if a port isn't designated
+   in addr, otherwise use the port in addr. grpc_ares_init() must be called at
+   least once before this function. \a on_done may be called directly in this
+   function without being scheduled with \a exec_ctx, it must not try to acquire
+   locks that are being held by the caller. */
+extern void (*grpc_resolve_address_ares)(grpc_exec_ctx *exec_ctx,
+                                         const char *addr,
+                                         const char *default_port,
+                                         grpc_pollset_set *interested_parties,
+                                         grpc_closure *on_done,
+                                         grpc_resolved_addresses **addresses);
 
-/* A worker that asynchronously calls completion_queue_next, and queues onto the
-   node event loop a call to the function stored in the event's tag. */
-class CompletionQueueAsyncWorker : public Nan::AsyncWorker {
- public:
-  CompletionQueueAsyncWorker();
+/* Initialize gRPC ares wrapper. Must be called at least once before
+   grpc_resolve_address_ares(). */
+grpc_error *grpc_ares_init(void);
 
-  ~CompletionQueueAsyncWorker();
-  /* Calls completion_queue_next with the provided deadline, and stores the
-     event if there was one or sets an error message if there was not */
-  void Execute();
+/* Uninitialized gRPC ares wrapper. If there was more than one previous call to
+   grpc_ares_init(), this function uninitializes the gRPC ares wrapper only if
+   it has been called the same number of times as grpc_ares_init(). */
+void grpc_ares_cleanup(void);
 
-  /* Returns the completion queue attached to this class */
-  static grpc_completion_queue *GetQueue();
-
-  /* Convenience function to create a worker with the given arguments and queue
-     it to run asynchronously */
-  static void Next();
-
-  /* Initialize the CompletionQueueAsyncWorker class */
-  static void Init(v8::Local<v8::Object> exports);
-
- protected:
-  /* Called when Execute has succeeded (completed without setting an error
-     message). Calls the saved callback with the event that came from
-     completion_queue_next */
-  void HandleOKCallback();
-
-  void HandleErrorCallback();
-
- private:
-  grpc_event result;
-
-  static grpc_completion_queue *queue;
-
-  // Number of grpc_completion_queue_next calls in the thread pool
-  static int current_threads;
-  // Number of grpc_completion_queue_next calls waiting to enter the thread pool
-  static int waiting_next_calls;
-};
-
-}  // namespace node
-}  // namespace grpc
-
-#endif  // NET_GRPC_NODE_COMPLETION_QUEUE_ASYNC_WORKER_H_
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H \
+          */
diff --git a/src/core/ext/resolver/dns/native/README.md b/src/core/ext/filters/client_channel/resolver/dns/native/README.md
similarity index 100%
rename from src/core/ext/resolver/dns/native/README.md
rename to src/core/ext/filters/client_channel/resolver/dns/native/README.md
diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c
similarity index 92%
rename from src/core/ext/resolver/dns/native/dns_resolver.c
rename to src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c
index d227c19c43c0a3da02ac5442ac0130ae2df704f7..ebe6a0721525aef674788d517ff902b628d7df20 100644
--- a/src/core/ext/resolver/dns/native/dns_resolver.c
+++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c
@@ -37,13 +37,14 @@
 #include <grpc/support/host_port.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/ext/client_channel/lb_policy_registry.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/combiner.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/support/backoff.h"
+#include "src/core/lib/support/env.h"
 #include "src/core/lib/support/string.h"
 
 #define GRPC_DNS_MIN_CONNECT_TIMEOUT_SECONDS 1
@@ -113,8 +114,9 @@ static void dns_shutdown_locked(grpc_exec_ctx *exec_ctx,
   }
   if (r->next_completion != NULL) {
     *r->target_result = NULL;
-    grpc_closure_sched(exec_ctx, r->next_completion,
-                       GRPC_ERROR_CREATE("Resolver Shutdown"));
+    grpc_closure_sched(
+        exec_ctx, r->next_completion,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resolver Shutdown"));
     r->next_completion = NULL;
   }
 }
@@ -303,7 +305,21 @@ static grpc_resolver_factory *dns_resolver_factory_create() {
 }
 
 void grpc_resolver_dns_native_init(void) {
-  grpc_register_resolver_type(dns_resolver_factory_create());
+  char *resolver = gpr_getenv("GRPC_DNS_RESOLVER");
+  if (resolver != NULL && gpr_stricmp(resolver, "native") == 0) {
+    gpr_log(GPR_DEBUG, "Using native dns resolver");
+    grpc_register_resolver_type(dns_resolver_factory_create());
+  } else {
+    grpc_resolver_factory *existing_factory =
+        grpc_resolver_factory_lookup("dns");
+    if (existing_factory == NULL) {
+      gpr_log(GPR_DEBUG, "Using native dns resolver");
+      grpc_register_resolver_type(dns_resolver_factory_create());
+    } else {
+      grpc_resolver_factory_unref(existing_factory);
+    }
+  }
+  gpr_free(resolver);
 }
 
 void grpc_resolver_dns_native_shutdown(void) {}
diff --git a/src/core/ext/resolver/sockaddr/README.md b/src/core/ext/filters/client_channel/resolver/sockaddr/README.md
similarity index 100%
rename from src/core/ext/resolver/sockaddr/README.md
rename to src/core/ext/filters/client_channel/resolver/sockaddr/README.md
diff --git a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c
similarity index 95%
rename from src/core/ext/resolver/sockaddr/sockaddr_resolver.c
rename to src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c
index da5923d26f5d584dc40d0ce0a828c45c7f499ede..4d7d878c2371f531b121e647b886a60cad5bedb6 100644
--- a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
+++ b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c
@@ -41,9 +41,9 @@
 #include <grpc/support/port_platform.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/ext/client_channel/lb_policy_factory.h"
-#include "src/core/ext/client_channel/parse_address.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/ext/filters/client_channel/parse_address.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/combiner.h"
 #include "src/core/lib/iomgr/resolve_address.h"
@@ -157,8 +157,8 @@ static void do_nothing(void *ignored) {}
 
 static grpc_resolver *sockaddr_create(grpc_exec_ctx *exec_ctx,
                                       grpc_resolver_args *args,
-                                      int parse(grpc_uri *uri,
-                                                grpc_resolved_address *dst)) {
+                                      bool parse(const grpc_uri *uri,
+                                                 grpc_resolved_address *dst)) {
   if (0 != strcmp(args->uri->authority, "")) {
     gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme",
             args->uri->scheme);
@@ -209,7 +209,7 @@ static void sockaddr_factory_unref(grpc_resolver_factory *factory) {}
   static grpc_resolver *name##_factory_create_resolver(                     \
       grpc_exec_ctx *exec_ctx, grpc_resolver_factory *factory,              \
       grpc_resolver_args *args) {                                           \
-    return sockaddr_create(exec_ctx, args, parse_##name);                   \
+    return sockaddr_create(exec_ctx, args, grpc_parse_##name);              \
   }                                                                         \
   static const grpc_resolver_factory_vtable name##_factory_vtable = {       \
       sockaddr_factory_ref, sockaddr_factory_unref,                         \
diff --git a/src/core/ext/client_channel/resolver_factory.c b/src/core/ext/filters/client_channel/resolver_factory.c
similarity index 97%
rename from src/core/ext/client_channel/resolver_factory.c
rename to src/core/ext/filters/client_channel/resolver_factory.c
index 00bbb92dd06adb8da427c9af3f1490dd1310ebbb..07f9e4cf0334c945f432660ded19b9a539a27d31 100644
--- a/src/core/ext/client_channel/resolver_factory.c
+++ b/src/core/ext/filters/client_channel/resolver_factory.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/ext/client_channel/resolver_factory.h"
+#include "src/core/ext/filters/client_channel/resolver_factory.h"
 
 void grpc_resolver_factory_ref(grpc_resolver_factory* factory) {
   factory->vtable->ref(factory);
diff --git a/src/core/ext/client_channel/resolver_factory.h b/src/core/ext/filters/client_channel/resolver_factory.h
similarity index 89%
rename from src/core/ext/client_channel/resolver_factory.h
rename to src/core/ext/filters/client_channel/resolver_factory.h
index e3cd99ec5a4b997307009e2cb3662812568946f5..f2fcfc06fefd0ac278ecf1bf5b5e48a5d383a239 100644
--- a/src/core/ext/client_channel/resolver_factory.h
+++ b/src/core/ext/filters/client_channel/resolver_factory.h
@@ -31,12 +31,12 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_FACTORY_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_FACTORY_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_FACTORY_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_FACTORY_H
 
-#include "src/core/ext/client_channel/client_channel_factory.h"
-#include "src/core/ext/client_channel/resolver.h"
-#include "src/core/ext/client_channel/uri_parser.h"
+#include "src/core/ext/filters/client_channel/client_channel_factory.h"
+#include "src/core/ext/filters/client_channel/resolver.h"
+#include "src/core/ext/filters/client_channel/uri_parser.h"
 #include "src/core/lib/iomgr/pollset_set.h"
 
 typedef struct grpc_resolver_factory grpc_resolver_factory;
@@ -82,4 +82,4 @@ grpc_resolver *grpc_resolver_factory_create_resolver(
 char *grpc_resolver_factory_get_default_authority(
     grpc_resolver_factory *factory, grpc_uri *uri);
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_FACTORY_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_FACTORY_H */
diff --git a/src/core/ext/client_channel/resolver_registry.c b/src/core/ext/filters/client_channel/resolver_registry.c
similarity index 87%
rename from src/core/ext/client_channel/resolver_registry.c
rename to src/core/ext/filters/client_channel/resolver_registry.c
index f8e8bc9c393569a51f8b45c993a7345e4fb5cb29..fa997bd68f1a941197bbe54c13b3703fac9379b5 100644
--- a/src/core/ext/client_channel/resolver_registry.c
+++ b/src/core/ext/filters/client_channel/resolver_registry.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
 
 #include <string.h>
 
@@ -93,7 +93,6 @@ static grpc_resolver_factory *lookup_factory(const char *name) {
       return g_all_of_the_resolvers[i];
     }
   }
-
   return NULL;
 }
 
@@ -108,22 +107,23 @@ static grpc_resolver_factory *lookup_factory_by_uri(grpc_uri *uri) {
   return lookup_factory(uri->scheme);
 }
 
-static grpc_resolver_factory *resolve_factory(const char *target,
+static grpc_resolver_factory *resolve_factory(grpc_exec_ctx *exec_ctx,
+                                              const char *target,
                                               grpc_uri **uri,
                                               char **canonical_target) {
   grpc_resolver_factory *factory = NULL;
 
   GPR_ASSERT(uri != NULL);
-  *uri = grpc_uri_parse(target, 1);
+  *uri = grpc_uri_parse(exec_ctx, target, 1);
   factory = lookup_factory_by_uri(*uri);
   if (factory == NULL) {
     grpc_uri_destroy(*uri);
     gpr_asprintf(canonical_target, "%s%s", g_default_resolver_prefix, target);
-    *uri = grpc_uri_parse(*canonical_target, 1);
+    *uri = grpc_uri_parse(exec_ctx, *canonical_target, 1);
     factory = lookup_factory_by_uri(*uri);
     if (factory == NULL) {
-      grpc_uri_destroy(grpc_uri_parse(target, 0));
-      grpc_uri_destroy(grpc_uri_parse(*canonical_target, 0));
+      grpc_uri_destroy(grpc_uri_parse(exec_ctx, target, 0));
+      grpc_uri_destroy(grpc_uri_parse(exec_ctx, *canonical_target, 0));
       gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target,
               *canonical_target);
     }
@@ -138,7 +138,7 @@ grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target,
   grpc_uri *uri = NULL;
   char *canonical_target = NULL;
   grpc_resolver_factory *factory =
-      resolve_factory(target, &uri, &canonical_target);
+      resolve_factory(exec_ctx, target, &uri, &canonical_target);
   grpc_resolver *resolver;
   grpc_resolver_args resolver_args;
   memset(&resolver_args, 0, sizeof(resolver_args));
@@ -153,21 +153,22 @@ grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target,
   return resolver;
 }
 
-char *grpc_get_default_authority(const char *target) {
+char *grpc_get_default_authority(grpc_exec_ctx *exec_ctx, const char *target) {
   grpc_uri *uri = NULL;
   char *canonical_target = NULL;
   grpc_resolver_factory *factory =
-      resolve_factory(target, &uri, &canonical_target);
+      resolve_factory(exec_ctx, target, &uri, &canonical_target);
   char *authority = grpc_resolver_factory_get_default_authority(factory, uri);
   grpc_uri_destroy(uri);
   gpr_free(canonical_target);
   return authority;
 }
 
-char *grpc_resolver_factory_add_default_prefix_if_needed(const char *target) {
+char *grpc_resolver_factory_add_default_prefix_if_needed(
+    grpc_exec_ctx *exec_ctx, const char *target) {
   grpc_uri *uri = NULL;
   char *canonical_target = NULL;
-  resolve_factory(target, &uri, &canonical_target);
+  resolve_factory(exec_ctx, target, &uri, &canonical_target);
   grpc_uri_destroy(uri);
   return canonical_target == NULL ? gpr_strdup(target) : canonical_target;
 }
diff --git a/src/core/ext/client_channel/resolver_registry.h b/src/core/ext/filters/client_channel/resolver_registry.h
similarity index 88%
rename from src/core/ext/client_channel/resolver_registry.h
rename to src/core/ext/filters/client_channel/resolver_registry.h
index e2c189cf0cd57617a33264740558f90833948959..f2e9f9249ca758872eb00bec7cfc303a3575e11d 100644
--- a/src/core/ext/client_channel/resolver_registry.h
+++ b/src/core/ext/filters/client_channel/resolver_registry.h
@@ -31,10 +31,10 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_REGISTRY_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_REGISTRY_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_REGISTRY_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_REGISTRY_H
 
-#include "src/core/ext/client_channel/resolver_factory.h"
+#include "src/core/ext/filters/client_channel/resolver_factory.h"
 #include "src/core/lib/iomgr/pollset_set.h"
 
 void grpc_resolver_registry_init();
@@ -74,10 +74,11 @@ grpc_resolver_factory *grpc_resolver_factory_lookup(const char *name);
 
 /** Given a target, return a (freshly allocated with gpr_malloc) string
     representing the default authority to pass from a client. */
-char *grpc_get_default_authority(const char *target);
+char *grpc_get_default_authority(grpc_exec_ctx *exec_ctx, const char *target);
 
 /** Returns a newly allocated string containing \a target, adding the
     default prefix if needed. */
-char *grpc_resolver_factory_add_default_prefix_if_needed(const char *target);
+char *grpc_resolver_factory_add_default_prefix_if_needed(
+    grpc_exec_ctx *exec_ctx, const char *target);
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_REGISTRY_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_REGISTRY_H */
diff --git a/src/core/ext/filters/client_channel/retry_throttle.c b/src/core/ext/filters/client_channel/retry_throttle.c
new file mode 100644
index 0000000000000000000000000000000000000000..dd78a178443c5c8ef0ea700859a3d8a209a4a0af
--- /dev/null
+++ b/src/core/ext/filters/client_channel/retry_throttle.c
@@ -0,0 +1,210 @@
+/*
+ *
+ * Copyright 2017, 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/ext/filters/client_channel/retry_throttle.h"
+
+#include <limits.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/atm.h>
+#include <grpc/support/avl.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/sync.h>
+
+//
+// server_retry_throttle_data
+//
+
+struct grpc_server_retry_throttle_data {
+  gpr_refcount refs;
+  int max_milli_tokens;
+  int milli_token_ratio;
+  gpr_atm milli_tokens;
+  // A pointer to the replacement for this grpc_server_retry_throttle_data
+  // entry.  If non-NULL, then this entry is stale and must not be used.
+  // We hold a reference to the replacement.
+  gpr_atm replacement;
+};
+
+static void get_replacement_throttle_data_if_needed(
+    grpc_server_retry_throttle_data** throttle_data) {
+  while (true) {
+    grpc_server_retry_throttle_data* new_throttle_data =
+        (grpc_server_retry_throttle_data*)gpr_atm_acq_load(
+            &(*throttle_data)->replacement);
+    if (new_throttle_data == NULL) return;
+    *throttle_data = new_throttle_data;
+  }
+}
+
+bool grpc_server_retry_throttle_data_record_failure(
+    grpc_server_retry_throttle_data* throttle_data) {
+  // First, check if we are stale and need to be replaced.
+  get_replacement_throttle_data_if_needed(&throttle_data);
+  // We decrement milli_tokens by 1000 (1 token) for each failure.
+  const int new_value = (int)gpr_atm_no_barrier_clamped_add(
+      &throttle_data->milli_tokens, (gpr_atm)-1000, (gpr_atm)0,
+      (gpr_atm)throttle_data->max_milli_tokens);
+  // Retries are allowed as long as the new value is above the threshold
+  // (max_milli_tokens / 2).
+  return new_value > throttle_data->max_milli_tokens / 2;
+}
+
+void grpc_server_retry_throttle_data_record_success(
+    grpc_server_retry_throttle_data* throttle_data) {
+  // First, check if we are stale and need to be replaced.
+  get_replacement_throttle_data_if_needed(&throttle_data);
+  // We increment milli_tokens by milli_token_ratio for each success.
+  gpr_atm_no_barrier_clamped_add(
+      &throttle_data->milli_tokens, (gpr_atm)throttle_data->milli_token_ratio,
+      (gpr_atm)0, (gpr_atm)throttle_data->max_milli_tokens);
+}
+
+grpc_server_retry_throttle_data* grpc_server_retry_throttle_data_ref(
+    grpc_server_retry_throttle_data* throttle_data) {
+  gpr_ref(&throttle_data->refs);
+  return throttle_data;
+}
+
+void grpc_server_retry_throttle_data_unref(
+    grpc_server_retry_throttle_data* throttle_data) {
+  if (gpr_unref(&throttle_data->refs)) {
+    grpc_server_retry_throttle_data* replacement =
+        (grpc_server_retry_throttle_data*)gpr_atm_acq_load(
+            &throttle_data->replacement);
+    if (replacement != NULL) {
+      grpc_server_retry_throttle_data_unref(replacement);
+    }
+    gpr_free(throttle_data);
+  }
+}
+
+static grpc_server_retry_throttle_data* grpc_server_retry_throttle_data_create(
+    int max_milli_tokens, int milli_token_ratio,
+    grpc_server_retry_throttle_data* old_throttle_data) {
+  grpc_server_retry_throttle_data* throttle_data =
+      gpr_malloc(sizeof(*throttle_data));
+  memset(throttle_data, 0, sizeof(*throttle_data));
+  gpr_ref_init(&throttle_data->refs, 1);
+  throttle_data->max_milli_tokens = max_milli_tokens;
+  throttle_data->milli_token_ratio = milli_token_ratio;
+  int initial_milli_tokens = max_milli_tokens;
+  // If there was a pre-existing entry for this server name, initialize
+  // the token count by scaling proportionately to the old data.  This
+  // ensures that if we're already throttling retries on the old scale,
+  // we will start out doing the same thing on the new one.
+  if (old_throttle_data != NULL) {
+    double token_fraction =
+        (int)gpr_atm_acq_load(&old_throttle_data->milli_tokens) /
+        (double)old_throttle_data->max_milli_tokens;
+    initial_milli_tokens = (int)(token_fraction * max_milli_tokens);
+  }
+  gpr_atm_rel_store(&throttle_data->milli_tokens,
+                    (gpr_atm)initial_milli_tokens);
+  // If there was a pre-existing entry, mark it as stale and give it a
+  // pointer to the new entry, which is its replacement.
+  if (old_throttle_data != NULL) {
+    grpc_server_retry_throttle_data_ref(throttle_data);
+    gpr_atm_rel_store(&old_throttle_data->replacement, (gpr_atm)throttle_data);
+  }
+  return throttle_data;
+}
+
+//
+// avl vtable for string -> server_retry_throttle_data map
+//
+
+static void* copy_server_name(void* key) { return gpr_strdup(key); }
+
+static long compare_server_name(void* key1, void* key2) {
+  return strcmp(key1, key2);
+}
+
+static void destroy_server_retry_throttle_data(void* value) {
+  grpc_server_retry_throttle_data* throttle_data = value;
+  grpc_server_retry_throttle_data_unref(throttle_data);
+}
+
+static void* copy_server_retry_throttle_data(void* value) {
+  grpc_server_retry_throttle_data* throttle_data = value;
+  return grpc_server_retry_throttle_data_ref(throttle_data);
+}
+
+static const gpr_avl_vtable avl_vtable = {
+    gpr_free /* destroy_key */, copy_server_name, compare_server_name,
+    destroy_server_retry_throttle_data, copy_server_retry_throttle_data};
+
+//
+// server_retry_throttle_map
+//
+
+static gpr_mu g_mu;
+static gpr_avl g_avl;
+
+void grpc_retry_throttle_map_init() {
+  gpr_mu_init(&g_mu);
+  g_avl = gpr_avl_create(&avl_vtable);
+}
+
+void grpc_retry_throttle_map_shutdown() {
+  gpr_mu_destroy(&g_mu);
+  gpr_avl_unref(g_avl);
+}
+
+grpc_server_retry_throttle_data* grpc_retry_throttle_map_get_data_for_server(
+    const char* server_name, int max_milli_tokens, int milli_token_ratio) {
+  gpr_mu_lock(&g_mu);
+  grpc_server_retry_throttle_data* throttle_data =
+      gpr_avl_get(g_avl, (char*)server_name);
+  if (throttle_data == NULL) {
+    // Entry not found.  Create a new one.
+    throttle_data = grpc_server_retry_throttle_data_create(
+        max_milli_tokens, milli_token_ratio, NULL);
+    g_avl = gpr_avl_add(g_avl, (char*)server_name, throttle_data);
+  } else {
+    if (throttle_data->max_milli_tokens != max_milli_tokens ||
+        throttle_data->milli_token_ratio != milli_token_ratio) {
+      // Entry found but with old parameters.  Create a new one based on
+      // the original one.
+      throttle_data = grpc_server_retry_throttle_data_create(
+          max_milli_tokens, milli_token_ratio, throttle_data);
+      g_avl = gpr_avl_add(g_avl, (char*)server_name, throttle_data);
+    } else {
+      // Entry found.  Increase refcount.
+      grpc_server_retry_throttle_data_ref(throttle_data);
+    }
+  }
+  gpr_mu_unlock(&g_mu);
+  return throttle_data;
+}
diff --git a/src/core/ext/filters/client_channel/retry_throttle.h b/src/core/ext/filters/client_channel/retry_throttle.h
new file mode 100644
index 0000000000000000000000000000000000000000..640865cf90f6ee2212fd1220b37ad22138cb79dc
--- /dev/null
+++ b/src/core/ext/filters/client_channel/retry_throttle.h
@@ -0,0 +1,65 @@
+/*
+ *
+ * Copyright 2017, 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_CORE_EXT_FILTERS_CLIENT_CHANNEL_RETRY_THROTTLE_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RETRY_THROTTLE_H
+
+#include <stdbool.h>
+
+/// Tracks retry throttling data for an individual server name.
+typedef struct grpc_server_retry_throttle_data grpc_server_retry_throttle_data;
+
+/// Records a failure.  Returns true if it's okay to send a retry.
+bool grpc_server_retry_throttle_data_record_failure(
+    grpc_server_retry_throttle_data* throttle_data);
+/// Records a success.
+void grpc_server_retry_throttle_data_record_success(
+    grpc_server_retry_throttle_data* throttle_data);
+
+grpc_server_retry_throttle_data* grpc_server_retry_throttle_data_ref(
+    grpc_server_retry_throttle_data* throttle_data);
+void grpc_server_retry_throttle_data_unref(
+    grpc_server_retry_throttle_data* throttle_data);
+
+/// Initializes global map of failure data for each server name.
+void grpc_retry_throttle_map_init();
+/// Shuts down global map of failure data for each server name.
+void grpc_retry_throttle_map_shutdown();
+
+/// Returns a reference to the failure data for \a server_name, creating
+/// a new entry if needed.
+/// Caller must eventually unref via \a grpc_server_retry_throttle_data_unref().
+grpc_server_retry_throttle_data* grpc_retry_throttle_map_get_data_for_server(
+    const char* server_name, int max_milli_tokens, int milli_token_ratio);
+
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RETRY_THROTTLE_H */
diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/filters/client_channel/subchannel.c
similarity index 87%
rename from src/core/ext/client_channel/subchannel.c
rename to src/core/ext/filters/client_channel/subchannel.c
index cb2d2c821dea9679a9397eb03ab222f818aa8bda..1af3393a62cd230fc05d93ff91688c4d7cfde506 100644
--- a/src/core/ext/client_channel/subchannel.c
+++ b/src/core/ext/filters/client_channel/subchannel.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/ext/client_channel/subchannel.h"
+#include "src/core/ext/filters/client_channel/subchannel.h"
 
 #include <limits.h>
 #include <string.h>
@@ -40,12 +40,11 @@
 #include <grpc/support/avl.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/client_channel/initial_connect_string.h"
-#include "src/core/ext/client_channel/parse_address.h"
-#include "src/core/ext/client_channel/proxy_mapper_registry.h"
-#include "src/core/ext/client_channel/subchannel_index.h"
-#include "src/core/ext/client_channel/uri_parser.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/parse_address.h"
+#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
+#include "src/core/ext/filters/client_channel/subchannel_index.h"
+#include "src/core/ext/filters/client_channel/uri_parser.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/connected_channel.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -60,9 +59,9 @@
 #define INTERNAL_REF_BITS 16
 #define STRONG_REF_MASK (~(gpr_atm)((1 << INTERNAL_REF_BITS) - 1))
 
-#define GRPC_SUBCHANNEL_MIN_CONNECT_TIMEOUT_SECONDS 20
 #define GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS 1
 #define GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER 1.6
+#define GRPC_SUBCHANNEL_RECONNECT_MIN_BACKOFF_SECONDS 20
 #define GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS 120
 #define GRPC_SUBCHANNEL_RECONNECT_JITTER 0.2
 
@@ -103,9 +102,6 @@ struct grpc_subchannel {
 
   grpc_subchannel_key *key;
 
-  /** initial string to send to peer */
-  grpc_slice initial_connect_string;
-
   /** set during connection */
   grpc_connect_out_args connecting_result;
 
@@ -148,6 +144,7 @@ struct grpc_subchannel {
 
 struct grpc_subchannel_call {
   grpc_connected_subchannel *connection;
+  grpc_closure *schedule_closure_after_destroy;
 };
 
 #define SUBCHANNEL_CALL_TO_CALL_STACK(call) ((grpc_call_stack *)((call) + 1))
@@ -214,7 +211,6 @@ static void subchannel_destroy(grpc_exec_ctx *exec_ctx, void *arg,
   grpc_subchannel *c = arg;
   gpr_free((void *)c->filters);
   grpc_channel_args_destroy(exec_ctx, c->args);
-  grpc_slice_unref_internal(exec_ctx, c->initial_connect_string);
   grpc_connectivity_state_destroy(exec_ctx, &c->state_tracker);
   grpc_connector_unref(exec_ctx, c->connector);
   grpc_pollset_set_destroy(exec_ctx, c->pollset_set);
@@ -273,8 +269,9 @@ static void disconnect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
   gpr_mu_lock(&c->mu);
   GPR_ASSERT(!c->disconnected);
   c->disconnected = true;
-  grpc_connector_shutdown(exec_ctx, c->connector,
-                          GRPC_ERROR_CREATE("Subchannel disconnected"));
+  grpc_connector_shutdown(
+      exec_ctx, c->connector,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Subchannel disconnected"));
   con = GET_CONNECTED_SUBCHANNEL(c, no_barrier);
   if (con != NULL) {
     GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, con, "connection");
@@ -331,8 +328,7 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
   }
   c->pollset_set = grpc_pollset_set_create();
   grpc_resolved_address *addr = gpr_malloc(sizeof(*addr));
-  grpc_get_subchannel_address_arg(args->args, addr);
-  grpc_set_initial_connect_string(&addr, &c->initial_connect_string);
+  grpc_get_subchannel_address_arg(exec_ctx, args->args, addr);
   grpc_resolved_address *new_address = NULL;
   grpc_channel_args *new_args = NULL;
   if (grpc_proxy_mappers_map_address(exec_ctx, addr, args->args, &new_address,
@@ -340,17 +336,15 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
     GPR_ASSERT(new_address != NULL);
     gpr_free(addr);
     addr = new_address;
-    if (new_args != NULL) c->args = new_args;
-  }
-  if (c->args == NULL) {
-    static const char *keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS};
-    grpc_arg new_arg = grpc_create_subchannel_address_arg(addr);
-    c->args = grpc_channel_args_copy_and_add_and_remove(
-        args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &new_arg,
-        1);
-    gpr_free(new_arg.value.string);
   }
+  static const char *keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS};
+  grpc_arg new_arg = grpc_create_subchannel_address_arg(addr);
   gpr_free(addr);
+  c->args = grpc_channel_args_copy_and_add_and_remove(
+      new_args != NULL ? new_args : args->args, keys_to_remove,
+      GPR_ARRAY_SIZE(keys_to_remove), &new_arg, 1);
+  gpr_free(new_arg.value.string);
+  if (new_args != NULL) grpc_channel_args_destroy(exec_ctx, new_args);
   c->root_external_state_watcher.next = c->root_external_state_watcher.prev =
       &c->root_external_state_watcher;
   grpc_closure_init(&c->connected, subchannel_connected, c,
@@ -359,19 +353,24 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
                                "subchannel");
   int initial_backoff_ms =
       GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS * 1000;
+  int min_backoff_ms = GRPC_SUBCHANNEL_RECONNECT_MIN_BACKOFF_SECONDS * 1000;
   int max_backoff_ms = GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS * 1000;
-  int min_backoff_ms = GRPC_SUBCHANNEL_MIN_CONNECT_TIMEOUT_SECONDS * 1000;
   bool fixed_reconnect_backoff = false;
   if (c->args) {
     for (size_t i = 0; i < c->args->num_args; i++) {
       if (0 == strcmp(c->args->args[i].key,
                       "grpc.testing.fixed_reconnect_backoff_ms")) {
-        GPR_ASSERT(c->args->args[i].type == GRPC_ARG_INTEGER);
         fixed_reconnect_backoff = true;
         initial_backoff_ms = min_backoff_ms = max_backoff_ms =
             grpc_channel_arg_get_integer(
                 &c->args->args[i],
                 (grpc_integer_options){initial_backoff_ms, 100, INT_MAX});
+      } else if (0 == strcmp(c->args->args[i].key,
+                             GRPC_ARG_MIN_RECONNECT_BACKOFF_MS)) {
+        fixed_reconnect_backoff = false;
+        min_backoff_ms = grpc_channel_arg_get_integer(
+            &c->args->args[i],
+            (grpc_integer_options){min_backoff_ms, 100, INT_MAX});
       } else if (0 == strcmp(c->args->args[i].key,
                              GRPC_ARG_MAX_RECONNECT_BACKOFF_MS)) {
         fixed_reconnect_backoff = false;
@@ -405,7 +404,6 @@ static void continue_connect_locked(grpc_exec_ctx *exec_ctx,
   args.interested_parties = c->pollset_set;
   args.deadline = c->next_attempt;
   args.channel_args = c->args;
-  args.initial_connect_string = c->initial_connect_string;
 
   grpc_connectivity_state_set(exec_ctx, &c->state_tracker,
                               GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
@@ -445,7 +443,8 @@ static void on_alarm(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
   gpr_mu_lock(&c->mu);
   c->have_alarm = false;
   if (c->disconnected) {
-    error = GRPC_ERROR_CREATE_REFERENCING("Disconnected", &error, 1);
+    error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Disconnected",
+                                                             &error, 1);
   } else {
     GRPC_ERROR_REF(error);
   }
@@ -616,7 +615,7 @@ void grpc_connected_subchannel_ping(grpc_exec_ctx *exec_ctx,
   elem->filter->start_transport_op(exec_ctx, elem, op);
 }
 
-static void publish_transport_locked(grpc_exec_ctx *exec_ctx,
+static bool publish_transport_locked(grpc_exec_ctx *exec_ctx,
                                      grpc_subchannel *c) {
   grpc_connected_subchannel *con;
   grpc_channel_stack *stk;
@@ -632,15 +631,16 @@ static void publish_transport_locked(grpc_exec_ctx *exec_ctx,
   if (!grpc_channel_init_create_stack(exec_ctx, builder,
                                       GRPC_CLIENT_SUBCHANNEL)) {
     grpc_channel_stack_builder_destroy(exec_ctx, builder);
-    abort(); /* TODO(ctiller): what to do here (previously we just crashed) */
+    return false;
   }
   grpc_error *error = grpc_channel_stack_builder_finish(
       exec_ctx, builder, 0, 1, connection_destroy, NULL, (void **)&con);
   if (error != GRPC_ERROR_NONE) {
+    grpc_transport_destroy(exec_ctx, c->connecting_result.transport);
     gpr_log(GPR_ERROR, "error initializing subchannel stack: %s",
             grpc_error_string(error));
     GRPC_ERROR_UNREF(error);
-    abort(); /* TODO(ctiller): what to do here? */
+    return false;
   }
   stk = CHANNEL_STACK_FROM_CONNECTION(con);
   memset(&c->connecting_result, 0, sizeof(c->connecting_result));
@@ -657,7 +657,7 @@ static void publish_transport_locked(grpc_exec_ctx *exec_ctx,
     grpc_channel_stack_destroy(exec_ctx, stk);
     gpr_free(con);
     GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
-    return;
+    return false;
   }
 
   /* publish */
@@ -679,6 +679,7 @@ static void publish_transport_locked(grpc_exec_ctx *exec_ctx,
   /* signal completion */
   grpc_connectivity_state_set(exec_ctx, &c->state_tracker, GRPC_CHANNEL_READY,
                               GRPC_ERROR_NONE, "connected");
+  return true;
 }
 
 static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *arg,
@@ -689,16 +690,17 @@ static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *arg,
   GRPC_SUBCHANNEL_WEAK_REF(c, "connected");
   gpr_mu_lock(&c->mu);
   c->connecting = false;
-  if (c->connecting_result.transport != NULL) {
-    publish_transport_locked(exec_ctx, c);
+  if (c->connecting_result.transport != NULL &&
+      publish_transport_locked(exec_ctx, c)) {
+    /* do nothing, transport was published */
   } else if (c->disconnected) {
     GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
   } else {
     grpc_connectivity_state_set(
         exec_ctx, &c->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
-        grpc_error_set_int(
-            GRPC_ERROR_CREATE_REFERENCING("Connect Failed", &error, 1),
-            GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE),
+        grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                               "Connect Failed", &error, 1),
+                           GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE),
         "connect_failed");
 
     const char *errmsg = grpc_error_string(error);
@@ -719,13 +721,22 @@ static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *arg,
 static void subchannel_call_destroy(grpc_exec_ctx *exec_ctx, void *call,
                                     grpc_error *error) {
   grpc_subchannel_call *c = call;
+  GPR_ASSERT(c->schedule_closure_after_destroy != NULL);
   GPR_TIMER_BEGIN("grpc_subchannel_call_unref.destroy", 0);
   grpc_connected_subchannel *connection = c->connection;
-  grpc_call_stack_destroy(exec_ctx, SUBCHANNEL_CALL_TO_CALL_STACK(c), NULL, c);
+  grpc_call_stack_destroy(exec_ctx, SUBCHANNEL_CALL_TO_CALL_STACK(c), NULL,
+                          c->schedule_closure_after_destroy);
   GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, connection, "subchannel_call");
   GPR_TIMER_END("grpc_subchannel_call_unref.destroy", 0);
 }
 
+void grpc_subchannel_call_set_cleanup_closure(grpc_subchannel_call *call,
+                                              grpc_closure *closure) {
+  GPR_ASSERT(call->schedule_closure_after_destroy == NULL);
+  GPR_ASSERT(closure != NULL);
+  call->schedule_closure_after_destroy = closure;
+}
+
 void grpc_subchannel_call_ref(
     grpc_subchannel_call *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
   GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON);
@@ -746,11 +757,11 @@ char *grpc_subchannel_call_get_peer(grpc_exec_ctx *exec_ctx,
 
 void grpc_subchannel_call_process_op(grpc_exec_ctx *exec_ctx,
                                      grpc_subchannel_call *call,
-                                     grpc_transport_stream_op *op) {
+                                     grpc_transport_stream_op_batch *op) {
   GPR_TIMER_BEGIN("grpc_subchannel_call_process_op", 0);
   grpc_call_stack *call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(call);
   grpc_call_element *top_elem = grpc_call_stack_element(call_stack, 0);
-  top_elem->filter->start_transport_stream_op(exec_ctx, top_elem, op);
+  top_elem->filter->start_transport_stream_op_batch(exec_ctx, top_elem, op);
   GPR_TIMER_END("grpc_subchannel_call_process_op", 0);
 }
 
@@ -761,24 +772,28 @@ grpc_connected_subchannel *grpc_subchannel_get_connected_subchannel(
 
 grpc_error *grpc_connected_subchannel_create_call(
     grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con,
-    grpc_polling_entity *pollent, grpc_slice path, gpr_timespec start_time,
-    gpr_timespec deadline, grpc_subchannel_call **call) {
+    const grpc_connected_subchannel_call_args *args,
+    grpc_subchannel_call **call) {
   grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con);
-  *call = gpr_zalloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size);
+  *call = gpr_arena_alloc(
+      args->arena, sizeof(grpc_subchannel_call) + chanstk->call_stack_size);
   grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call);
-  (*call)->connection = con;  // Ref is added below.
-  grpc_error *error =
-      grpc_call_stack_init(exec_ctx, chanstk, 1, subchannel_call_destroy, *call,
-                           NULL, NULL, path, start_time, deadline, callstk);
+  (*call)->connection = GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call");
+  const grpc_call_element_args call_args = {.call_stack = callstk,
+                                            .server_transport_data = NULL,
+                                            .context = args->context,
+                                            .path = args->path,
+                                            .start_time = args->start_time,
+                                            .deadline = args->deadline,
+                                            .arena = args->arena};
+  grpc_error *error = grpc_call_stack_init(
+      exec_ctx, chanstk, 1, subchannel_call_destroy, *call, &call_args);
   if (error != GRPC_ERROR_NONE) {
     const char *error_string = grpc_error_string(error);
     gpr_log(GPR_ERROR, "error: %s", error_string);
-
-    gpr_free(*call);
     return error;
   }
-  GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call");
-  grpc_call_stack_set_pollset_or_pollset_set(exec_ctx, callstk, pollent);
+  grpc_call_stack_set_pollset_or_pollset_set(exec_ctx, callstk, args->pollent);
   return GRPC_ERROR_NONE;
 }
 
@@ -787,26 +802,21 @@ grpc_call_stack *grpc_subchannel_call_get_call_stack(
   return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call);
 }
 
-static void grpc_uri_to_sockaddr(const char *uri_str,
+static void grpc_uri_to_sockaddr(grpc_exec_ctx *exec_ctx, const char *uri_str,
                                  grpc_resolved_address *addr) {
-  grpc_uri *uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */);
+  grpc_uri *uri = grpc_uri_parse(exec_ctx, uri_str, 0 /* suppress_errors */);
   GPR_ASSERT(uri != NULL);
-  if (strcmp(uri->scheme, "ipv4") == 0) {
-    GPR_ASSERT(parse_ipv4(uri, addr));
-  } else if (strcmp(uri->scheme, "ipv6") == 0) {
-    GPR_ASSERT(parse_ipv6(uri, addr));
-  } else {
-    GPR_ASSERT(parse_unix(uri, addr));
-  }
+  if (!grpc_parse_uri(uri, addr)) memset(addr, 0, sizeof(*addr));
   grpc_uri_destroy(uri);
 }
 
-void grpc_get_subchannel_address_arg(const grpc_channel_args *args,
+void grpc_get_subchannel_address_arg(grpc_exec_ctx *exec_ctx,
+                                     const grpc_channel_args *args,
                                      grpc_resolved_address *addr) {
   const char *addr_uri_str = grpc_get_subchannel_address_uri_arg(args);
   memset(addr, 0, sizeof(*addr));
   if (*addr_uri_str != '\0') {
-    grpc_uri_to_sockaddr(addr_uri_str, addr);
+    grpc_uri_to_sockaddr(exec_ctx, addr_uri_str, addr);
   }
 }
 
diff --git a/src/core/ext/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h
similarity index 89%
rename from src/core/ext/client_channel/subchannel.h
rename to src/core/ext/filters/client_channel/subchannel.h
index 26ce95448713273d40e8f7b9d2a53cf0a724a64c..e433c33e408f9da66c8ebae7cad402fd8d435d05 100644
--- a/src/core/ext/client_channel/subchannel.h
+++ b/src/core/ext/filters/client_channel/subchannel.h
@@ -31,12 +31,13 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_SUBCHANNEL_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_SUBCHANNEL_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_H
 
-#include "src/core/ext/client_channel/connector.h"
+#include "src/core/ext/filters/client_channel/connector.h"
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/iomgr/polling_entity.h"
+#include "src/core/lib/support/arena.h"
 #include "src/core/lib/transport/connectivity_state.h"
 #include "src/core/lib/transport/metadata.h"
 
@@ -112,10 +113,19 @@ void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx,
                                     GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
 
 /** construct a subchannel call */
+typedef struct {
+  grpc_polling_entity *pollent;
+  grpc_slice path;
+  gpr_timespec start_time;
+  gpr_timespec deadline;
+  gpr_arena *arena;
+  grpc_call_context_element *context;
+} grpc_connected_subchannel_call_args;
+
 grpc_error *grpc_connected_subchannel_create_call(
     grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *connected_subchannel,
-    grpc_polling_entity *pollent, grpc_slice path, gpr_timespec start_time,
-    gpr_timespec deadline, grpc_subchannel_call **subchannel_call);
+    const grpc_connected_subchannel_call_args *args,
+    grpc_subchannel_call **subchannel_call);
 
 /** process a transport level op */
 void grpc_connected_subchannel_process_transport_op(
@@ -148,12 +158,17 @@ grpc_connected_subchannel *grpc_subchannel_get_connected_subchannel(
 /** continue processing a transport op */
 void grpc_subchannel_call_process_op(grpc_exec_ctx *exec_ctx,
                                      grpc_subchannel_call *subchannel_call,
-                                     grpc_transport_stream_op *op);
+                                     grpc_transport_stream_op_batch *op);
 
 /** continue querying for peer */
 char *grpc_subchannel_call_get_peer(grpc_exec_ctx *exec_ctx,
                                     grpc_subchannel_call *subchannel_call);
 
+/** Must be called once per call. Sets the 'then_schedule_closure' argument for
+    call stack destruction. */
+void grpc_subchannel_call_set_cleanup_closure(
+    grpc_subchannel_call *subchannel_call, grpc_closure *closure);
+
 grpc_call_stack *grpc_subchannel_call_get_call_stack(
     grpc_subchannel_call *subchannel_call);
 
@@ -175,7 +190,8 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
                                         const grpc_subchannel_args *args);
 
 /// Sets \a addr from \a args.
-void grpc_get_subchannel_address_arg(const grpc_channel_args *args,
+void grpc_get_subchannel_address_arg(grpc_exec_ctx *exec_ctx,
+                                     const grpc_channel_args *args,
                                      grpc_resolved_address *addr);
 
 /// Returns the URI string for the address to connect to.
@@ -185,4 +201,4 @@ const char *grpc_get_subchannel_address_uri_arg(const grpc_channel_args *args);
 /// Caller is responsible for freeing the string.
 grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address *addr);
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_SUBCHANNEL_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_H */
diff --git a/src/core/ext/client_channel/subchannel_index.c b/src/core/ext/filters/client_channel/subchannel_index.c
similarity index 99%
rename from src/core/ext/client_channel/subchannel_index.c
rename to src/core/ext/filters/client_channel/subchannel_index.c
index 11889300a2caebf36e429ed498946c83fbddd3de..f6ef4a845e85e37e2246e35613ed5a27e0213459 100644
--- a/src/core/ext/client_channel/subchannel_index.c
+++ b/src/core/ext/filters/client_channel/subchannel_index.c
@@ -31,7 +31,7 @@
 //
 //
 
-#include "src/core/ext/client_channel/subchannel_index.h"
+#include "src/core/ext/filters/client_channel/subchannel_index.h"
 
 #include <stdbool.h>
 #include <string.h>
diff --git a/src/core/ext/client_channel/subchannel_index.h b/src/core/ext/filters/client_channel/subchannel_index.h
similarity index 91%
rename from src/core/ext/client_channel/subchannel_index.h
rename to src/core/ext/filters/client_channel/subchannel_index.h
index a67bd5e2195deaf7684c4997a58747259a05c824..f673ade378271167ab5b2fac18ba0fe487dc764e 100644
--- a/src/core/ext/client_channel/subchannel_index.h
+++ b/src/core/ext/filters/client_channel/subchannel_index.h
@@ -31,11 +31,11 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H
 
-#include "src/core/ext/client_channel/connector.h"
-#include "src/core/ext/client_channel/subchannel.h"
+#include "src/core/ext/filters/client_channel/connector.h"
+#include "src/core/ext/filters/client_channel/subchannel.h"
 
 /** \file Provides an index of active subchannels so that they can be
     shared amongst channels */
@@ -74,4 +74,4 @@ void grpc_subchannel_index_init(void);
 /** Shutdown the subchannel index (global) */
 void grpc_subchannel_index_shutdown(void);
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H */
diff --git a/src/core/ext/client_channel/uri_parser.c b/src/core/ext/filters/client_channel/uri_parser.c
similarity index 79%
rename from src/core/ext/client_channel/uri_parser.c
rename to src/core/ext/filters/client_channel/uri_parser.c
index 7dd7b753cc8cd55bb79468f64cb163b48aee16e7..b233d835cbc25814d905c5266d9cf92b73181d29 100644
--- a/src/core/ext/client_channel/uri_parser.c
+++ b/src/core/ext/filters/client_channel/uri_parser.c
@@ -31,24 +31,26 @@
  *
  */
 
-#include "src/core/ext/client_channel/uri_parser.h"
+#include "src/core/ext/filters/client_channel/uri_parser.h"
 
 #include <string.h>
 
-#include <grpc/slice.h>
 #include <grpc/slice_buffer.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/port_platform.h>
 #include <grpc/support/string_util.h>
 
+#include "src/core/lib/slice/percent_encoding.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 
 /** a size_t default value... maps to all 1's */
 #define NOT_SET (~(size_t)0)
 
 static grpc_uri *bad_uri(const char *uri_text, size_t pos, const char *section,
-                         int suppress_errors) {
+                         bool suppress_errors) {
   char *line_prefix;
   size_t pfx_len;
 
@@ -68,14 +70,24 @@ static grpc_uri *bad_uri(const char *uri_text, size_t pos, const char *section,
   return NULL;
 }
 
-/** Returns a copy of \a src[begin, end) */
-static char *copy_component(const char *src, size_t begin, size_t end) {
-  char *out = gpr_malloc(end - begin + 1);
-  memcpy(out, src + begin, end - begin);
-  out[end - begin] = 0;
+/** Returns a copy of percent decoded \a src[begin, end) */
+static char *decode_and_copy_component(grpc_exec_ctx *exec_ctx, const char *src,
+                                       size_t begin, size_t end) {
+  grpc_slice component =
+      grpc_slice_from_copied_buffer(src + begin, end - begin);
+  grpc_slice decoded_component =
+      grpc_permissive_percent_decode_slice(component);
+  char *out = grpc_dump_slice(decoded_component, GPR_DUMP_ASCII);
+  grpc_slice_unref_internal(exec_ctx, component);
+  grpc_slice_unref_internal(exec_ctx, decoded_component);
   return out;
 }
 
+static bool valid_hex(char c) {
+  return ((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F')) ||
+         ((c >= '0') && (c <= '9'));
+}
+
 /** Returns how many chars to advance if \a uri_text[i] begins a valid \a pchar
  * production. If \a uri_text[i] introduces an invalid \a pchar (such as percent
  * sign not followed by two hex digits), NOT_SET is returned. */
@@ -86,27 +98,36 @@ static size_t parse_pchar(const char *uri_text, size_t i) {
    * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
    / "*" / "+" / "," / ";" / "=" */
   char c = uri_text[i];
-  if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) ||
-      ((c >= '0') && (c <= '9')) ||
-      (c == '-' || c == '.' || c == '_' || c == '~') || /* unreserved */
-      (c == '!' || c == '$' || c == '&' || c == '\'' || c == '$' || c == '&' ||
-       c == '(' || c == ')' || c == '*' || c == '+' || c == ',' || c == ';' ||
-       c == '=') /* sub-delims */) {
-    return 1;
-  }
-  if (c == '%') { /* pct-encoded */
-    size_t j;
-    if (uri_text[i + 1] == 0 || uri_text[i + 2] == 0) {
-      return NOT_SET;
-    }
-    for (j = i + 1; j < 2; j++) {
-      c = uri_text[j];
-      if (!(((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f')) ||
-            ((c >= 'A') && (c <= 'F')))) {
-        return NOT_SET;
+  switch (c) {
+    default:
+      if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) ||
+          ((c >= '0') && (c <= '9'))) {
+        return 1;
       }
-    }
-    return 2;
+      break;
+    case ':':
+    case '@':
+    case '-':
+    case '.':
+    case '_':
+    case '~':
+    case '!':
+    case '$':
+    case '&':
+    case '\'':
+    case '(':
+    case ')':
+    case '*':
+    case '+':
+    case ',':
+    case ';':
+    case '=':
+      return 1;
+    case '%': /* pct-encoded */
+      if (valid_hex(uri_text[i + 1]) && valid_hex(uri_text[i + 2])) {
+        return 2;
+      }
+      return NOT_SET;
   }
   return 0;
 }
@@ -175,7 +196,8 @@ static void parse_query_parts(grpc_uri *uri) {
   }
 }
 
-grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) {
+grpc_uri *grpc_uri_parse(grpc_exec_ctx *exec_ctx, const char *uri_text,
+                         bool suppress_errors) {
   grpc_uri *uri;
   size_t scheme_begin = 0;
   size_t scheme_end = NOT_SET;
@@ -263,11 +285,16 @@ grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) {
   }
 
   uri = gpr_zalloc(sizeof(*uri));
-  uri->scheme = copy_component(uri_text, scheme_begin, scheme_end);
-  uri->authority = copy_component(uri_text, authority_begin, authority_end);
-  uri->path = copy_component(uri_text, path_begin, path_end);
-  uri->query = copy_component(uri_text, query_begin, query_end);
-  uri->fragment = copy_component(uri_text, fragment_begin, fragment_end);
+  uri->scheme =
+      decode_and_copy_component(exec_ctx, uri_text, scheme_begin, scheme_end);
+  uri->authority = decode_and_copy_component(exec_ctx, uri_text,
+                                             authority_begin, authority_end);
+  uri->path =
+      decode_and_copy_component(exec_ctx, uri_text, path_begin, path_end);
+  uri->query =
+      decode_and_copy_component(exec_ctx, uri_text, query_begin, query_end);
+  uri->fragment = decode_and_copy_component(exec_ctx, uri_text, fragment_begin,
+                                            fragment_end);
   parse_query_parts(uri);
 
   return uri;
diff --git a/src/core/ext/client_channel/uri_parser.h b/src/core/ext/filters/client_channel/uri_parser.h
similarity index 86%
rename from src/core/ext/client_channel/uri_parser.h
rename to src/core/ext/filters/client_channel/uri_parser.h
index 5fe0e8f35e3d4bbca84a4b93805e2d5384f12659..b889040b167f37ff2873cf5ad14678e953d3ad3e 100644
--- a/src/core/ext/client_channel/uri_parser.h
+++ b/src/core/ext/filters/client_channel/uri_parser.h
@@ -31,10 +31,11 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_URI_PARSER_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_URI_PARSER_H
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_URI_PARSER_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_URI_PARSER_H
 
 #include <stddef.h>
+#include "src/core/lib/iomgr/exec_ctx.h"
 
 typedef struct {
   char *scheme;
@@ -51,7 +52,8 @@ typedef struct {
 } grpc_uri;
 
 /** parse a uri, return NULL on failure */
-grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors);
+grpc_uri *grpc_uri_parse(grpc_exec_ctx *exec_ctx, const char *uri_text,
+                         bool suppress_errors);
 
 /** return the part of a query string after the '=' in "?key=xxx&...", or NULL
  * if key is not present */
@@ -60,4 +62,4 @@ const char *grpc_uri_get_query_arg(const grpc_uri *uri, const char *key);
 /** destroy a uri */
 void grpc_uri_destroy(grpc_uri *uri);
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_URI_PARSER_H */
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_URI_PARSER_H */
diff --git a/src/core/lib/channel/deadline_filter.c b/src/core/ext/filters/deadline/deadline_filter.c
similarity index 80%
rename from src/core/lib/channel/deadline_filter.c
rename to src/core/ext/filters/deadline/deadline_filter.c
index 5a12d62f1d1af7d0358cab4f0aba39d63c233f47..2e03d16bf6da8d895eead3fb60ca5a97b4391c3f 100644
--- a/src/core/lib/channel/deadline_filter.c
+++ b/src/core/ext/filters/deadline/deadline_filter.c
@@ -29,7 +29,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 
-#include "src/core/lib/channel/deadline_filter.h"
+#include "src/core/ext/filters/deadline/deadline_filter.h"
 
 #include <stdbool.h>
 #include <string.h>
@@ -39,9 +39,11 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
 
+#include "src/core/lib/channel/channel_stack_builder.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/surface/channel_init.h"
 
 //
 // grpc_deadline_state
@@ -55,9 +57,9 @@ static void timer_callback(grpc_exec_ctx* exec_ctx, void* arg,
   if (error != GRPC_ERROR_CANCELLED) {
     grpc_call_element_signal_error(
         exec_ctx, elem,
-        grpc_error_set_int(GRPC_ERROR_CREATE("Deadline Exceeded"),
-                           GRPC_ERROR_INT_GRPC_STATUS,
-                           GRPC_STATUS_DEADLINE_EXCEEDED));
+        grpc_error_set_int(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Deadline Exceeded"),
+            GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_DEADLINE_EXCEEDED));
   }
   GRPC_CALL_STACK_UNREF(exec_ctx, deadline_state->call_stack, "deadline_timer");
 }
@@ -134,25 +136,13 @@ static void on_complete(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
 
 // Inject our own on_complete callback into op.
 static void inject_on_complete_cb(grpc_deadline_state* deadline_state,
-                                  grpc_transport_stream_op* op) {
+                                  grpc_transport_stream_op_batch* op) {
   deadline_state->next_on_complete = op->on_complete;
   grpc_closure_init(&deadline_state->on_complete, on_complete, deadline_state,
                     grpc_schedule_on_exec_ctx);
   op->on_complete = &deadline_state->on_complete;
 }
 
-void grpc_deadline_state_init(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
-                              grpc_call_stack* call_stack) {
-  grpc_deadline_state* deadline_state = elem->call_data;
-  deadline_state->call_stack = call_stack;
-}
-
-void grpc_deadline_state_destroy(grpc_exec_ctx* exec_ctx,
-                                 grpc_call_element* elem) {
-  grpc_deadline_state* deadline_state = elem->call_data;
-  cancel_timer_if_needed(exec_ctx, deadline_state);
-}
-
 // Callback and associated state for starting the timer after call stack
 // initialization has been completed.
 struct start_timer_after_init_state {
@@ -167,8 +157,11 @@ static void start_timer_after_init(grpc_exec_ctx* exec_ctx, void* arg,
   gpr_free(state);
 }
 
-void grpc_deadline_state_start(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
-                               gpr_timespec deadline) {
+void grpc_deadline_state_init(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
+                              grpc_call_stack* call_stack,
+                              gpr_timespec deadline) {
+  grpc_deadline_state* deadline_state = elem->call_data;
+  deadline_state->call_stack = call_stack;
   // Deadline will always be infinite on servers, so the timer will only be
   // set on clients with a finite deadline.
   deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC);
@@ -189,6 +182,12 @@ void grpc_deadline_state_start(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
   }
 }
 
+void grpc_deadline_state_destroy(grpc_exec_ctx* exec_ctx,
+                                 grpc_call_element* elem) {
+  grpc_deadline_state* deadline_state = elem->call_data;
+  cancel_timer_if_needed(exec_ctx, deadline_state);
+}
+
 void grpc_deadline_state_reset(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
                                gpr_timespec new_deadline) {
   grpc_deadline_state* deadline_state = elem->call_data;
@@ -196,16 +195,16 @@ void grpc_deadline_state_reset(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
   start_timer_if_needed(exec_ctx, elem, new_deadline);
 }
 
-void grpc_deadline_state_client_start_transport_stream_op(
+void grpc_deadline_state_client_start_transport_stream_op_batch(
     grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
-    grpc_transport_stream_op* op) {
+    grpc_transport_stream_op_batch* op) {
   grpc_deadline_state* deadline_state = elem->call_data;
-  if (op->cancel_error != GRPC_ERROR_NONE) {
+  if (op->cancel_stream) {
     cancel_timer_if_needed(exec_ctx, deadline_state);
   } else {
     // Make sure we know when the call is complete, so that we can cancel
     // the timer.
-    if (op->recv_trailing_metadata != NULL) {
+    if (op->recv_trailing_metadata) {
       inject_on_complete_cb(deadline_state, op);
     }
   }
@@ -248,23 +247,23 @@ typedef struct server_call_data {
 static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
                                   grpc_call_element* elem,
                                   const grpc_call_element_args* args) {
-  grpc_deadline_state_init(exec_ctx, elem, args->call_stack);
-  grpc_deadline_state_start(exec_ctx, elem, args->deadline);
+  grpc_deadline_state_init(exec_ctx, elem, args->call_stack, args->deadline);
   return GRPC_ERROR_NONE;
 }
 
 // Destructor for call_data.  Used for both client and server filters.
 static void destroy_call_elem(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
                               const grpc_call_final_info* final_info,
-                              void* and_free_memory) {
+                              grpc_closure* ignored) {
   grpc_deadline_state_destroy(exec_ctx, elem);
 }
 
 // Method for starting a call op for client filter.
-static void client_start_transport_stream_op(grpc_exec_ctx* exec_ctx,
-                                             grpc_call_element* elem,
-                                             grpc_transport_stream_op* op) {
-  grpc_deadline_state_client_start_transport_stream_op(exec_ctx, elem, op);
+static void client_start_transport_stream_op_batch(
+    grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
+    grpc_transport_stream_op_batch* op) {
+  grpc_deadline_state_client_start_transport_stream_op_batch(exec_ctx, elem,
+                                                             op);
   // Chain to next filter.
   grpc_call_next_op(exec_ctx, elem, op);
 }
@@ -282,30 +281,33 @@ static void recv_initial_metadata_ready(grpc_exec_ctx* exec_ctx, void* arg,
 }
 
 // Method for starting a call op for server filter.
-static void server_start_transport_stream_op(grpc_exec_ctx* exec_ctx,
-                                             grpc_call_element* elem,
-                                             grpc_transport_stream_op* op) {
+static void server_start_transport_stream_op_batch(
+    grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
+    grpc_transport_stream_op_batch* op) {
   server_call_data* calld = elem->call_data;
-  if (op->cancel_error != GRPC_ERROR_NONE) {
+  if (op->cancel_stream) {
     cancel_timer_if_needed(exec_ctx, &calld->base.deadline_state);
   } else {
     // If we're receiving initial metadata, we need to get the deadline
     // from the recv_initial_metadata_ready callback.  So we inject our
     // own callback into that hook.
-    if (op->recv_initial_metadata_ready != NULL) {
-      calld->next_recv_initial_metadata_ready = op->recv_initial_metadata_ready;
-      calld->recv_initial_metadata = op->recv_initial_metadata;
+    if (op->recv_initial_metadata) {
+      calld->next_recv_initial_metadata_ready =
+          op->payload->recv_initial_metadata.recv_initial_metadata_ready;
+      calld->recv_initial_metadata =
+          op->payload->recv_initial_metadata.recv_initial_metadata;
       grpc_closure_init(&calld->recv_initial_metadata_ready,
                         recv_initial_metadata_ready, elem,
                         grpc_schedule_on_exec_ctx);
-      op->recv_initial_metadata_ready = &calld->recv_initial_metadata_ready;
+      op->payload->recv_initial_metadata.recv_initial_metadata_ready =
+          &calld->recv_initial_metadata_ready;
     }
     // Make sure we know when the call is complete, so that we can cancel
     // the timer.
     // Note that we trigger this on recv_trailing_metadata, even though
     // the client never sends trailing metadata, because this is the
     // hook that tells us when the call is complete on the server side.
-    if (op->recv_trailing_metadata != NULL) {
+    if (op->recv_trailing_metadata) {
       inject_on_complete_cb(&calld->base.deadline_state, op);
     }
   }
@@ -314,7 +316,7 @@ static void server_start_transport_stream_op(grpc_exec_ctx* exec_ctx,
 }
 
 const grpc_channel_filter grpc_client_deadline_filter = {
-    client_start_transport_stream_op,
+    client_start_transport_stream_op_batch,
     grpc_channel_next_op,
     sizeof(base_call_data),
     init_call_elem,
@@ -329,7 +331,7 @@ const grpc_channel_filter grpc_client_deadline_filter = {
 };
 
 const grpc_channel_filter grpc_server_deadline_filter = {
-    server_start_transport_stream_op,
+    server_start_transport_stream_op_batch,
     grpc_channel_next_op,
     sizeof(server_call_data),
     init_call_elem,
@@ -342,3 +344,30 @@ const grpc_channel_filter grpc_server_deadline_filter = {
     grpc_channel_next_get_info,
     "deadline",
 };
+
+bool grpc_deadline_checking_enabled(const grpc_channel_args* channel_args) {
+  return grpc_channel_arg_get_bool(
+      grpc_channel_args_find(channel_args, GRPC_ARG_ENABLE_DEADLINE_CHECKS),
+      !grpc_channel_args_want_minimal_stack(channel_args));
+}
+
+static bool maybe_add_deadline_filter(grpc_exec_ctx* exec_ctx,
+                                      grpc_channel_stack_builder* builder,
+                                      void* arg) {
+  return grpc_deadline_checking_enabled(
+             grpc_channel_stack_builder_get_channel_arguments(builder))
+             ? grpc_channel_stack_builder_prepend_filter(builder, arg, NULL,
+                                                         NULL)
+             : true;
+}
+
+void grpc_deadline_filter_init(void) {
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+      maybe_add_deadline_filter, (void*)&grpc_client_deadline_filter);
+  grpc_channel_init_register_stage(
+      GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+      maybe_add_deadline_filter, (void*)&grpc_server_deadline_filter);
+}
+
+void grpc_deadline_filter_shutdown(void) {}
diff --git a/src/core/lib/channel/deadline_filter.h b/src/core/ext/filters/deadline/deadline_filter.h
similarity index 87%
rename from src/core/lib/channel/deadline_filter.h
rename to src/core/ext/filters/deadline/deadline_filter.h
index 72cd5cb92963c7ed58e535a686940898dd07702d..5050453fa1a59e250e35628b8ccef3d7b04d2c60 100644
--- a/src/core/lib/channel/deadline_filter.h
+++ b/src/core/ext/filters/deadline/deadline_filter.h
@@ -29,8 +29,8 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 
-#ifndef GRPC_CORE_LIB_CHANNEL_DEADLINE_FILTER_H
-#define GRPC_CORE_LIB_CHANNEL_DEADLINE_FILTER_H
+#ifndef GRPC_CORE_EXT_FILTERS_DEADLINE_DEADLINE_FILTER_H
+#define GRPC_CORE_EXT_FILTERS_DEADLINE_DEADLINE_FILTER_H
 
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/iomgr/timer.h"
@@ -64,15 +64,11 @@ typedef struct grpc_deadline_state {
 
 // assumes elem->call_data is zero'd
 void grpc_deadline_state_init(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
-                              grpc_call_stack* call_stack);
+                              grpc_call_stack* call_stack,
+                              gpr_timespec deadline);
 void grpc_deadline_state_destroy(grpc_exec_ctx* exec_ctx,
                                  grpc_call_element* elem);
 
-// Starts the timer with the specified deadline.
-// Should be called from the filter's init_call_elem() method.
-void grpc_deadline_state_start(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
-                               gpr_timespec deadline);
-
 // Cancels the existing timer and starts a new one with new_deadline.
 //
 // Note: It is generally safe to call this with an earlier deadline
@@ -83,15 +79,18 @@ void grpc_deadline_state_start(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
 void grpc_deadline_state_reset(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
                                gpr_timespec new_deadline);
 
-// To be called from the client-side filter's start_transport_stream_op()
+// To be called from the client-side filter's start_transport_stream_op_batch()
 // method.  Ensures that the deadline timer is cancelled when the call
 // is completed.
 //
 // Note: It is the caller's responsibility to chain to the next filter if
 // necessary after this function returns.
-void grpc_deadline_state_client_start_transport_stream_op(
+void grpc_deadline_state_client_start_transport_stream_op_batch(
     grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
-    grpc_transport_stream_op* op);
+    grpc_transport_stream_op_batch* op);
+
+// Should deadline checking be performed (according to channel args)
+bool grpc_deadline_checking_enabled(const grpc_channel_args* args);
 
 // Deadline filters for direct client channels and server channels.
 // Note: Deadlines for non-direct client channels are handled by the
@@ -99,4 +98,4 @@ void grpc_deadline_state_client_start_transport_stream_op(
 extern const grpc_channel_filter grpc_client_deadline_filter;
 extern const grpc_channel_filter grpc_server_deadline_filter;
 
-#endif /* GRPC_CORE_LIB_CHANNEL_DEADLINE_FILTER_H */
+#endif /* GRPC_CORE_EXT_FILTERS_DEADLINE_DEADLINE_FILTER_H */
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/ext/filters/http/client/http_client_filter.c
similarity index 73%
rename from src/core/lib/channel/http_client_filter.c
rename to src/core/ext/filters/http/client/http_client_filter.c
index c031533dd867a65e4028dd63d8935ffc84c84fec..d8ae080eee7c8a04de1cd63a75d340cf2720a45a 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/ext/filters/http/client/http_client_filter.c
@@ -30,12 +30,13 @@
  *
  */
 
-#include "src/core/lib/channel/http_client_filter.h"
+#include "src/core/ext/filters/http/client/http_client_filter.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <string.h>
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/b64.h"
 #include "src/core/lib/slice/percent_encoding.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
@@ -56,14 +57,13 @@ typedef struct call_data {
   grpc_linked_mdelem te_trailers;
   grpc_linked_mdelem content_type;
   grpc_linked_mdelem user_agent;
-  grpc_linked_mdelem payload_bin;
 
   grpc_metadata_batch *recv_initial_metadata;
   grpc_metadata_batch *recv_trailing_metadata;
   uint8_t *payload_bytes;
 
   /* Vars to read data off of send_message */
-  grpc_transport_stream_op send_op;
+  grpc_transport_stream_op_batch *send_op;
   uint32_t send_length;
   uint32_t send_flags;
   grpc_slice incoming_slice;
@@ -108,11 +108,11 @@ static grpc_error *client_filter_incoming_metadata(grpc_exec_ctx *exec_ctx,
       grpc_error *e = grpc_error_set_str(
           grpc_error_set_int(
               grpc_error_set_str(
-                  GRPC_ERROR_CREATE(
+                  GRPC_ERROR_CREATE_FROM_STATIC_STRING(
                       "Received http2 :status header with non-200 OK status"),
-                  GRPC_ERROR_STR_VALUE, val),
+                  GRPC_ERROR_STR_VALUE, grpc_slice_from_copied_string(val)),
               GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_CANCELLED),
-          GRPC_ERROR_STR_GRPC_MESSAGE, msg);
+          GRPC_ERROR_STR_GRPC_MESSAGE, grpc_slice_from_copied_string(msg));
       gpr_free(val);
       gpr_free(msg);
       return e;
@@ -219,11 +219,16 @@ static void continue_send_message(grpc_exec_ctx *exec_ctx,
                                   grpc_call_element *elem) {
   call_data *calld = elem->call_data;
   uint8_t *wrptr = calld->payload_bytes;
-  while (grpc_byte_stream_next(exec_ctx, calld->send_op.send_message,
-                               &calld->incoming_slice, ~(size_t)0,
-                               &calld->got_slice)) {
-    memcpy(wrptr, GRPC_SLICE_START_PTR(calld->incoming_slice),
-           GRPC_SLICE_LENGTH(calld->incoming_slice));
+  while (grpc_byte_stream_next(
+      exec_ctx, calld->send_op->payload->send_message.send_message, ~(size_t)0,
+      &calld->got_slice)) {
+    grpc_byte_stream_pull(exec_ctx,
+                          calld->send_op->payload->send_message.send_message,
+                          &calld->incoming_slice);
+    if (GRPC_SLICE_LENGTH(calld->incoming_slice) > 0) {
+      memcpy(wrptr, GRPC_SLICE_START_PTR(calld->incoming_slice),
+             GRPC_SLICE_LENGTH(calld->incoming_slice));
+    }
     wrptr += GRPC_SLICE_LENGTH(calld->incoming_slice);
     grpc_slice_buffer_add(&calld->slices, calld->incoming_slice);
     if (calld->send_length == calld->slices.length) {
@@ -237,15 +242,23 @@ static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
   grpc_call_element *elem = elemp;
   call_data *calld = elem->call_data;
   calld->send_message_blocked = false;
+  if (GRPC_ERROR_NONE !=
+      grpc_byte_stream_pull(exec_ctx,
+                            calld->send_op->payload->send_message.send_message,
+                            &calld->incoming_slice)) {
+    /* Should never reach here */
+    abort();
+  }
   grpc_slice_buffer_add(&calld->slices, calld->incoming_slice);
   if (calld->send_length == calld->slices.length) {
     /* Pass down the original send_message op that was blocked.*/
     grpc_slice_buffer_stream_init(&calld->replacement_stream, &calld->slices,
                                   calld->send_flags);
-    calld->send_op.send_message = &calld->replacement_stream.base;
-    calld->post_send = calld->send_op.on_complete;
-    calld->send_op.on_complete = &calld->send_done;
-    grpc_call_next_op(exec_ctx, elem, &calld->send_op);
+    calld->send_op->payload->send_message.send_message =
+        &calld->replacement_stream.base;
+    calld->post_send = calld->send_op->on_complete;
+    calld->send_op->on_complete = &calld->send_done;
+    grpc_call_next_op(exec_ctx, elem, calld->send_op);
   } else {
     continue_send_message(exec_ctx, elem);
   }
@@ -253,29 +266,30 @@ static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
 
 static grpc_error *hc_mutate_op(grpc_exec_ctx *exec_ctx,
                                 grpc_call_element *elem,
-                                grpc_transport_stream_op *op) {
+                                grpc_transport_stream_op_batch *op) {
   /* grab pointers to our data from the call element */
   call_data *calld = elem->call_data;
   channel_data *channeld = elem->channel_data;
   grpc_error *error;
 
-  if (op->send_initial_metadata != NULL) {
+  if (op->send_initial_metadata) {
     /* Decide which HTTP VERB to use. We use GET if the request is marked
     cacheable, and the operation contains both initial metadata and send
     message, and the payload is below the size threshold, and all the data
     for this request is immediately available. */
     grpc_mdelem method = GRPC_MDELEM_METHOD_POST;
-    if ((op->send_initial_metadata_flags &
+    if (op->send_message &&
+        (op->payload->send_initial_metadata.send_initial_metadata_flags &
          GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) &&
-        op->send_message != NULL &&
-        op->send_message->length < channeld->max_payload_size_for_get) {
+        op->payload->send_message.send_message->length <
+            channeld->max_payload_size_for_get) {
       method = GRPC_MDELEM_METHOD_GET;
       /* The following write to calld->send_message_blocked isn't racy with
       reads in hc_start_transport_op (which deals with SEND_MESSAGE ops) because
       being here means ops->send_message is not NULL, which is primarily
       guarding the read there. */
       calld->send_message_blocked = true;
-    } else if (op->send_initial_metadata_flags &
+    } else if (op->payload->send_initial_metadata.send_initial_metadata_flags &
                GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) {
       method = GRPC_MDELEM_METHOD_PUT;
     }
@@ -283,28 +297,67 @@ static grpc_error *hc_mutate_op(grpc_exec_ctx *exec_ctx,
     /* Attempt to read the data from send_message and create a header field. */
     if (grpc_mdelem_eq(method, GRPC_MDELEM_METHOD_GET)) {
       /* allocate memory to hold the entire payload */
-      calld->payload_bytes = gpr_malloc(op->send_message->length);
+      calld->payload_bytes =
+          gpr_malloc(op->payload->send_message.send_message->length);
 
       /* read slices of send_message and copy into payload_bytes */
-      calld->send_op = *op;
-      calld->send_length = op->send_message->length;
-      calld->send_flags = op->send_message->flags;
+      calld->send_op = op;
+      calld->send_length = op->payload->send_message.send_message->length;
+      calld->send_flags = op->payload->send_message.send_message->flags;
       continue_send_message(exec_ctx, elem);
 
       if (calld->send_message_blocked == false) {
-        /* when all the send_message data is available, then create a MDELEM and
-        append to headers */
-        grpc_mdelem payload_bin = grpc_mdelem_from_slices(
-            exec_ctx, GRPC_MDSTR_GRPC_PAYLOAD_BIN,
-            grpc_slice_from_copied_buffer((const char *)calld->payload_bytes,
-                                          op->send_message->length));
-        error =
-            grpc_metadata_batch_add_tail(exec_ctx, op->send_initial_metadata,
-                                         &calld->payload_bin, payload_bin);
+        /* when all the send_message data is available, then modify the path
+         * MDELEM by appending base64 encoded query to the path */
+        const int k_url_safe = 1;
+        const int k_multi_line = 0;
+        const unsigned char k_query_separator = '?';
+
+        grpc_slice path_slice =
+            GRPC_MDVALUE(op->payload->send_initial_metadata
+                             .send_initial_metadata->idx.named.path->md);
+        /* sum up individual component's lengths and allocate enough memory to
+         * hold combined path+query */
+        size_t estimated_len = GRPC_SLICE_LENGTH(path_slice);
+        estimated_len++; /* for the '?' */
+        estimated_len += grpc_base64_estimate_encoded_size(
+            op->payload->send_message.send_message->length, k_url_safe,
+            k_multi_line);
+        grpc_slice path_with_query_slice = GRPC_SLICE_MALLOC(estimated_len);
+
+        /* memcopy individual pieces into this slice */
+        uint8_t *write_ptr =
+            (uint8_t *)GRPC_SLICE_START_PTR(path_with_query_slice);
+        uint8_t *original_path = (uint8_t *)GRPC_SLICE_START_PTR(path_slice);
+        memcpy(write_ptr, original_path, GRPC_SLICE_LENGTH(path_slice));
+        write_ptr += GRPC_SLICE_LENGTH(path_slice);
+
+        *write_ptr = k_query_separator;
+        write_ptr++; /* for the '?' */
+
+        grpc_base64_encode_core((char *)write_ptr, calld->payload_bytes,
+                                op->payload->send_message.send_message->length,
+                                k_url_safe, k_multi_line);
+
+        /* remove trailing unused memory and add trailing 0 to terminate string
+         */
+        char *t = (char *)GRPC_SLICE_START_PTR(path_with_query_slice);
+        /* safe to use strlen since base64_encode will always add '\0' */
+        path_with_query_slice =
+            grpc_slice_sub_no_ref(path_with_query_slice, 0, strlen(t));
+
+        /* substitute previous path with the new path+query */
+        grpc_mdelem mdelem_path_and_query = grpc_mdelem_from_slices(
+            exec_ctx, GRPC_MDSTR_PATH, path_with_query_slice);
+        grpc_metadata_batch *b =
+            op->payload->send_initial_metadata.send_initial_metadata;
+        error = grpc_metadata_batch_substitute(exec_ctx, b, b->idx.named.path,
+                                               mdelem_path_and_query);
         if (error != GRPC_ERROR_NONE) return error;
+
         calld->on_complete = op->on_complete;
         op->on_complete = &calld->hc_on_complete;
-        op->send_message = NULL;
+        op->send_message = false;
       } else {
         /* Not all data is available. Fall back to POST. */
         gpr_log(GPR_DEBUG,
@@ -314,47 +367,60 @@ static grpc_error *hc_mutate_op(grpc_exec_ctx *exec_ctx,
       }
     }
 
-    remove_if_present(exec_ctx, op->send_initial_metadata, GRPC_BATCH_METHOD);
-    remove_if_present(exec_ctx, op->send_initial_metadata, GRPC_BATCH_SCHEME);
-    remove_if_present(exec_ctx, op->send_initial_metadata, GRPC_BATCH_TE);
-    remove_if_present(exec_ctx, op->send_initial_metadata,
+    remove_if_present(exec_ctx,
+                      op->payload->send_initial_metadata.send_initial_metadata,
+                      GRPC_BATCH_METHOD);
+    remove_if_present(exec_ctx,
+                      op->payload->send_initial_metadata.send_initial_metadata,
+                      GRPC_BATCH_SCHEME);
+    remove_if_present(exec_ctx,
+                      op->payload->send_initial_metadata.send_initial_metadata,
+                      GRPC_BATCH_TE);
+    remove_if_present(exec_ctx,
+                      op->payload->send_initial_metadata.send_initial_metadata,
                       GRPC_BATCH_CONTENT_TYPE);
-    remove_if_present(exec_ctx, op->send_initial_metadata,
+    remove_if_present(exec_ctx,
+                      op->payload->send_initial_metadata.send_initial_metadata,
                       GRPC_BATCH_USER_AGENT);
 
     /* Send : prefixed headers, which have to be before any application
        layer headers. */
-    error = grpc_metadata_batch_add_head(exec_ctx, op->send_initial_metadata,
-                                         &calld->method, method);
+    error = grpc_metadata_batch_add_head(
+        exec_ctx, op->payload->send_initial_metadata.send_initial_metadata,
+        &calld->method, method);
     if (error != GRPC_ERROR_NONE) return error;
-    error =
-        grpc_metadata_batch_add_head(exec_ctx, op->send_initial_metadata,
-                                     &calld->scheme, channeld->static_scheme);
+    error = grpc_metadata_batch_add_head(
+        exec_ctx, op->payload->send_initial_metadata.send_initial_metadata,
+        &calld->scheme, channeld->static_scheme);
     if (error != GRPC_ERROR_NONE) return error;
-    error = grpc_metadata_batch_add_tail(exec_ctx, op->send_initial_metadata,
-                                         &calld->te_trailers,
-                                         GRPC_MDELEM_TE_TRAILERS);
+    error = grpc_metadata_batch_add_tail(
+        exec_ctx, op->payload->send_initial_metadata.send_initial_metadata,
+        &calld->te_trailers, GRPC_MDELEM_TE_TRAILERS);
     if (error != GRPC_ERROR_NONE) return error;
     error = grpc_metadata_batch_add_tail(
-        exec_ctx, op->send_initial_metadata, &calld->content_type,
-        GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC);
+        exec_ctx, op->payload->send_initial_metadata.send_initial_metadata,
+        &calld->content_type, GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC);
     if (error != GRPC_ERROR_NONE) return error;
-    error = grpc_metadata_batch_add_tail(exec_ctx, op->send_initial_metadata,
-                                         &calld->user_agent,
-                                         GRPC_MDELEM_REF(channeld->user_agent));
+    error = grpc_metadata_batch_add_tail(
+        exec_ctx, op->payload->send_initial_metadata.send_initial_metadata,
+        &calld->user_agent, GRPC_MDELEM_REF(channeld->user_agent));
     if (error != GRPC_ERROR_NONE) return error;
   }
 
-  if (op->recv_initial_metadata != NULL) {
+  if (op->recv_initial_metadata) {
     /* substitute our callback for the higher callback */
-    calld->recv_initial_metadata = op->recv_initial_metadata;
-    calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready;
-    op->recv_initial_metadata_ready = &calld->hc_on_recv_initial_metadata;
+    calld->recv_initial_metadata =
+        op->payload->recv_initial_metadata.recv_initial_metadata;
+    calld->on_done_recv_initial_metadata =
+        op->payload->recv_initial_metadata.recv_initial_metadata_ready;
+    op->payload->recv_initial_metadata.recv_initial_metadata_ready =
+        &calld->hc_on_recv_initial_metadata;
   }
 
-  if (op->recv_trailing_metadata != NULL) {
+  if (op->recv_trailing_metadata) {
     /* substitute our callback for the higher callback */
-    calld->recv_trailing_metadata = op->recv_trailing_metadata;
+    calld->recv_trailing_metadata =
+        op->payload->recv_trailing_metadata.recv_trailing_metadata;
     calld->on_done_recv_trailing_metadata = op->on_complete;
     op->on_complete = &calld->hc_on_recv_trailing_metadata;
   }
@@ -364,17 +430,17 @@ static grpc_error *hc_mutate_op(grpc_exec_ctx *exec_ctx,
 
 static void hc_start_transport_op(grpc_exec_ctx *exec_ctx,
                                   grpc_call_element *elem,
-                                  grpc_transport_stream_op *op) {
+                                  grpc_transport_stream_op_batch *op) {
   GPR_TIMER_BEGIN("hc_start_transport_op", 0);
   GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
   grpc_error *error = hc_mutate_op(exec_ctx, elem, op);
   if (error != GRPC_ERROR_NONE) {
-    grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error);
+    grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, op, error);
   } else {
     call_data *calld = elem->call_data;
-    if (op->send_message != NULL && calld->send_message_blocked) {
+    if (op->send_message && calld->send_message_blocked) {
       /* Don't forward the op. send_message contains slices that aren't ready
-      yet. The call will be forwarded by the op_complete of slice read call.
+         yet. The call will be forwarded by the op_complete of slice read call.
       */
     } else {
       grpc_call_next_op(exec_ctx, elem, op);
@@ -412,7 +478,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
 /* Destructor for call_data */
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
-                              void *ignored) {
+                              grpc_closure *ignored) {
   call_data *calld = elem->call_data;
   grpc_slice_buffer_destroy_internal(exec_ctx, &calld->slices);
 }
diff --git a/src/core/lib/channel/http_client_filter.h b/src/core/ext/filters/http/client/http_client_filter.h
similarity index 87%
rename from src/core/lib/channel/http_client_filter.h
rename to src/core/ext/filters/http/client/http_client_filter.h
index 9e6e106e9cb0cc38a0eb0dcf096977696b9e392f..6e1eb3937bac6e202236b5ad23f2db6ea5f3cd1d 100644
--- a/src/core/lib/channel/http_client_filter.h
+++ b/src/core/ext/filters/http/client/http_client_filter.h
@@ -30,18 +30,15 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_CHANNEL_HTTP_CLIENT_FILTER_H
-#define GRPC_CORE_LIB_CHANNEL_HTTP_CLIENT_FILTER_H
+#ifndef GRPC_CORE_EXT_FILTERS_HTTP_CLIENT_HTTP_CLIENT_FILTER_H
+#define GRPC_CORE_EXT_FILTERS_HTTP_CLIENT_HTTP_CLIENT_FILTER_H
 
 #include "src/core/lib/channel/channel_stack.h"
 
 /* Processes metadata on the client side for HTTP2 transports */
 extern const grpc_channel_filter grpc_http_client_filter;
 
-/* Channel arg to override the http2 :scheme header */
-#define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme"
-
 /* Channel arg to determine maximum size of payload eligable for GET request */
 #define GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET "grpc.max_payload_size_for_get"
 
-#endif /* GRPC_CORE_LIB_CHANNEL_HTTP_CLIENT_FILTER_H */
+#endif /* GRPC_CORE_EXT_FILTERS_HTTP_CLIENT_HTTP_CLIENT_FILTER_H */
diff --git a/src/core/ext/filters/http/http_filters_plugin.c b/src/core/ext/filters/http/http_filters_plugin.c
new file mode 100644
index 0000000000000000000000000000000000000000..195a1a8119b6400d1d272eb47c54a6e6e014dda1
--- /dev/null
+++ b/src/core/ext/filters/http/http_filters_plugin.c
@@ -0,0 +1,103 @@
+/*
+ *
+ * Copyright 2017, 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 <string.h>
+
+#include "src/core/ext/filters/http/client/http_client_filter.h"
+#include "src/core/ext/filters/http/message_compress/message_compress_filter.h"
+#include "src/core/ext/filters/http/server/http_server_filter.h"
+#include "src/core/lib/channel/channel_stack_builder.h"
+#include "src/core/lib/surface/channel_init.h"
+#include "src/core/lib/transport/transport_impl.h"
+
+typedef struct {
+  const grpc_channel_filter *filter;
+  const char *control_channel_arg;
+} optional_filter;
+
+static optional_filter compress_filter = {
+    &grpc_message_compress_filter, GRPC_ARG_ENABLE_PER_MESSAGE_COMPRESSION};
+
+static bool is_building_http_like_transport(
+    grpc_channel_stack_builder *builder) {
+  grpc_transport *t = grpc_channel_stack_builder_get_transport(builder);
+  return t != NULL && strstr(t->vtable->name, "http");
+}
+
+static bool maybe_add_optional_filter(grpc_exec_ctx *exec_ctx,
+                                      grpc_channel_stack_builder *builder,
+                                      void *arg) {
+  if (!is_building_http_like_transport(builder)) return true;
+  optional_filter *filtarg = arg;
+  const grpc_channel_args *channel_args =
+      grpc_channel_stack_builder_get_channel_arguments(builder);
+  bool enable = grpc_channel_arg_get_bool(
+      grpc_channel_args_find(channel_args, filtarg->control_channel_arg),
+      !grpc_channel_args_want_minimal_stack(channel_args));
+  return enable ? grpc_channel_stack_builder_prepend_filter(
+                      builder, filtarg->filter, NULL, NULL)
+                : true;
+}
+
+static bool maybe_add_required_filter(grpc_exec_ctx *exec_ctx,
+                                      grpc_channel_stack_builder *builder,
+                                      void *arg) {
+  return is_building_http_like_transport(builder)
+             ? grpc_channel_stack_builder_prepend_filter(
+                   builder, (const grpc_channel_filter *)arg, NULL, NULL)
+             : true;
+}
+
+void grpc_http_filters_init(void) {
+  grpc_register_tracer("compression", &grpc_compression_trace);
+  grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL,
+                                   GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+                                   maybe_add_optional_filter, &compress_filter);
+  grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL,
+                                   GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+                                   maybe_add_optional_filter, &compress_filter);
+  grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL,
+                                   GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+                                   maybe_add_optional_filter, &compress_filter);
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+      maybe_add_required_filter, (void *)&grpc_http_client_filter);
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+      maybe_add_required_filter, (void *)&grpc_http_client_filter);
+  grpc_channel_init_register_stage(
+      GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+      maybe_add_required_filter, (void *)&grpc_http_server_filter);
+}
+
+void grpc_http_filters_shutdown(void) {}
diff --git a/src/core/lib/channel/compress_filter.c b/src/core/ext/filters/http/message_compress/message_compress_filter.c
similarity index 68%
rename from src/core/lib/channel/compress_filter.c
rename to src/core/ext/filters/http/message_compress/message_compress_filter.c
index aa41014a217ba727f9e18e0fe5451c6d2327b854..1da8cf69cbf39d7a2f6e8c983a34adc2ab125e27 100644
--- a/src/core/lib/channel/compress_filter.c
+++ b/src/core/ext/filters/http/message_compress/message_compress_filter.c
@@ -39,8 +39,8 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
+#include "src/core/ext/filters/http/message_compress/message_compress_filter.h"
 #include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/channel/compress_filter.h"
 #include "src/core/lib/compression/algorithm_metadata.h"
 #include "src/core/lib/compression/message_compress.h"
 #include "src/core/lib/profiling/timers.h"
@@ -49,7 +49,11 @@
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/static_metadata.h"
 
-int grpc_compression_trace = 0;
+#define INITIAL_METADATA_UNSEEN 0
+#define HAS_COMPRESSION_ALGORITHM 2
+#define NO_COMPRESSION_ALGORITHM 4
+
+#define CANCELLED_BIT ((gpr_atm)1)
 
 typedef struct call_data {
   grpc_slice_buffer slices; /**< Buffers up input slices to be compressed */
@@ -59,10 +63,19 @@ typedef struct call_data {
   /** Compression algorithm we'll try to use. It may be given by incoming
    * metadata, or by the channel's default compression settings. */
   grpc_compression_algorithm compression_algorithm;
-  /** If true, contents of \a compression_algorithm are authoritative */
-  int has_compression_algorithm;
 
-  grpc_transport_stream_op *send_op;
+  /* Atomic recording the state of initial metadata; allowed values:
+     INITIAL_METADATA_UNSEEN - initial metadata op not seen
+     HAS_COMPRESSION_ALGORITHM - initial metadata seen; compression algorithm
+                                 set
+     NO_COMPRESSION_ALGORITHM - initial metadata seen; no compression algorithm
+                                set
+     pointer - a stalled op containing a send_message that's waiting on initial
+               metadata
+     pointer | CANCELLED_BIT - request was cancelled with error pointed to */
+  gpr_atm send_initial_metadata_state;
+
+  grpc_transport_stream_op_batch *send_op;
   uint32_t send_length;
   uint32_t send_flags;
   grpc_slice incoming_slice;
@@ -81,14 +94,15 @@ typedef struct channel_data {
   uint32_t supported_compression_algorithms;
 } channel_data;
 
-static int skip_compression(grpc_call_element *elem, uint32_t flags) {
+static bool skip_compression(grpc_call_element *elem, uint32_t flags,
+                             bool has_compression_algorithm) {
   call_data *calld = elem->call_data;
   channel_data *channeld = elem->channel_data;
 
   if (flags & (GRPC_WRITE_NO_COMPRESS | GRPC_WRITE_INTERNAL_COMPRESS)) {
     return 1;
   }
-  if (calld->has_compression_algorithm) {
+  if (has_compression_algorithm) {
     if (calld->compression_algorithm == GRPC_COMPRESS_NONE) {
       return 1;
     }
@@ -101,12 +115,14 @@ static int skip_compression(grpc_call_element *elem, uint32_t flags) {
 /** Filter initial metadata */
 static grpc_error *process_send_initial_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-    grpc_metadata_batch *initial_metadata) GRPC_MUST_USE_RESULT;
+    grpc_metadata_batch *initial_metadata,
+    bool *has_compression_algorithm) GRPC_MUST_USE_RESULT;
 static grpc_error *process_send_initial_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-    grpc_metadata_batch *initial_metadata) {
+    grpc_metadata_batch *initial_metadata, bool *has_compression_algorithm) {
   call_data *calld = elem->call_data;
   channel_data *channeld = elem->channel_data;
+  *has_compression_algorithm = false;
   /* Parse incoming request for compression. If any, it'll be available
    * at calld->compression_algorithm */
   if (initial_metadata->idx.named.grpc_internal_encoding_request != NULL) {
@@ -130,7 +146,7 @@ static grpc_error *process_send_initial_metadata(
       gpr_free(val);
       calld->compression_algorithm = GRPC_COMPRESS_NONE;
     }
-    calld->has_compression_algorithm = 1;
+    *has_compression_algorithm = true;
 
     grpc_metadata_batch_remove(
         exec_ctx, initial_metadata,
@@ -140,7 +156,7 @@ static grpc_error *process_send_initial_metadata(
      * exceptionally skipping compression, fall back to the channel
      * default */
     calld->compression_algorithm = channeld->default_compression_algorithm;
-    calld->has_compression_algorithm = 1; /* GPR_TRUE */
+    *has_compression_algorithm = true;
   }
 
   grpc_error *error = GRPC_ERROR_NONE;
@@ -210,7 +226,8 @@ static void finish_send_message(grpc_exec_ctx *exec_ctx,
 
   grpc_slice_buffer_stream_init(&calld->replacement_stream, &calld->slices,
                                 calld->send_flags);
-  calld->send_op->send_message = &calld->replacement_stream.base;
+  calld->send_op->payload->send_message.send_message =
+      &calld->replacement_stream.base;
   calld->post_send = calld->send_op->on_complete;
   calld->send_op->on_complete = &calld->send_done;
 
@@ -220,6 +237,13 @@ static void finish_send_message(grpc_exec_ctx *exec_ctx,
 static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
   grpc_call_element *elem = elemp;
   call_data *calld = elem->call_data;
+  if (GRPC_ERROR_NONE !=
+      grpc_byte_stream_pull(exec_ctx,
+                            calld->send_op->payload->send_message.send_message,
+                            &calld->incoming_slice)) {
+    /* Should never reach here */
+    abort();
+  }
   grpc_slice_buffer_add(&calld->slices, calld->incoming_slice);
   if (calld->send_length == calld->slices.length) {
     finish_send_message(exec_ctx, elem);
@@ -231,9 +255,12 @@ static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
 static void continue_send_message(grpc_exec_ctx *exec_ctx,
                                   grpc_call_element *elem) {
   call_data *calld = elem->call_data;
-  while (grpc_byte_stream_next(exec_ctx, calld->send_op->send_message,
-                               &calld->incoming_slice, ~(size_t)0,
-                               &calld->got_slice)) {
+  while (grpc_byte_stream_next(
+      exec_ctx, calld->send_op->payload->send_message.send_message, ~(size_t)0,
+      &calld->got_slice)) {
+    grpc_byte_stream_pull(exec_ctx,
+                          calld->send_op->payload->send_message.send_message,
+                          &calld->incoming_slice);
     grpc_slice_buffer_add(&calld->slices, calld->incoming_slice);
     if (calld->send_length == calld->slices.length) {
       finish_send_message(exec_ctx, elem);
@@ -242,33 +269,104 @@ static void continue_send_message(grpc_exec_ctx *exec_ctx,
   }
 }
 
-static void compress_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
-                                               grpc_call_element *elem,
-                                               grpc_transport_stream_op *op) {
+static void compress_start_transport_stream_op_batch(
+    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+    grpc_transport_stream_op_batch *op) {
   call_data *calld = elem->call_data;
 
-  GPR_TIMER_BEGIN("compress_start_transport_stream_op", 0);
+  GPR_TIMER_BEGIN("compress_start_transport_stream_op_batch", 0);
+
+  if (op->cancel_stream) {
+    GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error);
+    gpr_atm cur = gpr_atm_full_xchg(
+        &calld->send_initial_metadata_state,
+        CANCELLED_BIT | (gpr_atm)op->payload->cancel_stream.cancel_error);
+    switch (cur) {
+      case HAS_COMPRESSION_ALGORITHM:
+      case NO_COMPRESSION_ALGORITHM:
+      case INITIAL_METADATA_UNSEEN:
+        break;
+      default:
+        if ((cur & CANCELLED_BIT) == 0) {
+          grpc_transport_stream_op_batch_finish_with_failure(
+              exec_ctx, (grpc_transport_stream_op_batch *)cur,
+              GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error));
+        } else {
+          GRPC_ERROR_UNREF((grpc_error *)(cur & ~CANCELLED_BIT));
+        }
+        break;
+    }
+  }
 
   if (op->send_initial_metadata) {
+    bool has_compression_algorithm;
     grpc_error *error = process_send_initial_metadata(
-        exec_ctx, elem, op->send_initial_metadata);
+        exec_ctx, elem,
+        op->payload->send_initial_metadata.send_initial_metadata,
+        &has_compression_algorithm);
     if (error != GRPC_ERROR_NONE) {
-      grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error);
+      grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, op, error);
       return;
     }
+    gpr_atm cur;
+  retry_send_im:
+    cur = gpr_atm_acq_load(&calld->send_initial_metadata_state);
+    GPR_ASSERT(cur != HAS_COMPRESSION_ALGORITHM &&
+               cur != NO_COMPRESSION_ALGORITHM);
+    if ((cur & CANCELLED_BIT) == 0) {
+      if (!gpr_atm_rel_cas(&calld->send_initial_metadata_state, cur,
+                           has_compression_algorithm
+                               ? HAS_COMPRESSION_ALGORITHM
+                               : NO_COMPRESSION_ALGORITHM)) {
+        goto retry_send_im;
+      }
+      if (cur != INITIAL_METADATA_UNSEEN) {
+        grpc_call_next_op(exec_ctx, elem,
+                          (grpc_transport_stream_op_batch *)cur);
+      }
+    }
   }
-  if (op->send_message != NULL &&
-      !skip_compression(elem, op->send_message->flags)) {
-    calld->send_op = op;
-    calld->send_length = op->send_message->length;
-    calld->send_flags = op->send_message->flags;
-    continue_send_message(exec_ctx, elem);
+  if (op->send_message) {
+    gpr_atm cur;
+  retry_send:
+    cur = gpr_atm_acq_load(&calld->send_initial_metadata_state);
+    switch (cur) {
+      case INITIAL_METADATA_UNSEEN:
+        if (!gpr_atm_rel_cas(&calld->send_initial_metadata_state, cur,
+                             (gpr_atm)op)) {
+          goto retry_send;
+        }
+        break;
+      case HAS_COMPRESSION_ALGORITHM:
+      case NO_COMPRESSION_ALGORITHM:
+        if (!skip_compression(elem,
+                              op->payload->send_message.send_message->flags,
+                              cur == HAS_COMPRESSION_ALGORITHM)) {
+          calld->send_op = op;
+          calld->send_length = op->payload->send_message.send_message->length;
+          calld->send_flags = op->payload->send_message.send_message->flags;
+          continue_send_message(exec_ctx, elem);
+        } else {
+          /* pass control down the stack */
+          grpc_call_next_op(exec_ctx, elem, op);
+        }
+        break;
+      default:
+        if (cur & CANCELLED_BIT) {
+          grpc_transport_stream_op_batch_finish_with_failure(
+              exec_ctx, op,
+              GRPC_ERROR_REF((grpc_error *)(cur & ~CANCELLED_BIT)));
+        } else {
+          /* >1 send_message concurrently */
+          GPR_UNREACHABLE_CODE(break);
+        }
+    }
   } else {
     /* pass control down the stack */
     grpc_call_next_op(exec_ctx, elem, op);
   }
 
-  GPR_TIMER_END("compress_start_transport_stream_op", 0);
+  GPR_TIMER_END("compress_start_transport_stream_op_batch", 0);
 }
 
 /* Constructor for call_data */
@@ -280,7 +378,6 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
 
   /* initialize members */
   grpc_slice_buffer_init(&calld->slices);
-  calld->has_compression_algorithm = 0;
   grpc_closure_init(&calld->got_slice, got_slice, elem,
                     grpc_schedule_on_exec_ctx);
   grpc_closure_init(&calld->send_done, send_done, elem,
@@ -292,10 +389,15 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
 /* Destructor for call_data */
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
-                              void *ignored) {
+                              grpc_closure *ignored) {
   /* grab pointers to our data from the call element */
   call_data *calld = elem->call_data;
   grpc_slice_buffer_destroy_internal(exec_ctx, &calld->slices);
+  gpr_atm imstate =
+      gpr_atm_no_barrier_load(&calld->send_initial_metadata_state);
+  if (imstate & CANCELLED_BIT) {
+    GRPC_ERROR_UNREF((grpc_error *)(imstate & ~CANCELLED_BIT));
+  }
 }
 
 /* Constructor for channel_data */
@@ -336,8 +438,8 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
                                  grpc_channel_element *elem) {}
 
-const grpc_channel_filter grpc_compress_filter = {
-    compress_start_transport_stream_op,
+const grpc_channel_filter grpc_message_compress_filter = {
+    compress_start_transport_stream_op_batch,
     grpc_channel_next_op,
     sizeof(call_data),
     init_call_elem,
diff --git a/src/core/lib/channel/compress_filter.h b/src/core/ext/filters/http/message_compress/message_compress_filter.h
similarity index 89%
rename from src/core/lib/channel/compress_filter.h
rename to src/core/ext/filters/http/message_compress/message_compress_filter.h
index e4a2a829d5997bddf422018344dfaaddffc3d7da..75bfa17fba31b03aa9d3bc98e166cd01a6c7e2db 100644
--- a/src/core/lib/channel/compress_filter.h
+++ b/src/core/ext/filters/http/message_compress/message_compress_filter.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_CHANNEL_COMPRESS_FILTER_H
-#define GRPC_CORE_LIB_CHANNEL_COMPRESS_FILTER_H
+#ifndef GRPC_CORE_EXT_FILTERS_HTTP_MESSAGE_COMPRESS_MESSAGE_COMPRESS_FILTER_H
+#define GRPC_CORE_EXT_FILTERS_HTTP_MESSAGE_COMPRESS_MESSAGE_COMPRESS_FILTER_H
 
 #include <grpc/impl/codegen/compression_types.h>
 
@@ -62,6 +62,7 @@ extern int grpc_compression_trace;
  * aforementioned 'grpc-encoding' metadata value, data will pass through
  * uncompressed. */
 
-extern const grpc_channel_filter grpc_compress_filter;
+extern const grpc_channel_filter grpc_message_compress_filter;
 
-#endif /* GRPC_CORE_LIB_CHANNEL_COMPRESS_FILTER_H */
+#endif /* GRPC_CORE_EXT_FILTERS_HTTP_MESSAGE_COMPRESS_MESSAGE_COMPRESS_FILTER_H \
+          */
diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/ext/filters/http/server/http_server_filter.c
similarity index 66%
rename from src/core/lib/channel/http_server_filter.c
rename to src/core/ext/filters/http/server/http_server_filter.c
index fb70de8e96c5f8093a659659734b8e2ca77c9bea..ff857878e46b527122382181b42659d842d47159 100644
--- a/src/core/lib/channel/http_server_filter.c
+++ b/src/core/ext/filters/http/server/http_server_filter.c
@@ -31,12 +31,13 @@
  *
  */
 
-#include "src/core/lib/channel/http_server_filter.h"
+#include "src/core/ext/filters/http/server/http_server_filter.h"
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <string.h>
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/b64.h"
 #include "src/core/lib/slice/percent_encoding.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
@@ -51,17 +52,16 @@ typedef struct call_data {
   grpc_linked_mdelem status;
   grpc_linked_mdelem content_type;
 
-  /* did this request come with payload-bin */
-  bool seen_payload_bin;
+  /* did this request come with path query containing request payload */
+  bool seen_path_with_query;
   /* flag to ensure payload_bin is delivered only once */
   bool payload_bin_delivered;
 
   grpc_metadata_batch *recv_initial_metadata;
-  bool *recv_idempotent_request;
-  bool *recv_cacheable_request;
+  uint32_t *recv_initial_metadata_flags;
   /** Closure to call when finished with the hs_on_recv hook */
   grpc_closure *on_done_recv;
-  /** Closure to call when we retrieve read message from the payload-bin header
+  /** Closure to call when we retrieve read message from the path URI
    */
   grpc_closure *recv_message_ready;
   grpc_closure *on_complete;
@@ -101,7 +101,7 @@ static void add_error(const char *error_name, grpc_error **cumulative,
                       grpc_error *new) {
   if (new == GRPC_ERROR_NONE) return;
   if (*cumulative == GRPC_ERROR_NONE) {
-    *cumulative = GRPC_ERROR_CREATE(error_name);
+    *cumulative = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_name);
   }
   *cumulative = grpc_error_add_child(*cumulative, new);
 }
@@ -115,37 +115,49 @@ static grpc_error *server_filter_incoming_metadata(grpc_exec_ctx *exec_ctx,
 
   if (b->idx.named.method != NULL) {
     if (grpc_mdelem_eq(b->idx.named.method->md, GRPC_MDELEM_METHOD_POST)) {
-      *calld->recv_idempotent_request = false;
-      *calld->recv_cacheable_request = false;
+      *calld->recv_initial_metadata_flags &=
+          ~(GRPC_INITIAL_METADATA_CACHEABLE_REQUEST |
+            GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST);
     } else if (grpc_mdelem_eq(b->idx.named.method->md,
                               GRPC_MDELEM_METHOD_PUT)) {
-      *calld->recv_idempotent_request = true;
+      *calld->recv_initial_metadata_flags &=
+          ~GRPC_INITIAL_METADATA_CACHEABLE_REQUEST;
+      *calld->recv_initial_metadata_flags |=
+          GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST;
     } else if (grpc_mdelem_eq(b->idx.named.method->md,
                               GRPC_MDELEM_METHOD_GET)) {
-      *calld->recv_cacheable_request = true;
+      *calld->recv_initial_metadata_flags |=
+          GRPC_INITIAL_METADATA_CACHEABLE_REQUEST;
+      *calld->recv_initial_metadata_flags &=
+          ~GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST;
     } else {
       add_error(error_name, &error,
-                grpc_attach_md_to_error(GRPC_ERROR_CREATE("Bad header"),
-                                        b->idx.named.method->md));
+                grpc_attach_md_to_error(
+                    GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad header"),
+                    b->idx.named.method->md));
     }
     grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.method);
   } else {
-    add_error(error_name, &error,
-              grpc_error_set_str(GRPC_ERROR_CREATE("Missing header"),
-                                 GRPC_ERROR_STR_KEY, ":method"));
+    add_error(
+        error_name, &error,
+        grpc_error_set_str(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing header"),
+            GRPC_ERROR_STR_KEY, grpc_slice_from_static_string(":method")));
   }
 
   if (b->idx.named.te != NULL) {
     if (!grpc_mdelem_eq(b->idx.named.te->md, GRPC_MDELEM_TE_TRAILERS)) {
       add_error(error_name, &error,
-                grpc_attach_md_to_error(GRPC_ERROR_CREATE("Bad header"),
-                                        b->idx.named.te->md));
+                grpc_attach_md_to_error(
+                    GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad header"),
+                    b->idx.named.te->md));
     }
     grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.te);
   } else {
     add_error(error_name, &error,
-              grpc_error_set_str(GRPC_ERROR_CREATE("Missing header"),
-                                 GRPC_ERROR_STR_KEY, "te"));
+              grpc_error_set_str(
+                  GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing header"),
+                  GRPC_ERROR_STR_KEY, grpc_slice_from_static_string("te")));
   }
 
   if (b->idx.named.scheme != NULL) {
@@ -153,14 +165,17 @@ static grpc_error *server_filter_incoming_metadata(grpc_exec_ctx *exec_ctx,
         !grpc_mdelem_eq(b->idx.named.scheme->md, GRPC_MDELEM_SCHEME_HTTPS) &&
         !grpc_mdelem_eq(b->idx.named.scheme->md, GRPC_MDELEM_SCHEME_GRPC)) {
       add_error(error_name, &error,
-                grpc_attach_md_to_error(GRPC_ERROR_CREATE("Bad header"),
-                                        b->idx.named.scheme->md));
+                grpc_attach_md_to_error(
+                    GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad header"),
+                    b->idx.named.scheme->md));
     }
     grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.scheme);
   } else {
-    add_error(error_name, &error,
-              grpc_error_set_str(GRPC_ERROR_CREATE("Missing header"),
-                                 GRPC_ERROR_STR_KEY, ":scheme"));
+    add_error(
+        error_name, &error,
+        grpc_error_set_str(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing header"),
+            GRPC_ERROR_STR_KEY, grpc_slice_from_static_string(":scheme")));
   }
 
   if (b->idx.named.content_type != NULL) {
@@ -194,8 +209,47 @@ static grpc_error *server_filter_incoming_metadata(grpc_exec_ctx *exec_ctx,
 
   if (b->idx.named.path == NULL) {
     add_error(error_name, &error,
-              grpc_error_set_str(GRPC_ERROR_CREATE("Missing header"),
-                                 GRPC_ERROR_STR_KEY, ":path"));
+              grpc_error_set_str(
+                  GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing header"),
+                  GRPC_ERROR_STR_KEY, grpc_slice_from_static_string(":path")));
+  } else if (*calld->recv_initial_metadata_flags &
+             GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) {
+    /* We have a cacheable request made with GET verb. The path contains the
+     * query parameter which is base64 encoded request payload. */
+    const char k_query_separator = '?';
+    grpc_slice path_slice = GRPC_MDVALUE(b->idx.named.path->md);
+    uint8_t *path_ptr = (uint8_t *)GRPC_SLICE_START_PTR(path_slice);
+    size_t path_length = GRPC_SLICE_LENGTH(path_slice);
+    /* offset of the character '?' */
+    size_t offset = 0;
+    for (offset = 0; offset < path_length && *path_ptr != k_query_separator;
+         path_ptr++, offset++)
+      ;
+    if (offset < path_length) {
+      grpc_slice query_slice =
+          grpc_slice_sub(path_slice, offset + 1, path_length);
+
+      /* substitute path metadata with just the path (not query) */
+      grpc_mdelem mdelem_path_without_query = grpc_mdelem_from_slices(
+          exec_ctx, GRPC_MDSTR_PATH, grpc_slice_sub(path_slice, 0, offset));
+
+      grpc_metadata_batch_substitute(exec_ctx, b, b->idx.named.path,
+                                     mdelem_path_without_query);
+
+      /* decode payload from query and add to the slice buffer to be returned */
+      const int k_url_safe = 1;
+      grpc_slice_buffer_add(
+          &calld->read_slice_buffer,
+          grpc_base64_decode_with_len(
+              exec_ctx, (const char *)GRPC_SLICE_START_PTR(query_slice),
+              GRPC_SLICE_LENGTH(query_slice), k_url_safe));
+      grpc_slice_buffer_stream_init(&calld->read_stream,
+                                    &calld->read_slice_buffer, 0);
+      calld->seen_path_with_query = true;
+      grpc_slice_unref_internal(exec_ctx, query_slice);
+    } else {
+      gpr_log(GPR_ERROR, "GET request without QUERY");
+    }
   }
 
   if (b->idx.named.host != NULL && b->idx.named.authority == NULL) {
@@ -212,19 +266,11 @@ static grpc_error *server_filter_incoming_metadata(grpc_exec_ctx *exec_ctx,
   }
 
   if (b->idx.named.authority == NULL) {
-    add_error(error_name, &error,
-              grpc_error_set_str(GRPC_ERROR_CREATE("Missing header"),
-                                 GRPC_ERROR_STR_KEY, ":authority"));
-  }
-
-  if (b->idx.named.grpc_payload_bin != NULL) {
-    calld->seen_payload_bin = true;
-    grpc_slice_buffer_add(&calld->read_slice_buffer,
-                          grpc_slice_ref_internal(
-                              GRPC_MDVALUE(b->idx.named.grpc_payload_bin->md)));
-    grpc_slice_buffer_stream_init(&calld->read_stream,
-                                  &calld->read_slice_buffer, 0);
-    grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.grpc_payload_bin);
+    add_error(
+        error_name, &error,
+        grpc_error_set_str(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing header"),
+            GRPC_ERROR_STR_KEY, grpc_slice_from_static_string(":authority")));
   }
 
   return error;
@@ -247,8 +293,8 @@ static void hs_on_complete(grpc_exec_ctx *exec_ctx, void *user_data,
                            grpc_error *err) {
   grpc_call_element *elem = user_data;
   call_data *calld = elem->call_data;
-  /* Call recv_message_ready if we got the payload via the header field */
-  if (calld->seen_payload_bin && calld->recv_message_ready != NULL) {
+  /* Call recv_message_ready if we got the payload via the path field */
+  if (calld->seen_path_with_query && calld->recv_message_ready != NULL) {
     *calld->pp_recv_message = calld->payload_bin_delivered
                                   ? NULL
                                   : (grpc_byte_stream *)&calld->read_stream;
@@ -263,7 +309,7 @@ static void hs_recv_message_ready(grpc_exec_ctx *exec_ctx, void *user_data,
                                   grpc_error *err) {
   grpc_call_element *elem = user_data;
   call_data *calld = elem->call_data;
-  if (calld->seen_payload_bin) {
+  if (calld->seen_path_with_query) {
     /* do nothing. This is probably a GET request, and payload will be returned
     in hs_on_complete callback. */
   } else {
@@ -272,45 +318,53 @@ static void hs_recv_message_ready(grpc_exec_ctx *exec_ctx, void *user_data,
 }
 
 static void hs_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                         grpc_transport_stream_op *op) {
+                         grpc_transport_stream_op_batch *op) {
   /* grab pointers to our data from the call element */
   call_data *calld = elem->call_data;
 
-  if (op->send_initial_metadata != NULL) {
+  if (op->send_initial_metadata) {
     grpc_error *error = GRPC_ERROR_NONE;
     static const char *error_name = "Failed sending initial metadata";
-    add_error(error_name, &error, grpc_metadata_batch_add_head(
-                                      exec_ctx, op->send_initial_metadata,
-                                      &calld->status, GRPC_MDELEM_STATUS_200));
-    add_error(error_name, &error,
-              grpc_metadata_batch_add_tail(
-                  exec_ctx, op->send_initial_metadata, &calld->content_type,
-                  GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC));
+    add_error(
+        error_name, &error,
+        grpc_metadata_batch_add_head(
+            exec_ctx, op->payload->send_initial_metadata.send_initial_metadata,
+            &calld->status, GRPC_MDELEM_STATUS_200));
+    add_error(
+        error_name, &error,
+        grpc_metadata_batch_add_tail(
+            exec_ctx, op->payload->send_initial_metadata.send_initial_metadata,
+            &calld->content_type,
+            GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC));
     add_error(error_name, &error,
-              server_filter_outgoing_metadata(exec_ctx, elem,
-                                              op->send_initial_metadata));
+              server_filter_outgoing_metadata(
+                  exec_ctx, elem,
+                  op->payload->send_initial_metadata.send_initial_metadata));
     if (error != GRPC_ERROR_NONE) {
-      grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error);
+      grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, op, error);
       return;
     }
   }
 
   if (op->recv_initial_metadata) {
     /* substitute our callback for the higher callback */
-    GPR_ASSERT(op->recv_idempotent_request != NULL);
-    GPR_ASSERT(op->recv_cacheable_request != NULL);
-    calld->recv_initial_metadata = op->recv_initial_metadata;
-    calld->recv_idempotent_request = op->recv_idempotent_request;
-    calld->recv_cacheable_request = op->recv_cacheable_request;
-    calld->on_done_recv = op->recv_initial_metadata_ready;
-    op->recv_initial_metadata_ready = &calld->hs_on_recv;
+    GPR_ASSERT(op->payload->recv_initial_metadata.recv_flags != NULL);
+    calld->recv_initial_metadata =
+        op->payload->recv_initial_metadata.recv_initial_metadata;
+    calld->recv_initial_metadata_flags =
+        op->payload->recv_initial_metadata.recv_flags;
+    calld->on_done_recv =
+        op->payload->recv_initial_metadata.recv_initial_metadata_ready;
+    op->payload->recv_initial_metadata.recv_initial_metadata_ready =
+        &calld->hs_on_recv;
   }
 
   if (op->recv_message) {
-    calld->recv_message_ready = op->recv_message_ready;
-    calld->pp_recv_message = op->recv_message;
-    if (op->recv_message_ready) {
-      op->recv_message_ready = &calld->hs_recv_message_ready;
+    calld->recv_message_ready = op->payload->recv_message.recv_message_ready;
+    calld->pp_recv_message = op->payload->recv_message.recv_message;
+    if (op->payload->recv_message.recv_message_ready) {
+      op->payload->recv_message.recv_message_ready =
+          &calld->hs_recv_message_ready;
     }
     if (op->on_complete) {
       calld->on_complete = op->on_complete;
@@ -320,9 +374,10 @@ static void hs_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 
   if (op->send_trailing_metadata) {
     grpc_error *error = server_filter_outgoing_metadata(
-        exec_ctx, elem, op->send_trailing_metadata);
+        exec_ctx, elem,
+        op->payload->send_trailing_metadata.send_trailing_metadata);
     if (error != GRPC_ERROR_NONE) {
-      grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error);
+      grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, op, error);
       return;
     }
   }
@@ -330,7 +385,7 @@ static void hs_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 
 static void hs_start_transport_op(grpc_exec_ctx *exec_ctx,
                                   grpc_call_element *elem,
-                                  grpc_transport_stream_op *op) {
+                                  grpc_transport_stream_op_batch *op) {
   GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
   GPR_TIMER_BEGIN("hs_start_transport_op", 0);
   hs_mutate_op(exec_ctx, elem, op);
@@ -358,7 +413,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
 /* Destructor for call_data */
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
-                              void *ignored) {
+                              grpc_closure *ignored) {
   call_data *calld = elem->call_data;
   grpc_slice_buffer_destroy_internal(exec_ctx, &calld->read_slice_buffer);
 }
diff --git a/src/core/lib/channel/http_server_filter.h b/src/core/ext/filters/http/server/http_server_filter.h
similarity index 89%
rename from src/core/lib/channel/http_server_filter.h
rename to src/core/ext/filters/http/server/http_server_filter.h
index 77ba2d263d1ac1aa0b14e9618e8587f8f4a6edff..8a2b2196ae149a6cf5bf0496f00a4a34aacd3d2b 100644
--- a/src/core/lib/channel/http_server_filter.h
+++ b/src/core/ext/filters/http/server/http_server_filter.h
@@ -31,12 +31,12 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_CHANNEL_HTTP_SERVER_FILTER_H
-#define GRPC_CORE_LIB_CHANNEL_HTTP_SERVER_FILTER_H
+#ifndef GRPC_CORE_EXT_FILTERS_HTTP_SERVER_HTTP_SERVER_FILTER_H
+#define GRPC_CORE_EXT_FILTERS_HTTP_SERVER_HTTP_SERVER_FILTER_H
 
 #include "src/core/lib/channel/channel_stack.h"
 
 /* Processes metadata on the client side for HTTP2 transports */
 extern const grpc_channel_filter grpc_http_server_filter;
 
-#endif /* GRPC_CORE_LIB_CHANNEL_HTTP_SERVER_FILTER_H */
+#endif /* GRPC_CORE_EXT_FILTERS_HTTP_SERVER_HTTP_SERVER_FILTER_H */
diff --git a/src/core/ext/load_reporting/load_reporting.c b/src/core/ext/filters/load_reporting/load_reporting.c
similarity index 75%
rename from src/core/ext/load_reporting/load_reporting.c
rename to src/core/ext/filters/load_reporting/load_reporting.c
index 942aea4fd1cf25f8f03703895066624583b9b466..4e9d0937ae0f7bd59b9a67715725d0a2fde8583a 100644
--- a/src/core/ext/load_reporting/load_reporting.c
+++ b/src/core/ext/filters/load_reporting/load_reporting.c
@@ -31,6 +31,8 @@
  *
  */
 
+#include <grpc/support/port_platform.h>
+
 #include <limits.h>
 #include <string.h>
 
@@ -38,39 +40,16 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/sync.h>
 
-#include "src/core/ext/load_reporting/load_reporting.h"
-#include "src/core/ext/load_reporting/load_reporting_filter.h"
+#include "src/core/ext/filters/load_reporting/load_reporting.h"
+#include "src/core/ext/filters/load_reporting/load_reporting_filter.h"
 #include "src/core/lib/channel/channel_stack_builder.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/surface/channel_init.h"
 
-static void destroy_lr_cost_context(void *c) {
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_load_reporting_cost_context *cost_ctx = c;
-  for (size_t i = 0; i < cost_ctx->values_count; ++i) {
-    grpc_slice_unref_internal(&exec_ctx, cost_ctx->values[i]);
-  }
-  grpc_exec_ctx_finish(&exec_ctx);
-  gpr_free(cost_ctx->values);
-  gpr_free(cost_ctx);
-}
-
-void grpc_call_set_load_reporting_cost_context(
-    grpc_call *call, grpc_load_reporting_cost_context *ctx) {
-  grpc_call_context_set(call, GRPC_CONTEXT_LR_COST, ctx,
-                        destroy_lr_cost_context);
-}
-
 static bool is_load_reporting_enabled(const grpc_channel_args *a) {
-  if (a == NULL) return false;
-  for (size_t i = 0; i < a->num_args; i++) {
-    if (0 == strcmp(a->args[i].key, GRPC_ARG_ENABLE_LOAD_REPORTING)) {
-      return a->args[i].type == GRPC_ARG_INTEGER &&
-             a->args[i].value.integer != 0;
-    }
-  }
-  return false;
+  return grpc_channel_arg_get_bool(
+      grpc_channel_args_find(a, GRPC_ARG_ENABLE_LOAD_REPORTING), false);
 }
 
 static bool maybe_add_load_reporting_filter(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/ext/load_reporting/load_reporting.h b/src/core/ext/filters/load_reporting/load_reporting.h
similarity index 93%
rename from src/core/ext/load_reporting/load_reporting.h
rename to src/core/ext/filters/load_reporting/load_reporting.h
index 22859a599a7451d85c1b26bac232930e596a65ed..e05a9dcc715ad671c22bf36b7d1a5dfbf4810eb2 100644
--- a/src/core/ext/load_reporting/load_reporting.h
+++ b/src/core/ext/filters/load_reporting/load_reporting.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_H
-#define GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_H
+#ifndef GRPC_CORE_EXT_FILTERS_LOAD_REPORTING_LOAD_REPORTING_H
+#define GRPC_CORE_EXT_FILTERS_LOAD_REPORTING_LOAD_REPORTING_H
 
 #include <grpc/impl/codegen/grpc_types.h>
 
@@ -70,4 +70,4 @@ typedef struct grpc_load_reporting_call_data {
 /** Return a \a grpc_arg enabling load reporting */
 grpc_arg grpc_load_reporting_enable_arg();
 
-#endif /* GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_H */
+#endif /* GRPC_CORE_EXT_FILTERS_LOAD_REPORTING_LOAD_REPORTING_H */
diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/filters/load_reporting/load_reporting_filter.c
similarity index 79%
rename from src/core/ext/load_reporting/load_reporting_filter.c
rename to src/core/ext/filters/load_reporting/load_reporting_filter.c
index c2750634a50e1db089b63f89795378bf923070ef..75a9a566871cacc1e3cb1a6aee739f9d59d61493 100644
--- a/src/core/ext/load_reporting/load_reporting_filter.c
+++ b/src/core/ext/filters/load_reporting/load_reporting_filter.c
@@ -39,8 +39,8 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/sync.h>
 
-#include "src/core/ext/load_reporting/load_reporting.h"
-#include "src/core/ext/load_reporting/load_reporting_filter.h"
+#include "src/core/ext/filters/load_reporting/load_reporting.h"
+#include "src/core/ext/filters/load_reporting/load_reporting_filter.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/slice/slice_internal.h"
@@ -48,6 +48,8 @@
 
 typedef struct call_data {
   intptr_t id; /**< an id unique to the call */
+  bool have_trailing_md_string;
+  grpc_slice trailing_md_string;
   bool have_initial_md_string;
   grpc_slice initial_md_string;
   bool have_service_method;
@@ -78,8 +80,8 @@ static void on_initial_md_ready(grpc_exec_ctx *exec_ctx, void *user_data,
           GRPC_MDVALUE(calld->recv_initial_metadata->idx.named.path->md));
       calld->have_service_method = true;
     } else {
-      err =
-          grpc_error_add_child(err, GRPC_ERROR_CREATE("Missing :path header"));
+      err = grpc_error_add_child(
+          err, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing :path header"));
     }
     if (calld->recv_initial_metadata->idx.named.lb_token != NULL) {
       calld->initial_md_string = grpc_slice_ref_internal(
@@ -123,7 +125,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
 /* Destructor for call_data */
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
-                              void *ignored) {
+                              grpc_closure *ignored) {
   call_data *calld = elem->call_data;
 
   /* TODO(dgq): do something with the data
@@ -140,6 +142,9 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
   if (calld->have_initial_md_string) {
     grpc_slice_unref_internal(exec_ctx, calld->initial_md_string);
   }
+  if (calld->have_trailing_md_string) {
+    grpc_slice_unref_internal(exec_ctx, calld->trailing_md_string);
+  }
   if (calld->have_service_method) {
     grpc_slice_unref_internal(exec_ctx, calld->service_method);
   }
@@ -183,25 +188,48 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
   */
 }
 
-static void lr_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
-                                         grpc_call_element *elem,
-                                         grpc_transport_stream_op *op) {
-  GPR_TIMER_BEGIN("lr_start_transport_stream_op", 0);
+static grpc_filtered_mdelem lr_trailing_md_filter(grpc_exec_ctx *exec_ctx,
+                                                  void *user_data,
+                                                  grpc_mdelem md) {
+  grpc_call_element *elem = user_data;
+  call_data *calld = elem->call_data;
+  if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_LB_COST_BIN)) {
+    calld->trailing_md_string = GRPC_MDVALUE(md);
+    return GRPC_FILTERED_REMOVE();
+  }
+  return GRPC_FILTERED_MDELEM(md);
+}
+
+static void lr_start_transport_stream_op_batch(
+    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+    grpc_transport_stream_op_batch *op) {
+  GPR_TIMER_BEGIN("lr_start_transport_stream_op_batch", 0);
   call_data *calld = elem->call_data;
 
   if (op->recv_initial_metadata) {
-    calld->recv_initial_metadata = op->recv_initial_metadata;
     /* substitute our callback for the higher callback */
-    calld->ops_recv_initial_metadata_ready = op->recv_initial_metadata_ready;
-    op->recv_initial_metadata_ready = &calld->on_initial_md_ready;
+    calld->recv_initial_metadata =
+        op->payload->recv_initial_metadata.recv_initial_metadata;
+    calld->ops_recv_initial_metadata_ready =
+        op->payload->recv_initial_metadata.recv_initial_metadata_ready;
+    op->payload->recv_initial_metadata.recv_initial_metadata_ready =
+        &calld->on_initial_md_ready;
+  } else if (op->send_trailing_metadata) {
+    GRPC_LOG_IF_ERROR(
+        "grpc_metadata_batch_filter",
+        grpc_metadata_batch_filter(
+            exec_ctx,
+            op->payload->send_trailing_metadata.send_trailing_metadata,
+            lr_trailing_md_filter, elem,
+            "LR trailing metadata filtering error"));
   }
   grpc_call_next_op(exec_ctx, elem, op);
 
-  GPR_TIMER_END("lr_start_transport_stream_op", 0);
+  GPR_TIMER_END("lr_start_transport_stream_op_batch", 0);
 }
 
 const grpc_channel_filter grpc_load_reporting_filter = {
-    lr_start_transport_stream_op,
+    lr_start_transport_stream_op_batch,
     grpc_channel_next_op,
     sizeof(call_data),
     init_call_elem,
diff --git a/src/core/ext/load_reporting/load_reporting_filter.h b/src/core/ext/filters/load_reporting/load_reporting_filter.h
similarity index 85%
rename from src/core/ext/load_reporting/load_reporting_filter.h
rename to src/core/ext/filters/load_reporting/load_reporting_filter.h
index 160ed32af99c352045d7465eca2a02e9ad75f834..da884a147933f668d9d91440c0dfb095cf0ec722 100644
--- a/src/core/ext/load_reporting/load_reporting_filter.h
+++ b/src/core/ext/filters/load_reporting/load_reporting_filter.h
@@ -31,12 +31,12 @@
  *
  */
 
-#ifndef GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_FILTER_H
-#define GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_FILTER_H
+#ifndef GRPC_CORE_EXT_FILTERS_LOAD_REPORTING_LOAD_REPORTING_FILTER_H
+#define GRPC_CORE_EXT_FILTERS_LOAD_REPORTING_LOAD_REPORTING_FILTER_H
 
-#include "src/core/ext/load_reporting/load_reporting.h"
+#include "src/core/ext/filters/load_reporting/load_reporting.h"
 #include "src/core/lib/channel/channel_stack.h"
 
 extern const grpc_channel_filter grpc_load_reporting_filter;
 
-#endif /* GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_FILTER_H */
+#endif /* GRPC_CORE_EXT_FILTERS_LOAD_REPORTING_LOAD_REPORTING_FILTER_H */
diff --git a/src/core/ext/filters/max_age/max_age_filter.c b/src/core/ext/filters/max_age/max_age_filter.c
new file mode 100644
index 0000000000000000000000000000000000000000..a9d91e2f80cb592141d066161313f555f110b5d9
--- /dev/null
+++ b/src/core/ext/filters/max_age/max_age_filter.c
@@ -0,0 +1,439 @@
+/*
+ *
+ * Copyright 2017, 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/ext/filters/max_age/max_age_filter.h"
+
+#include <limits.h>
+#include <string.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/channel/channel_stack_builder.h"
+#include "src/core/lib/iomgr/timer.h"
+#include "src/core/lib/surface/channel_init.h"
+#include "src/core/lib/transport/http2_errors.h"
+
+#define DEFAULT_MAX_CONNECTION_AGE_MS INT_MAX
+#define DEFAULT_MAX_CONNECTION_AGE_GRACE_MS INT_MAX
+#define DEFAULT_MAX_CONNECTION_IDLE_MS INT_MAX
+#define MAX_CONNECTION_AGE_JITTER 0.1
+
+#define MAX_CONNECTION_AGE_INTEGER_OPTIONS \
+  (grpc_integer_options) { DEFAULT_MAX_CONNECTION_AGE_MS, 1, INT_MAX }
+#define MAX_CONNECTION_IDLE_INTEGER_OPTIONS \
+  (grpc_integer_options) { DEFAULT_MAX_CONNECTION_IDLE_MS, 1, INT_MAX }
+
+typedef struct channel_data {
+  /* We take a reference to the channel stack for the timer callback */
+  grpc_channel_stack* channel_stack;
+  /* Guards access to max_age_timer, max_age_timer_pending, max_age_grace_timer
+     and max_age_grace_timer_pending */
+  gpr_mu max_age_timer_mu;
+  /* True if the max_age timer callback is currently pending */
+  bool max_age_timer_pending;
+  /* True if the max_age_grace timer callback is currently pending */
+  bool max_age_grace_timer_pending;
+  /* The timer for checking if the channel has reached its max age */
+  grpc_timer max_age_timer;
+  /* The timer for checking if the max-aged channel has uesed up the grace
+     period */
+  grpc_timer max_age_grace_timer;
+  /* The timer for checking if the channel's idle duration reaches
+     max_connection_idle */
+  grpc_timer max_idle_timer;
+  /* Allowed max time a channel may have no outstanding rpcs */
+  gpr_timespec max_connection_idle;
+  /* Allowed max time a channel may exist */
+  gpr_timespec max_connection_age;
+  /* Allowed grace period after the channel reaches its max age */
+  gpr_timespec max_connection_age_grace;
+  /* Closure to run when the channel's idle duration reaches max_connection_idle
+     and should be closed gracefully */
+  grpc_closure close_max_idle_channel;
+  /* Closure to run when the channel reaches its max age and should be closed
+     gracefully */
+  grpc_closure close_max_age_channel;
+  /* Closure to run the channel uses up its max age grace time and should be
+     closed forcibly */
+  grpc_closure force_close_max_age_channel;
+  /* Closure to run when the init fo channel stack is done and the max_idle
+     timer should be started */
+  grpc_closure start_max_idle_timer_after_init;
+  /* Closure to run when the init fo channel stack is done and the max_age timer
+     should be started */
+  grpc_closure start_max_age_timer_after_init;
+  /* Closure to run when the goaway op is finished and the max_age_timer */
+  grpc_closure start_max_age_grace_timer_after_goaway_op;
+  /* Closure to run when the channel connectivity state changes */
+  grpc_closure channel_connectivity_changed;
+  /* Records the current connectivity state */
+  grpc_connectivity_state connectivity_state;
+  /* Number of active calls */
+  gpr_atm call_count;
+} channel_data;
+
+/* Increase the nubmer of active calls. Before the increasement, if there are no
+   calls, the max_idle_timer should be cancelled. */
+static void increase_call_count(grpc_exec_ctx* exec_ctx, channel_data* chand) {
+  if (gpr_atm_full_fetch_add(&chand->call_count, 1) == 0) {
+    grpc_timer_cancel(exec_ctx, &chand->max_idle_timer);
+  }
+}
+
+/* Decrease the nubmer of active calls. After the decrement, if there are no
+   calls, the max_idle_timer should be started. */
+static void decrease_call_count(grpc_exec_ctx* exec_ctx, channel_data* chand) {
+  if (gpr_atm_full_fetch_add(&chand->call_count, -1) == 1) {
+    GRPC_CHANNEL_STACK_REF(chand->channel_stack, "max_age max_idle_timer");
+    grpc_timer_init(
+        exec_ctx, &chand->max_idle_timer,
+        gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), chand->max_connection_idle),
+        &chand->close_max_idle_channel, gpr_now(GPR_CLOCK_MONOTONIC));
+  }
+}
+
+static void start_max_idle_timer_after_init(grpc_exec_ctx* exec_ctx, void* arg,
+                                            grpc_error* error) {
+  channel_data* chand = arg;
+  /* Decrease call_count. If there are no active calls at this time,
+     max_idle_timer will start here. If the number of active calls is not 0,
+     max_idle_timer will start after all the active calls end. */
+  decrease_call_count(exec_ctx, chand);
+  GRPC_CHANNEL_STACK_UNREF(exec_ctx, chand->channel_stack,
+                           "max_age start_max_idle_timer_after_init");
+}
+
+static void start_max_age_timer_after_init(grpc_exec_ctx* exec_ctx, void* arg,
+                                           grpc_error* error) {
+  channel_data* chand = arg;
+  gpr_mu_lock(&chand->max_age_timer_mu);
+  chand->max_age_timer_pending = true;
+  GRPC_CHANNEL_STACK_REF(chand->channel_stack, "max_age max_age_timer");
+  grpc_timer_init(
+      exec_ctx, &chand->max_age_timer,
+      gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), chand->max_connection_age),
+      &chand->close_max_age_channel, gpr_now(GPR_CLOCK_MONOTONIC));
+  gpr_mu_unlock(&chand->max_age_timer_mu);
+  grpc_transport_op* op = grpc_make_transport_op(NULL);
+  op->on_connectivity_state_change = &chand->channel_connectivity_changed,
+  op->connectivity_state = &chand->connectivity_state;
+  grpc_channel_next_op(exec_ctx,
+                       grpc_channel_stack_element(chand->channel_stack, 0), op);
+  GRPC_CHANNEL_STACK_UNREF(exec_ctx, chand->channel_stack,
+                           "max_age start_max_age_timer_after_init");
+}
+
+static void start_max_age_grace_timer_after_goaway_op(grpc_exec_ctx* exec_ctx,
+                                                      void* arg,
+                                                      grpc_error* error) {
+  channel_data* chand = arg;
+  gpr_mu_lock(&chand->max_age_timer_mu);
+  chand->max_age_grace_timer_pending = true;
+  GRPC_CHANNEL_STACK_REF(chand->channel_stack, "max_age max_age_grace_timer");
+  grpc_timer_init(exec_ctx, &chand->max_age_grace_timer,
+                  gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+                               chand->max_connection_age_grace),
+                  &chand->force_close_max_age_channel,
+                  gpr_now(GPR_CLOCK_MONOTONIC));
+  gpr_mu_unlock(&chand->max_age_timer_mu);
+  GRPC_CHANNEL_STACK_UNREF(exec_ctx, chand->channel_stack,
+                           "max_age start_max_age_grace_timer_after_goaway_op");
+}
+
+static void close_max_idle_channel(grpc_exec_ctx* exec_ctx, void* arg,
+                                   grpc_error* error) {
+  channel_data* chand = arg;
+  if (error == GRPC_ERROR_NONE) {
+    /* Prevent the max idle timer from being set again */
+    gpr_atm_no_barrier_fetch_add(&chand->call_count, 1);
+    grpc_transport_op* op = grpc_make_transport_op(NULL);
+    op->goaway_error =
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("max_idle"),
+                           GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_NO_ERROR);
+    grpc_channel_element* elem =
+        grpc_channel_stack_element(chand->channel_stack, 0);
+    elem->filter->start_transport_op(exec_ctx, elem, op);
+  } else if (error != GRPC_ERROR_CANCELLED) {
+    GRPC_LOG_IF_ERROR("close_max_idle_channel", error);
+  }
+  GRPC_CHANNEL_STACK_UNREF(exec_ctx, chand->channel_stack,
+                           "max_age max_idle_timer");
+}
+
+static void close_max_age_channel(grpc_exec_ctx* exec_ctx, void* arg,
+                                  grpc_error* error) {
+  channel_data* chand = arg;
+  gpr_mu_lock(&chand->max_age_timer_mu);
+  chand->max_age_timer_pending = false;
+  gpr_mu_unlock(&chand->max_age_timer_mu);
+  if (error == GRPC_ERROR_NONE) {
+    GRPC_CHANNEL_STACK_REF(chand->channel_stack,
+                           "max_age start_max_age_grace_timer_after_goaway_op");
+    grpc_transport_op* op = grpc_make_transport_op(
+        &chand->start_max_age_grace_timer_after_goaway_op);
+    op->goaway_error =
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("max_age"),
+                           GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_NO_ERROR);
+    grpc_channel_element* elem =
+        grpc_channel_stack_element(chand->channel_stack, 0);
+    elem->filter->start_transport_op(exec_ctx, elem, op);
+  } else if (error != GRPC_ERROR_CANCELLED) {
+    GRPC_LOG_IF_ERROR("close_max_age_channel", error);
+  }
+  GRPC_CHANNEL_STACK_UNREF(exec_ctx, chand->channel_stack,
+                           "max_age max_age_timer");
+}
+
+static void force_close_max_age_channel(grpc_exec_ctx* exec_ctx, void* arg,
+                                        grpc_error* error) {
+  channel_data* chand = arg;
+  gpr_mu_lock(&chand->max_age_timer_mu);
+  chand->max_age_grace_timer_pending = false;
+  gpr_mu_unlock(&chand->max_age_timer_mu);
+  if (error == GRPC_ERROR_NONE) {
+    grpc_transport_op* op = grpc_make_transport_op(NULL);
+    op->disconnect_with_error =
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel reaches max age");
+    grpc_channel_element* elem =
+        grpc_channel_stack_element(chand->channel_stack, 0);
+    elem->filter->start_transport_op(exec_ctx, elem, op);
+  } else if (error != GRPC_ERROR_CANCELLED) {
+    GRPC_LOG_IF_ERROR("force_close_max_age_channel", error);
+  }
+  GRPC_CHANNEL_STACK_UNREF(exec_ctx, chand->channel_stack,
+                           "max_age max_age_grace_timer");
+}
+
+static void channel_connectivity_changed(grpc_exec_ctx* exec_ctx, void* arg,
+                                         grpc_error* error) {
+  channel_data* chand = arg;
+  if (chand->connectivity_state != GRPC_CHANNEL_SHUTDOWN) {
+    grpc_transport_op* op = grpc_make_transport_op(NULL);
+    op->on_connectivity_state_change = &chand->channel_connectivity_changed,
+    op->connectivity_state = &chand->connectivity_state;
+    grpc_channel_next_op(
+        exec_ctx, grpc_channel_stack_element(chand->channel_stack, 0), op);
+  } else {
+    gpr_mu_lock(&chand->max_age_timer_mu);
+    if (chand->max_age_timer_pending) {
+      grpc_timer_cancel(exec_ctx, &chand->max_age_timer);
+      chand->max_age_timer_pending = false;
+    }
+    if (chand->max_age_grace_timer_pending) {
+      grpc_timer_cancel(exec_ctx, &chand->max_age_grace_timer);
+      chand->max_age_grace_timer_pending = false;
+    }
+    gpr_mu_unlock(&chand->max_age_timer_mu);
+    /* If there are no active calls, this increasement will cancel
+       max_idle_timer, and prevent max_idle_timer from being started in the
+       future. */
+    increase_call_count(exec_ctx, chand);
+  }
+}
+
+/* A random jitter of +/-10% will be added to MAX_CONNECTION_AGE to spread out
+   connection storms. Note that the MAX_CONNECTION_AGE option without jitter
+   would not create connection storms by itself, but if there happened to be a
+   connection storm it could cause it to repeat at a fixed period. */
+static int add_random_max_connection_age_jitter(int value) {
+  /* generate a random number between 1 - MAX_CONNECTION_AGE_JITTER and
+     1 + MAX_CONNECTION_AGE_JITTER */
+  double multiplier = rand() * MAX_CONNECTION_AGE_JITTER * 2.0 / RAND_MAX +
+                      1.0 - MAX_CONNECTION_AGE_JITTER;
+  double result = multiplier * value;
+  /* INT_MAX - 0.5 converts the value to float, so that result will not be
+     cast to int implicitly before the comparison. */
+  return result > INT_MAX - 0.5 ? INT_MAX : (int)result;
+}
+
+/* Constructor for call_data. */
+static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
+                                  grpc_call_element* elem,
+                                  const grpc_call_element_args* args) {
+  channel_data* chand = elem->channel_data;
+  increase_call_count(exec_ctx, chand);
+  return GRPC_ERROR_NONE;
+}
+
+/* Destructor for call_data. */
+static void destroy_call_elem(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
+                              const grpc_call_final_info* final_info,
+                              grpc_closure* ignored) {
+  channel_data* chand = elem->channel_data;
+  decrease_call_count(exec_ctx, chand);
+}
+
+/* Constructor for channel_data. */
+static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
+                                     grpc_channel_element* elem,
+                                     grpc_channel_element_args* args) {
+  channel_data* chand = elem->channel_data;
+  gpr_mu_init(&chand->max_age_timer_mu);
+  chand->max_age_timer_pending = false;
+  chand->max_age_grace_timer_pending = false;
+  chand->channel_stack = args->channel_stack;
+  chand->max_connection_age =
+      DEFAULT_MAX_CONNECTION_AGE_MS == INT_MAX
+          ? gpr_inf_future(GPR_TIMESPAN)
+          : gpr_time_from_millis(add_random_max_connection_age_jitter(
+                                     DEFAULT_MAX_CONNECTION_AGE_MS),
+                                 GPR_TIMESPAN);
+  chand->max_connection_age_grace =
+      DEFAULT_MAX_CONNECTION_AGE_GRACE_MS == INT_MAX
+          ? gpr_inf_future(GPR_TIMESPAN)
+          : gpr_time_from_millis(DEFAULT_MAX_CONNECTION_AGE_GRACE_MS,
+                                 GPR_TIMESPAN);
+  chand->max_connection_idle =
+      DEFAULT_MAX_CONNECTION_IDLE_MS == INT_MAX
+          ? gpr_inf_future(GPR_TIMESPAN)
+          : gpr_time_from_millis(DEFAULT_MAX_CONNECTION_IDLE_MS, GPR_TIMESPAN);
+  for (size_t i = 0; i < args->channel_args->num_args; ++i) {
+    if (0 == strcmp(args->channel_args->args[i].key,
+                    GRPC_ARG_MAX_CONNECTION_AGE_MS)) {
+      const int value = grpc_channel_arg_get_integer(
+          &args->channel_args->args[i], MAX_CONNECTION_AGE_INTEGER_OPTIONS);
+      chand->max_connection_age =
+          value == INT_MAX
+              ? gpr_inf_future(GPR_TIMESPAN)
+              : gpr_time_from_millis(
+                    add_random_max_connection_age_jitter(value), GPR_TIMESPAN);
+    } else if (0 == strcmp(args->channel_args->args[i].key,
+                           GRPC_ARG_MAX_CONNECTION_AGE_GRACE_MS)) {
+      const int value = grpc_channel_arg_get_integer(
+          &args->channel_args->args[i],
+          (grpc_integer_options){DEFAULT_MAX_CONNECTION_AGE_GRACE_MS, 0,
+                                 INT_MAX});
+      chand->max_connection_age_grace =
+          value == INT_MAX ? gpr_inf_future(GPR_TIMESPAN)
+                           : gpr_time_from_millis(value, GPR_TIMESPAN);
+    } else if (0 == strcmp(args->channel_args->args[i].key,
+                           GRPC_ARG_MAX_CONNECTION_IDLE_MS)) {
+      const int value = grpc_channel_arg_get_integer(
+          &args->channel_args->args[i], MAX_CONNECTION_IDLE_INTEGER_OPTIONS);
+      chand->max_connection_idle =
+          value == INT_MAX ? gpr_inf_future(GPR_TIMESPAN)
+                           : gpr_time_from_millis(value, GPR_TIMESPAN);
+    }
+  }
+  grpc_closure_init(&chand->close_max_idle_channel, close_max_idle_channel,
+                    chand, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&chand->close_max_age_channel, close_max_age_channel, chand,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&chand->force_close_max_age_channel,
+                    force_close_max_age_channel, chand,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&chand->start_max_idle_timer_after_init,
+                    start_max_idle_timer_after_init, chand,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&chand->start_max_age_timer_after_init,
+                    start_max_age_timer_after_init, chand,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&chand->start_max_age_grace_timer_after_goaway_op,
+                    start_max_age_grace_timer_after_goaway_op, chand,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&chand->channel_connectivity_changed,
+                    channel_connectivity_changed, chand,
+                    grpc_schedule_on_exec_ctx);
+
+  if (gpr_time_cmp(chand->max_connection_age, gpr_inf_future(GPR_TIMESPAN)) !=
+      0) {
+    /* When the channel reaches its max age, we send down an op with
+       goaway_error set.  However, we can't send down any ops until after the
+       channel stack is fully initialized.  If we start the timer here, we have
+       no guarantee that the timer won't pop before channel stack initialization
+       is finished.  To avoid that problem, we create a closure to start the
+       timer, and we schedule that closure to be run after call stack
+       initialization is done. */
+    GRPC_CHANNEL_STACK_REF(chand->channel_stack,
+                           "max_age start_max_age_timer_after_init");
+    grpc_closure_sched(exec_ctx, &chand->start_max_age_timer_after_init,
+                       GRPC_ERROR_NONE);
+  }
+
+  /* Initialize the number of calls as 1, so that the max_idle_timer will not
+     start until start_max_idle_timer_after_init is invoked. */
+  gpr_atm_rel_store(&chand->call_count, 1);
+  if (gpr_time_cmp(chand->max_connection_idle, gpr_inf_future(GPR_TIMESPAN)) !=
+      0) {
+    GRPC_CHANNEL_STACK_REF(chand->channel_stack,
+                           "max_age start_max_idle_timer_after_init");
+    grpc_closure_sched(exec_ctx, &chand->start_max_idle_timer_after_init,
+                       GRPC_ERROR_NONE);
+  }
+  return GRPC_ERROR_NONE;
+}
+
+/* Destructor for channel_data. */
+static void destroy_channel_elem(grpc_exec_ctx* exec_ctx,
+                                 grpc_channel_element* elem) {}
+
+const grpc_channel_filter grpc_max_age_filter = {
+    grpc_call_next_op,
+    grpc_channel_next_op,
+    0, /* sizeof_call_data */
+    init_call_elem,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
+    destroy_call_elem,
+    sizeof(channel_data),
+    init_channel_elem,
+    destroy_channel_elem,
+    grpc_call_next_get_peer,
+    grpc_channel_next_get_info,
+    "max_age"};
+
+static bool maybe_add_max_age_filter(grpc_exec_ctx* exec_ctx,
+                                     grpc_channel_stack_builder* builder,
+                                     void* arg) {
+  const grpc_channel_args* channel_args =
+      grpc_channel_stack_builder_get_channel_arguments(builder);
+  bool enable =
+      grpc_channel_arg_get_integer(
+          grpc_channel_args_find(channel_args, GRPC_ARG_MAX_CONNECTION_AGE_MS),
+          MAX_CONNECTION_AGE_INTEGER_OPTIONS) != INT_MAX &&
+      grpc_channel_arg_get_integer(
+          grpc_channel_args_find(channel_args, GRPC_ARG_MAX_CONNECTION_IDLE_MS),
+          MAX_CONNECTION_IDLE_INTEGER_OPTIONS) != INT_MAX;
+  if (enable) {
+    return grpc_channel_stack_builder_prepend_filter(
+        builder, &grpc_max_age_filter, NULL, NULL);
+  } else {
+    return true;
+  }
+}
+
+void grpc_max_age_filter_init(void) {
+  grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL,
+                                   GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+                                   maybe_add_max_age_filter, NULL);
+}
+
+void grpc_max_age_filter_shutdown(void) {}
diff --git a/src/core/ext/filters/max_age/max_age_filter.h b/src/core/ext/filters/max_age/max_age_filter.h
new file mode 100644
index 0000000000000000000000000000000000000000..ed2015297a7294bf8c26f5588494e2493f1293f0
--- /dev/null
+++ b/src/core/ext/filters/max_age/max_age_filter.h
@@ -0,0 +1,39 @@
+//
+// Copyright 2017, 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_CORE_EXT_FILTERS_MAX_AGE_MAX_AGE_FILTER_H
+#define GRPC_CORE_EXT_FILTERS_MAX_AGE_MAX_AGE_FILTER_H
+
+#include "src/core/lib/channel/channel_stack.h"
+
+extern const grpc_channel_filter grpc_max_age_filter;
+
+#endif /* GRPC_CORE_EXT_FILTERS_MAX_AGE_MAX_AGE_FILTER_H */
diff --git a/src/core/lib/channel/message_size_filter.c b/src/core/ext/filters/message_size/message_size_filter.c
similarity index 62%
rename from src/core/lib/channel/message_size_filter.c
rename to src/core/ext/filters/message_size/message_size_filter.c
index b424c0d2acbb55e7b79dd47d0270ee8267f67015..b615116965ff8f1ce9fcb64e300250c5f356fe9f 100644
--- a/src/core/lib/channel/message_size_filter.c
+++ b/src/core/ext/filters/message_size/message_size_filter.c
@@ -29,7 +29,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 
-#include "src/core/lib/channel/message_size_filter.h"
+#include "src/core/ext/filters/message_size/message_size_filter.h"
 
 #include <limits.h>
 #include <string.h>
@@ -40,7 +40,9 @@
 #include <grpc/support/string_util.h>
 
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/channel/channel_stack_builder.h"
 #include "src/core/lib/support/string.h"
+#include "src/core/lib/surface/channel_init.h"
 #include "src/core/lib/transport/service_config.h"
 
 typedef struct message_size_limits {
@@ -48,19 +50,10 @@ typedef struct message_size_limits {
   int max_recv_size;
 } message_size_limits;
 
-static void* message_size_limits_copy(void* value) {
-  void* new_value = gpr_malloc(sizeof(message_size_limits));
-  memcpy(new_value, value, sizeof(message_size_limits));
-  return new_value;
-}
-
 static void message_size_limits_free(grpc_exec_ctx* exec_ctx, void* value) {
   gpr_free(value);
 }
 
-static const grpc_slice_hash_table_vtable message_size_limits_vtable = {
-    message_size_limits_free, message_size_limits_copy};
-
 static void* message_size_limits_create_from_json(const grpc_json* json) {
   int max_request_message_bytes = -1;
   int max_response_message_bytes = -1;
@@ -89,8 +82,7 @@ static void* message_size_limits_create_from_json(const grpc_json* json) {
 }
 
 typedef struct call_data {
-  int max_send_size;
-  int max_recv_size;
+  message_size_limits limits;
   // Receive closures are chained: we inject this closure as the
   // recv_message_ready up-call on transport_stream_op, and remember to
   // call our next_recv_message_ready member after handling it.
@@ -102,8 +94,7 @@ typedef struct call_data {
 } call_data;
 
 typedef struct channel_data {
-  int max_send_size;
-  int max_recv_size;
+  message_size_limits limits;
   // Maps path names to message_size_limits structs.
   grpc_slice_hash_table* method_limit_table;
 } channel_data;
@@ -114,15 +105,15 @@ static void recv_message_ready(grpc_exec_ctx* exec_ctx, void* user_data,
                                grpc_error* error) {
   grpc_call_element* elem = user_data;
   call_data* calld = elem->call_data;
-  if (*calld->recv_message != NULL && calld->max_recv_size >= 0 &&
-      (*calld->recv_message)->length > (size_t)calld->max_recv_size) {
+  if (*calld->recv_message != NULL && calld->limits.max_recv_size >= 0 &&
+      (*calld->recv_message)->length > (size_t)calld->limits.max_recv_size) {
     char* message_string;
     gpr_asprintf(&message_string,
                  "Received message larger than max (%u vs. %d)",
-                 (*calld->recv_message)->length, calld->max_recv_size);
+                 (*calld->recv_message)->length, calld->limits.max_recv_size);
     grpc_error* new_error = grpc_error_set_int(
-        GRPC_ERROR_CREATE(message_string), GRPC_ERROR_INT_GRPC_STATUS,
-        GRPC_STATUS_INVALID_ARGUMENT);
+        GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string),
+        GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED);
     if (error == GRPC_ERROR_NONE) {
       error = new_error;
     } else {
@@ -130,34 +121,40 @@ static void recv_message_ready(grpc_exec_ctx* exec_ctx, void* user_data,
       GRPC_ERROR_UNREF(new_error);
     }
     gpr_free(message_string);
+  } else {
+    GRPC_ERROR_REF(error);
   }
   // Invoke the next callback.
-  grpc_closure_sched(exec_ctx, calld->next_recv_message_ready, error);
+  grpc_closure_run(exec_ctx, calld->next_recv_message_ready, error);
 }
 
 // Start transport stream op.
-static void start_transport_stream_op(grpc_exec_ctx* exec_ctx,
-                                      grpc_call_element* elem,
-                                      grpc_transport_stream_op* op) {
+static void start_transport_stream_op_batch(
+    grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
+    grpc_transport_stream_op_batch* op) {
   call_data* calld = elem->call_data;
   // Check max send message size.
-  if (op->send_message != NULL && calld->max_send_size >= 0 &&
-      op->send_message->length > (size_t)calld->max_send_size) {
+  if (op->send_message && calld->limits.max_send_size >= 0 &&
+      op->payload->send_message.send_message->length >
+          (size_t)calld->limits.max_send_size) {
     char* message_string;
     gpr_asprintf(&message_string, "Sent message larger than max (%u vs. %d)",
-                 op->send_message->length, calld->max_send_size);
-    grpc_transport_stream_op_finish_with_failure(
-        exec_ctx, op, grpc_error_set_int(GRPC_ERROR_CREATE(message_string),
-                                         GRPC_ERROR_INT_GRPC_STATUS,
-                                         GRPC_STATUS_INVALID_ARGUMENT));
+                 op->payload->send_message.send_message->length,
+                 calld->limits.max_send_size);
+    grpc_transport_stream_op_batch_finish_with_failure(
+        exec_ctx, op,
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string),
+                           GRPC_ERROR_INT_GRPC_STATUS,
+                           GRPC_STATUS_RESOURCE_EXHAUSTED));
     gpr_free(message_string);
     return;
   }
   // Inject callback for receiving a message.
-  if (op->recv_message_ready != NULL) {
-    calld->next_recv_message_ready = op->recv_message_ready;
-    calld->recv_message = op->recv_message;
-    op->recv_message_ready = &calld->recv_message_ready;
+  if (op->recv_message) {
+    calld->next_recv_message_ready =
+        op->payload->recv_message.recv_message_ready;
+    calld->recv_message = op->payload->recv_message.recv_message;
+    op->payload->recv_message.recv_message_ready = &calld->recv_message_ready;
   }
   // Chain to the next filter.
   grpc_call_next_op(exec_ctx, elem, op);
@@ -176,21 +173,20 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
   // Note: Per-method config is only available on the client, so we
   // apply the max request size to the send limit and the max response
   // size to the receive limit.
-  calld->max_send_size = chand->max_send_size;
-  calld->max_recv_size = chand->max_recv_size;
+  calld->limits = chand->limits;
   if (chand->method_limit_table != NULL) {
     message_size_limits* limits = grpc_method_config_table_get(
         exec_ctx, chand->method_limit_table, args->path);
     if (limits != NULL) {
       if (limits->max_send_size >= 0 &&
-          (limits->max_send_size < calld->max_send_size ||
-           calld->max_send_size < 0)) {
-        calld->max_send_size = limits->max_send_size;
+          (limits->max_send_size < calld->limits.max_send_size ||
+           calld->limits.max_send_size < 0)) {
+        calld->limits.max_send_size = limits->max_send_size;
       }
       if (limits->max_recv_size >= 0 &&
-          (limits->max_recv_size < calld->max_recv_size ||
-           calld->max_recv_size < 0)) {
-        calld->max_recv_size = limits->max_recv_size;
+          (limits->max_recv_size < calld->limits.max_recv_size ||
+           calld->limits.max_recv_size < 0)) {
+        calld->limits.max_recv_size = limits->max_recv_size;
       }
     }
   }
@@ -200,7 +196,39 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
 // Destructor for call_data.
 static void destroy_call_elem(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
                               const grpc_call_final_info* final_info,
-                              void* ignored) {}
+                              grpc_closure* ignored) {}
+
+static int default_size(const grpc_channel_args* args,
+                        int without_minimal_stack) {
+  if (grpc_channel_args_want_minimal_stack(args)) {
+    return -1;
+  }
+  return without_minimal_stack;
+}
+
+message_size_limits get_message_size_limits(
+    const grpc_channel_args* channel_args) {
+  message_size_limits lim;
+  lim.max_send_size =
+      default_size(channel_args, GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH);
+  lim.max_recv_size =
+      default_size(channel_args, GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH);
+  for (size_t i = 0; i < channel_args->num_args; ++i) {
+    if (strcmp(channel_args->args[i].key, GRPC_ARG_MAX_SEND_MESSAGE_LENGTH) ==
+        0) {
+      const grpc_integer_options options = {lim.max_send_size, -1, INT_MAX};
+      lim.max_send_size =
+          grpc_channel_arg_get_integer(&channel_args->args[i], options);
+    }
+    if (strcmp(channel_args->args[i].key,
+               GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH) == 0) {
+      const grpc_integer_options options = {lim.max_recv_size, -1, INT_MAX};
+      lim.max_recv_size =
+          grpc_channel_arg_get_integer(&channel_args->args[i], options);
+    }
+  }
+  return lim;
+}
 
 // Constructor for channel_data.
 static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
@@ -208,24 +236,7 @@ static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
                                      grpc_channel_element_args* args) {
   GPR_ASSERT(!args->is_last);
   channel_data* chand = elem->channel_data;
-  chand->max_send_size = GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH;
-  chand->max_recv_size = GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH;
-  for (size_t i = 0; i < args->channel_args->num_args; ++i) {
-    if (strcmp(args->channel_args->args[i].key,
-               GRPC_ARG_MAX_SEND_MESSAGE_LENGTH) == 0) {
-      const grpc_integer_options options = {
-          GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH, 0, INT_MAX};
-      chand->max_send_size =
-          grpc_channel_arg_get_integer(&args->channel_args->args[i], options);
-    }
-    if (strcmp(args->channel_args->args[i].key,
-               GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH) == 0) {
-      const grpc_integer_options options = {
-          GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH, 0, INT_MAX};
-      chand->max_recv_size =
-          grpc_channel_arg_get_integer(&args->channel_args->args[i], options);
-    }
-  }
+  chand->limits = get_message_size_limits(args->channel_args);
   // Get method config table from channel args.
   const grpc_arg* channel_arg =
       grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG);
@@ -237,7 +248,7 @@ static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
       chand->method_limit_table =
           grpc_service_config_create_method_config_table(
               exec_ctx, service_config, message_size_limits_create_from_json,
-              &message_size_limits_vtable);
+              message_size_limits_free);
       grpc_service_config_destroy(service_config);
     }
   }
@@ -252,7 +263,7 @@ static void destroy_channel_elem(grpc_exec_ctx* exec_ctx,
 }
 
 const grpc_channel_filter grpc_message_size_filter = {
-    start_transport_stream_op,
+    start_transport_stream_op_batch,
     grpc_channel_next_op,
     sizeof(call_data),
     init_call_elem,
@@ -264,3 +275,40 @@ const grpc_channel_filter grpc_message_size_filter = {
     grpc_call_next_get_peer,
     grpc_channel_next_get_info,
     "message_size"};
+
+static bool maybe_add_message_size_filter(grpc_exec_ctx* exec_ctx,
+                                          grpc_channel_stack_builder* builder,
+                                          void* arg) {
+  const grpc_channel_args* channel_args =
+      grpc_channel_stack_builder_get_channel_arguments(builder);
+  bool enable = false;
+  message_size_limits lim = get_message_size_limits(channel_args);
+  if (lim.max_send_size != -1 || lim.max_recv_size != -1) {
+    enable = true;
+  }
+  const grpc_arg* a =
+      grpc_channel_args_find(channel_args, GRPC_ARG_SERVICE_CONFIG);
+  if (a != NULL) {
+    enable = true;
+  }
+  if (enable) {
+    return grpc_channel_stack_builder_prepend_filter(
+        builder, &grpc_message_size_filter, NULL, NULL);
+  } else {
+    return true;
+  }
+}
+
+void grpc_message_size_filter_init(void) {
+  grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL,
+                                   GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+                                   maybe_add_message_size_filter, NULL);
+  grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL,
+                                   GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+                                   maybe_add_message_size_filter, NULL);
+  grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL,
+                                   GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+                                   maybe_add_message_size_filter, NULL);
+}
+
+void grpc_message_size_filter_shutdown(void) {}
diff --git a/src/core/lib/channel/message_size_filter.h b/src/core/ext/filters/message_size/message_size_filter.h
similarity index 89%
rename from src/core/lib/channel/message_size_filter.h
rename to src/core/ext/filters/message_size/message_size_filter.h
index a88ff7f81a1f9bc8119fa28af34d3dfdeec5a9dc..83980e738cb1448c6e1294ef6472b751b663dfac 100644
--- a/src/core/lib/channel/message_size_filter.h
+++ b/src/core/ext/filters/message_size/message_size_filter.h
@@ -29,11 +29,11 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 
-#ifndef GRPC_CORE_LIB_CHANNEL_MESSAGE_SIZE_FILTER_H
-#define GRPC_CORE_LIB_CHANNEL_MESSAGE_SIZE_FILTER_H
+#ifndef GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H
+#define GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H
 
 #include "src/core/lib/channel/channel_stack.h"
 
 extern const grpc_channel_filter grpc_message_size_filter;
 
-#endif /* GRPC_CORE_LIB_CHANNEL_MESSAGE_SIZE_FILTER_H */
+#endif /* GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H */
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.c b/src/core/ext/transport/chttp2/client/chttp2_connector.c
index fc5e17d8fc9b47595322237c5ff623d20121e702..e645eda7e3e35c7c50a6b37b15ea6acffc0bb465 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.c
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.c
@@ -41,9 +41,9 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/ext/client_channel/connector.h"
-#include "src/core/ext/client_channel/http_connect_handshaker.h"
-#include "src/core/ext/client_channel/subchannel.h"
+#include "src/core/ext/filters/client_channel/connector.h"
+#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
+#include "src/core/ext/filters/client_channel/subchannel.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/handshaker.h"
@@ -63,8 +63,6 @@ typedef struct {
   grpc_closure *notify;
   grpc_connect_in_args args;
   grpc_connect_out_args *result;
-  grpc_closure initial_string_sent;
-  grpc_slice_buffer initial_string_buffer;
 
   grpc_endpoint *endpoint;  // Non-NULL until handshaking starts.
 
@@ -82,7 +80,6 @@ static void chttp2_connector_unref(grpc_exec_ctx *exec_ctx,
                                    grpc_connector *con) {
   chttp2_connector *c = (chttp2_connector *)con;
   if (gpr_unref(&c->refs)) {
-    /* c->initial_string_buffer does not need to be destroyed */
     gpr_mu_destroy(&c->mu);
     // If handshaking is not yet in progress, destroy the endpoint.
     // Otherwise, the handshaker will do this for us.
@@ -116,7 +113,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
   gpr_mu_lock(&c->mu);
   if (error != GRPC_ERROR_NONE || c->shutdown) {
     if (error == GRPC_ERROR_NONE) {
-      error = GRPC_ERROR_CREATE("connector shutdown");
+      error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("connector shutdown");
       // We were shut down after handshaking completed successfully, so
       // destroy the endpoint here.
       // TODO(ctiller): It is currently necessary to shutdown endpoints
@@ -160,28 +157,6 @@ static void start_handshake_locked(grpc_exec_ctx *exec_ctx,
   c->endpoint = NULL;  // Endpoint handed off to handshake manager.
 }
 
-static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg,
-                                           grpc_error *error) {
-  chttp2_connector *c = arg;
-  gpr_mu_lock(&c->mu);
-  if (error != GRPC_ERROR_NONE || c->shutdown) {
-    if (error == GRPC_ERROR_NONE) {
-      error = GRPC_ERROR_CREATE("connector shutdown");
-    } else {
-      error = GRPC_ERROR_REF(error);
-    }
-    memset(c->result, 0, sizeof(*c->result));
-    grpc_closure *notify = c->notify;
-    c->notify = NULL;
-    grpc_closure_sched(exec_ctx, notify, error);
-    gpr_mu_unlock(&c->mu);
-    chttp2_connector_unref(exec_ctx, arg);
-  } else {
-    start_handshake_locked(exec_ctx, c);
-    gpr_mu_unlock(&c->mu);
-  }
-}
-
 static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
   chttp2_connector *c = arg;
   gpr_mu_lock(&c->mu);
@@ -189,7 +164,7 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
   c->connecting = false;
   if (error != GRPC_ERROR_NONE || c->shutdown) {
     if (error == GRPC_ERROR_NONE) {
-      error = GRPC_ERROR_CREATE("connector shutdown");
+      error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("connector shutdown");
     } else {
       error = GRPC_ERROR_REF(error);
     }
@@ -204,17 +179,7 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
     chttp2_connector_unref(exec_ctx, arg);
   } else {
     GPR_ASSERT(c->endpoint != NULL);
-    if (!GRPC_SLICE_IS_EMPTY(c->args.initial_connect_string)) {
-      grpc_closure_init(&c->initial_string_sent, on_initial_connect_string_sent,
-                        c, grpc_schedule_on_exec_ctx);
-      grpc_slice_buffer_init(&c->initial_string_buffer);
-      grpc_slice_buffer_add(&c->initial_string_buffer,
-                            c->args.initial_connect_string);
-      grpc_endpoint_write(exec_ctx, c->endpoint, &c->initial_string_buffer,
-                          &c->initial_string_sent);
-    } else {
-      start_handshake_locked(exec_ctx, c);
-    }
+    start_handshake_locked(exec_ctx, c);
     gpr_mu_unlock(&c->mu);
   }
 }
@@ -226,7 +191,7 @@ static void chttp2_connector_connect(grpc_exec_ctx *exec_ctx,
                                      grpc_closure *notify) {
   chttp2_connector *c = (chttp2_connector *)con;
   grpc_resolved_address addr;
-  grpc_get_subchannel_address_arg(args->channel_args, &addr);
+  grpc_get_subchannel_address_arg(exec_ctx, args->channel_args, &addr);
   gpr_mu_lock(&c->mu);
   GPR_ASSERT(c->notify == NULL);
   c->notify = notify;
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.h b/src/core/ext/transport/chttp2/client/chttp2_connector.h
index f5d10254320e4f2a1d7fd70f79efa8f2aabfddc8..d55f6ed669a65c2452d34bdba7c3216556212ebd 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.h
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.h
@@ -34,7 +34,7 @@
 #ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_CLIENT_CHTTP2_CONNECTOR_H
 #define GRPC_CORE_EXT_TRANSPORT_CHTTP2_CLIENT_CHTTP2_CONNECTOR_H
 
-#include "src/core/ext/client_channel/connector.h"
+#include "src/core/ext/filters/client_channel/connector.h"
 
 grpc_connector* grpc_chttp2_connector_create();
 
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
index 286232f277f335f482da5746d2fc197b3db23ba5..9c8505ddfa97e3b9de8f1515847d412cf9d42cf9 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
@@ -38,8 +38,8 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/ext/transport/chttp2/client/chttp2_connector.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/surface/api_trace.h"
@@ -72,7 +72,8 @@ static grpc_channel *client_channel_factory_create_channel(
   grpc_arg arg;
   arg.type = GRPC_ARG_STRING;
   arg.key = GRPC_ARG_SERVER_URI;
-  arg.value.string = grpc_resolver_factory_add_default_prefix_if_needed(target);
+  arg.value.string =
+      grpc_resolver_factory_add_default_prefix_if_needed(exec_ctx, target);
   const char *to_remove[] = {GRPC_ARG_SERVER_URI};
   grpc_channel_args *new_args =
       grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1);
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
index 825db68c65037a769097fbaa53e32ea2f6d8c051..119adfade16c6e6286b80c8dc6892ddc91a55fd7 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
@@ -38,9 +38,9 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
-#include "src/core/ext/client_channel/uri_parser.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/uri_parser.h"
 #include "src/core/ext/transport/chttp2/client/chttp2_connector.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -83,7 +83,7 @@ static grpc_subchannel_args *get_secure_naming_subchannel_args(
   const char *server_uri_str = server_uri_arg->value.string;
   GPR_ASSERT(server_uri_str != NULL);
   grpc_uri *server_uri =
-      grpc_uri_parse(server_uri_str, true /* supress errors */);
+      grpc_uri_parse(exec_ctx, server_uri_str, true /* supress errors */);
   GPR_ASSERT(server_uri != NULL);
   const char *server_uri_path;
   server_uri_path =
@@ -96,7 +96,7 @@ static grpc_subchannel_args *get_secure_naming_subchannel_args(
     const char *target_uri_str =
         grpc_get_subchannel_address_uri_arg(args->args);
     grpc_uri *target_uri =
-        grpc_uri_parse(target_uri_str, false /* suppress errors */);
+        grpc_uri_parse(exec_ctx, target_uri_str, false /* suppress errors */);
     GPR_ASSERT(target_uri != NULL);
     if (target_uri->path[0] != '\0') {  // "path" may be empty
       const grpc_slice key = grpc_slice_from_static_string(
@@ -181,7 +181,8 @@ static grpc_channel *client_channel_factory_create_channel(
   grpc_arg arg;
   arg.type = GRPC_ARG_STRING;
   arg.key = GRPC_ARG_SERVER_URI;
-  arg.value.string = grpc_resolver_factory_add_default_prefix_if_needed(target);
+  arg.value.string =
+      grpc_resolver_factory_add_default_prefix_if_needed(exec_ctx, target);
   const char *to_remove[] = {GRPC_ARG_SERVER_URI};
   grpc_channel_args *new_args =
       grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1);
diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.c b/src/core/ext/transport/chttp2/server/chttp2_server.c
index 837b9fd03d869aa49858b4ca6aefef38c854bba1..b9c62c376a1fc079d6e8b12b9a3c6606fb5b723e 100644
--- a/src/core/ext/transport/chttp2/server/chttp2_server.c
+++ b/src/core/ext/transport/chttp2/server/chttp2_server.c
@@ -43,11 +43,11 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/handshaker.h"
 #include "src/core/lib/channel/handshaker_registry.h"
-#include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/iomgr/endpoint.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/tcp_server.h"
@@ -80,7 +80,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
   gpr_mu_lock(&connection_state->server_state->mu);
   if (error != GRPC_ERROR_NONE || connection_state->server_state->shutdown) {
     const char *error_str = grpc_error_string(error);
-    gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str);
+    gpr_log(GPR_DEBUG, "Handshaking failed: %s", error_str);
 
     if (error == GRPC_ERROR_NONE && args->endpoint != NULL) {
       // We were shut down after handshaking completed successfully, so
@@ -256,7 +256,7 @@ grpc_error *grpc_chttp2_server_add_port(grpc_exec_ctx *exec_ctx,
     char *msg;
     gpr_asprintf(&msg, "No address added out of total %" PRIuPTR " resolved",
                  naddrs);
-    err = GRPC_ERROR_CREATE_REFERENCING(msg, errors, naddrs);
+    err = GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(msg, errors, naddrs);
     gpr_free(msg);
     goto error;
   } else if (count != naddrs) {
@@ -264,7 +264,7 @@ grpc_error *grpc_chttp2_server_add_port(grpc_exec_ctx *exec_ctx,
     gpr_asprintf(&msg, "Only %" PRIuPTR
                        " addresses added out of total %" PRIuPTR " resolved",
                  count, naddrs);
-    err = GRPC_ERROR_CREATE_REFERENCING(msg, errors, naddrs);
+    err = GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(msg, errors, naddrs);
     gpr_free(msg);
 
     const char *warning_message = grpc_error_string(err);
diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
index f46e8499326d5a0ecea74368fa0fdc605581edf5..6ab176e8ad74eba529f1783986577c0e43523743 100644
--- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
+++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
@@ -57,12 +57,9 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server *server,
   char *name;
   gpr_asprintf(&name, "fd:%d", fd);
 
-  grpc_resource_quota *resource_quota = grpc_resource_quota_from_channel_args(
-      grpc_server_get_channel_args(server));
   grpc_endpoint *server_endpoint =
-      grpc_tcp_create(grpc_fd_create(fd, name), resource_quota,
-                      GRPC_TCP_DEFAULT_READ_SLICE_SIZE, name);
-  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
+      grpc_tcp_create(&exec_ctx, grpc_fd_create(fd, name),
+                      grpc_server_get_channel_args(server), name);
 
   gpr_free(name);
 
diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
index cb2b3f5502c0b952253fbed774e51077fc8ece3c..88c813f3beeff77962ff25687cde6c3e6c039cb9 100644
--- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
+++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
@@ -61,7 +61,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
       3, (server, addr, creds));
   // Create security context.
   if (creds == NULL) {
-    err = GRPC_ERROR_CREATE(
+    err = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
         "No credentials specified for secure server port (creds==NULL)");
     goto done;
   }
@@ -72,7 +72,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
     gpr_asprintf(&msg,
                  "Unable to create secure server with credentials of type %s.",
                  creds->type);
-    err = grpc_error_set_int(GRPC_ERROR_CREATE(msg),
+    err = grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg),
                              GRPC_ERROR_INT_SECURITY_STATUS, status);
     gpr_free(msg);
     goto done;
diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.c b/src/core/ext/transport/chttp2/transport/bin_decoder.c
index 8c87de112eb12d808aa01ff7e973346abc55e23d..21bed18c9a771a7f4c181a2fd756da22fe39d4f2 100644
--- a/src/core/ext/transport/chttp2/transport/bin_decoder.c
+++ b/src/core/ext/transport/chttp2/transport/bin_decoder.c
@@ -169,7 +169,7 @@ grpc_slice grpc_chttp2_base64_decode(grpc_exec_ctx *exec_ctx,
       }
     }
   }
-  output = grpc_slice_malloc(output_length);
+  output = GRPC_SLICE_MALLOC(output_length);
 
   ctx.input_cur = GRPC_SLICE_START_PTR(input);
   ctx.input_end = GRPC_SLICE_END_PTR(input);
@@ -193,7 +193,7 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx *exec_ctx,
                                                  grpc_slice input,
                                                  size_t output_length) {
   size_t input_length = GRPC_SLICE_LENGTH(input);
-  grpc_slice output = grpc_slice_malloc(output_length);
+  grpc_slice output = GRPC_SLICE_MALLOC(output_length);
   struct grpc_base64_decode_context ctx;
 
   // The length of a base64 string cannot be 4 * n + 1
diff --git a/src/core/ext/transport/chttp2/transport/bin_encoder.c b/src/core/ext/transport/chttp2/transport/bin_encoder.c
index e301c073f3722dfb41e6aac8d3c0f90416079b5e..3b8ab1f17aafd0c90b36193d94cf3e4b39811f6b 100644
--- a/src/core/ext/transport/chttp2/transport/bin_encoder.c
+++ b/src/core/ext/transport/chttp2/transport/bin_encoder.c
@@ -66,7 +66,7 @@ grpc_slice grpc_chttp2_base64_encode(grpc_slice input) {
   size_t input_triplets = input_length / 3;
   size_t tail_case = input_length % 3;
   size_t output_length = input_triplets * 4 + tail_xtra[tail_case];
-  grpc_slice output = grpc_slice_malloc(output_length);
+  grpc_slice output = GRPC_SLICE_MALLOC(output_length);
   uint8_t *in = GRPC_SLICE_START_PTR(input);
   char *out = (char *)GRPC_SLICE_START_PTR(output);
   size_t i;
@@ -119,7 +119,7 @@ grpc_slice grpc_chttp2_huffman_compress(grpc_slice input) {
     nbits += grpc_chttp2_huffsyms[*in].length;
   }
 
-  output = grpc_slice_malloc(nbits / 8 + (nbits % 8 != 0));
+  output = GRPC_SLICE_MALLOC(nbits / 8 + (nbits % 8 != 0));
   out = GRPC_SLICE_START_PTR(output);
   for (in = GRPC_SLICE_START_PTR(input); in != GRPC_SLICE_END_PTR(input);
        ++in) {
@@ -184,7 +184,7 @@ grpc_slice grpc_chttp2_base64_encode_and_huffman_compress(grpc_slice input) {
   size_t output_syms = input_triplets * 4 + tail_xtra[tail_case];
   size_t max_output_bits = 11 * output_syms;
   size_t max_output_length = max_output_bits / 8 + (max_output_bits % 8 != 0);
-  grpc_slice output = grpc_slice_malloc(max_output_length);
+  grpc_slice output = GRPC_SLICE_MALLOC(max_output_length);
   uint8_t *in = GRPC_SLICE_START_PTR(input);
   uint8_t *start_out = GRPC_SLICE_START_PTR(output);
   huff_out out;
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index da4c7dc7b231e9544fa09b52bf0f944aedceface..d6b79bd49233183e8d328aad4f99710e43c5f902 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -44,6 +44,7 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/ext/transport/chttp2/transport/frame_data.h"
 #include "src/core/ext/transport/chttp2/transport/internal.h"
 #include "src/core/ext/transport/chttp2/transport/varint.h"
 #include "src/core/lib/channel/channel_args.h"
@@ -69,9 +70,23 @@
 #define MAX_WRITE_BUFFER_SIZE (64 * 1024 * 1024)
 #define DEFAULT_MAX_HEADER_LIST_SIZE (16 * 1024)
 
-#define DEFAULT_KEEPALIVE_TIME_SECOND INT_MAX
-#define DEFAULT_KEEPALIVE_TIMEOUT_SECOND 20
+#define DEFAULT_CLIENT_KEEPALIVE_TIME_MS INT_MAX
+#define DEFAULT_CLIENT_KEEPALIVE_TIMEOUT_MS 20000 /* 20 seconds */
+#define DEFAULT_SERVER_KEEPALIVE_TIME_MS 7200000  /* 2 hours */
+#define DEFAULT_SERVER_KEEPALIVE_TIMEOUT_MS 20000 /* 20 seconds */
 #define DEFAULT_KEEPALIVE_PERMIT_WITHOUT_CALLS false
+#define KEEPALIVE_TIME_BACKOFF_MULTIPLIER 2
+
+static int g_default_client_keepalive_time_ms =
+    DEFAULT_CLIENT_KEEPALIVE_TIME_MS;
+static int g_default_client_keepalive_timeout_ms =
+    DEFAULT_CLIENT_KEEPALIVE_TIMEOUT_MS;
+static int g_default_server_keepalive_time_ms =
+    DEFAULT_SERVER_KEEPALIVE_TIME_MS;
+static int g_default_server_keepalive_timeout_ms =
+    DEFAULT_SERVER_KEEPALIVE_TIMEOUT_MS;
+static bool g_default_keepalive_permit_without_calls =
+    DEFAULT_KEEPALIVE_PERMIT_WITHOUT_CALLS;
 
 #define MAX_CLIENT_STREAM_ID 0x7fffffffu
 int grpc_http_trace = 0;
@@ -115,6 +130,11 @@ static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx,
 static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx,
                                                 void *byte_stream,
                                                 grpc_error *error_ignored);
+static void incoming_byte_stream_publish_error(
+    grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
+    grpc_error *error);
+static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx,
+                                       grpc_chttp2_incoming_byte_stream *bs);
 
 static void benign_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *t,
                                     grpc_error *error);
@@ -142,9 +162,13 @@ static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
                              grpc_chttp2_ping_type ping_type,
                              grpc_closure *on_initiate,
                              grpc_closure *on_complete);
+static void retry_initiate_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
+                                       grpc_error *error);
 
 #define DEFAULT_MIN_TIME_BETWEEN_PINGS_MS 0
 #define DEFAULT_MAX_PINGS_BETWEEN_DATA 3
+#define DEFAULT_MAX_PING_STRIKES 2
+#define DEFAULT_MIN_PING_INTERVAL_WITHOUT_DATA_MS 300000 /* 5 minutes */
 
 /** keepalive-relevant functions */
 static void init_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
@@ -156,6 +180,9 @@ static void finish_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
 static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg,
                                             grpc_error *error);
 
+static void reset_byte_stream(grpc_exec_ctx *exec_ctx, void *arg,
+                              grpc_error *error);
+
 /*******************************************************************************
  * CONSTRUCTION/DESTRUCTION/REFCOUNTING
  */
@@ -187,7 +214,8 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
 
   GRPC_COMBINER_UNREF(exec_ctx, t->combiner, "chttp2_transport");
 
-  cancel_pings(exec_ctx, t, GRPC_ERROR_CREATE("Transport destroyed"));
+  cancel_pings(exec_ctx, t,
+               GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed"));
 
   while (t->write_cb_pool) {
     grpc_chttp2_write_cb *next = t->write_cb_pool->next;
@@ -266,6 +294,8 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
   grpc_closure_init(&t->destructive_reclaimer_locked,
                     destructive_reclaimer_locked, t,
                     grpc_combiner_scheduler(t->combiner, false));
+  grpc_closure_init(&t->retry_initiate_ping_locked, retry_initiate_ping_locked,
+                    t, grpc_combiner_scheduler(t->combiner, false));
   grpc_closure_init(&t->start_bdp_ping_locked, start_bdp_ping_locked, t,
                     grpc_combiner_scheduler(t->combiner, false));
   grpc_closure_init(&t->finish_bdp_ping_locked, finish_bdp_ping_locked, t,
@@ -335,24 +365,43 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
                DEFAULT_WINDOW);
   push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
                DEFAULT_MAX_HEADER_LIST_SIZE);
+  push_setting(exec_ctx, t,
+               GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA, 1);
 
   t->ping_policy = (grpc_chttp2_repeated_ping_policy){
       .max_pings_without_data = DEFAULT_MAX_PINGS_BETWEEN_DATA,
       .min_time_between_pings =
           gpr_time_from_millis(DEFAULT_MIN_TIME_BETWEEN_PINGS_MS, GPR_TIMESPAN),
+      .max_ping_strikes = DEFAULT_MAX_PING_STRIKES,
+      .min_ping_interval_without_data = gpr_time_from_millis(
+          DEFAULT_MIN_PING_INTERVAL_WITHOUT_DATA_MS, GPR_TIMESPAN),
   };
 
-  /* client-side keepalive setting */
-  t->keepalive_time =
-      DEFAULT_KEEPALIVE_TIME_SECOND == INT_MAX
-          ? gpr_inf_future(GPR_TIMESPAN)
-          : gpr_time_from_seconds(DEFAULT_KEEPALIVE_TIME_SECOND, GPR_TIMESPAN);
-  t->keepalive_timeout =
-      DEFAULT_KEEPALIVE_TIMEOUT_SECOND == INT_MAX
-          ? gpr_inf_future(GPR_TIMESPAN)
-          : gpr_time_from_seconds(DEFAULT_KEEPALIVE_TIMEOUT_SECOND,
-                                  GPR_TIMESPAN);
-  t->keepalive_permit_without_calls = DEFAULT_KEEPALIVE_PERMIT_WITHOUT_CALLS;
+  /* Keepalive setting */
+  if (t->is_client) {
+    t->keepalive_time =
+        g_default_client_keepalive_time_ms == INT_MAX
+            ? gpr_inf_future(GPR_TIMESPAN)
+            : gpr_time_from_millis(g_default_client_keepalive_time_ms,
+                                   GPR_TIMESPAN);
+    t->keepalive_timeout =
+        g_default_client_keepalive_timeout_ms == INT_MAX
+            ? gpr_inf_future(GPR_TIMESPAN)
+            : gpr_time_from_millis(g_default_client_keepalive_timeout_ms,
+                                   GPR_TIMESPAN);
+  } else {
+    t->keepalive_time =
+        g_default_server_keepalive_time_ms == INT_MAX
+            ? gpr_inf_future(GPR_TIMESPAN)
+            : gpr_time_from_millis(g_default_server_keepalive_time_ms,
+                                   GPR_TIMESPAN);
+    t->keepalive_timeout =
+        g_default_server_keepalive_timeout_ms == INT_MAX
+            ? gpr_inf_future(GPR_TIMESPAN)
+            : gpr_time_from_millis(g_default_server_keepalive_timeout_ms,
+                                   GPR_TIMESPAN);
+  }
+  t->keepalive_permit_without_calls = g_default_keepalive_permit_without_calls;
 
   if (channel_args) {
     for (i = 0; i < channel_args->num_args; i++) {
@@ -384,6 +433,11 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
         t->ping_policy.max_pings_without_data = grpc_channel_arg_get_integer(
             &channel_args->args[i],
             (grpc_integer_options){DEFAULT_MAX_PINGS_BETWEEN_DATA, 0, INT_MAX});
+      } else if (0 == strcmp(channel_args->args[i].key,
+                             GRPC_ARG_HTTP2_MAX_PING_STRIKES)) {
+        t->ping_policy.max_ping_strikes = grpc_channel_arg_get_integer(
+            &channel_args->args[i],
+            (grpc_integer_options){DEFAULT_MAX_PING_STRIKES, 0, INT_MAX});
       } else if (0 == strcmp(channel_args->args[i].key,
                              GRPC_ARG_HTTP2_MIN_TIME_BETWEEN_PINGS_MS)) {
         t->ping_policy.min_time_between_pings = gpr_time_from_millis(
@@ -392,6 +446,15 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
                 (grpc_integer_options){DEFAULT_MIN_TIME_BETWEEN_PINGS_MS, 0,
                                        INT_MAX}),
             GPR_TIMESPAN);
+      } else if (0 ==
+                 strcmp(channel_args->args[i].key,
+                        GRPC_ARG_HTTP2_MIN_PING_INTERVAL_WITHOUT_DATA_MS)) {
+        t->ping_policy.min_ping_interval_without_data = gpr_time_from_millis(
+            grpc_channel_arg_get_integer(
+                &channel_args->args[i],
+                (grpc_integer_options){
+                    DEFAULT_MIN_PING_INTERVAL_WITHOUT_DATA_MS, 0, INT_MAX}),
+            GPR_TIMESPAN);
       } else if (0 == strcmp(channel_args->args[i].key,
                              GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE)) {
         t->write_buffer_size = (uint32_t)grpc_channel_arg_get_integer(
@@ -402,24 +465,29 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
         t->enable_bdp_probe = grpc_channel_arg_get_integer(
             &channel_args->args[i], (grpc_integer_options){1, 0, 1});
       } else if (0 == strcmp(channel_args->args[i].key,
-                             GRPC_ARG_HTTP2_KEEPALIVE_TIME)) {
+                             GRPC_ARG_KEEPALIVE_TIME_MS)) {
         const int value = grpc_channel_arg_get_integer(
             &channel_args->args[i],
-            (grpc_integer_options){DEFAULT_KEEPALIVE_TIME_SECOND, 1, INT_MAX});
+            (grpc_integer_options){t->is_client
+                                       ? g_default_client_keepalive_time_ms
+                                       : g_default_server_keepalive_time_ms,
+                                   1, INT_MAX});
         t->keepalive_time = value == INT_MAX
                                 ? gpr_inf_future(GPR_TIMESPAN)
-                                : gpr_time_from_seconds(value, GPR_TIMESPAN);
+                                : gpr_time_from_millis(value, GPR_TIMESPAN);
       } else if (0 == strcmp(channel_args->args[i].key,
-                             GRPC_ARG_HTTP2_KEEPALIVE_TIMEOUT)) {
+                             GRPC_ARG_KEEPALIVE_TIMEOUT_MS)) {
         const int value = grpc_channel_arg_get_integer(
             &channel_args->args[i],
-            (grpc_integer_options){DEFAULT_KEEPALIVE_TIMEOUT_SECOND, 0,
-                                   INT_MAX});
+            (grpc_integer_options){t->is_client
+                                       ? g_default_client_keepalive_timeout_ms
+                                       : g_default_server_keepalive_timeout_ms,
+                                   0, INT_MAX});
         t->keepalive_timeout = value == INT_MAX
                                    ? gpr_inf_future(GPR_TIMESPAN)
-                                   : gpr_time_from_seconds(value, GPR_TIMESPAN);
+                                   : gpr_time_from_millis(value, GPR_TIMESPAN);
       } else if (0 == strcmp(channel_args->args[i].key,
-                             GRPC_ARG_HTTP2_KEEPALIVE_PERMIT_WITHOUT_CALLS)) {
+                             GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS)) {
         t->keepalive_permit_without_calls =
             (uint32_t)grpc_channel_arg_get_integer(
                 &channel_args->args[i], (grpc_integer_options){0, 0, 1});
@@ -429,26 +497,31 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
           grpc_chttp2_setting_id setting_id;
           grpc_integer_options integer_options;
           bool availability[2] /* server, client */;
-        } settings_map[] = {{GRPC_ARG_MAX_CONCURRENT_STREAMS,
-                             GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
-                             {-1, 0, INT32_MAX},
-                             {true, false}},
-                            {GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER,
-                             GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE,
-                             {-1, 0, INT32_MAX},
-                             {true, true}},
-                            {GRPC_ARG_MAX_METADATA_SIZE,
-                             GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
-                             {-1, 0, INT32_MAX},
-                             {true, true}},
-                            {GRPC_ARG_HTTP2_MAX_FRAME_SIZE,
-                             GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE,
-                             {-1, 16384, 16777215},
-                             {true, true}},
-                            {GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES,
-                             GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
-                             {-1, 5, INT32_MAX},
-                             {true, true}}};
+        } settings_map[] = {
+            {GRPC_ARG_MAX_CONCURRENT_STREAMS,
+             GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
+             {-1, 0, INT32_MAX},
+             {true, false}},
+            {GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER,
+             GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE,
+             {-1, 0, INT32_MAX},
+             {true, true}},
+            {GRPC_ARG_MAX_METADATA_SIZE,
+             GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
+             {-1, 0, INT32_MAX},
+             {true, true}},
+            {GRPC_ARG_HTTP2_MAX_FRAME_SIZE,
+             GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE,
+             {-1, 16384, 16777215},
+             {true, true}},
+            {GRPC_ARG_HTTP2_ENABLE_TRUE_BINARY,
+             GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA,
+             {1, 0, 1},
+             {true, true}},
+            {GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES,
+             GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
+             {-1, 5, INT32_MAX},
+             {true, true}}};
         for (j = 0; j < (int)GPR_ARRAY_SIZE(settings_map); j++) {
           if (0 == strcmp(channel_args->args[i].key,
                           settings_map[j].channel_arg_name)) {
@@ -473,15 +546,23 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
 
   t->ping_state.pings_before_data_required =
       t->ping_policy.max_pings_without_data;
+  t->ping_state.is_delayed_ping_timer_set = false;
 
-  /** Start client-side keepalive pings */
-  if (t->is_client) {
+  t->ping_recv_state.last_ping_recv_time = gpr_inf_past(GPR_CLOCK_MONOTONIC);
+  t->ping_recv_state.ping_strikes = 0;
+
+  /* Start keepalive pings */
+  if (gpr_time_cmp(t->keepalive_time, gpr_inf_future(GPR_TIMESPAN)) != 0) {
     t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_WAITING;
     GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping");
     grpc_timer_init(
         exec_ctx, &t->keepalive_ping_timer,
         gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), t->keepalive_time),
         &t->init_keepalive_ping_locked, gpr_now(GPR_CLOCK_MONOTONIC));
+  } else {
+    /* Use GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED to indicate there are no
+       inflight keeaplive timers */
+    t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED;
   }
 
   grpc_chttp2_initiate_write(exec_ctx, t, false, "init");
@@ -494,8 +575,9 @@ static void destroy_transport_locked(grpc_exec_ctx *exec_ctx, void *tp,
   t->destroying = 1;
   close_transport_locked(
       exec_ctx, t,
-      grpc_error_set_int(GRPC_ERROR_CREATE("Transport destroyed"),
-                         GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state));
+      grpc_error_set_int(
+          GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed"),
+          GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state));
   GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "destroy");
 }
 
@@ -511,38 +593,36 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
                                    grpc_chttp2_transport *t,
                                    grpc_error *error) {
   if (!t->closed) {
+    if (!grpc_error_has_clear_grpc_status(error)) {
+      error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS,
+                                 GRPC_STATUS_UNAVAILABLE);
+    }
     if (t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE) {
       if (t->close_transport_on_writes_finished == NULL) {
         t->close_transport_on_writes_finished =
-            GRPC_ERROR_CREATE("Delayed close due to in-progress write");
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                "Delayed close due to in-progress write");
       }
       t->close_transport_on_writes_finished =
           grpc_error_add_child(t->close_transport_on_writes_finished, error);
       return;
     }
-    if (!grpc_error_has_clear_grpc_status(error)) {
-      error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS,
-                                 GRPC_STATUS_UNAVAILABLE);
-    }
     t->closed = 1;
     connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_SHUTDOWN,
                            GRPC_ERROR_REF(error), "close_transport");
     grpc_endpoint_shutdown(exec_ctx, t->ep, GRPC_ERROR_REF(error));
-    if (t->is_client) {
-      switch (t->keepalive_state) {
-        case GRPC_CHTTP2_KEEPALIVE_STATE_WAITING: {
-          grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer);
-          break;
-        }
-        case GRPC_CHTTP2_KEEPALIVE_STATE_PINGING: {
-          grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer);
-          grpc_timer_cancel(exec_ctx, &t->keepalive_watchdog_timer);
-          break;
-        }
-        case GRPC_CHTTP2_KEEPALIVE_STATE_DYING: {
-          break;
-        }
-      }
+    switch (t->keepalive_state) {
+      case GRPC_CHTTP2_KEEPALIVE_STATE_WAITING:
+        grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer);
+        break;
+      case GRPC_CHTTP2_KEEPALIVE_STATE_PINGING:
+        grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer);
+        grpc_timer_cancel(exec_ctx, &t->keepalive_watchdog_timer);
+        break;
+      case GRPC_CHTTP2_KEEPALIVE_STATE_DYING:
+      case GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED:
+        /* keepalive timers are not set in these two states */
+        break;
     }
 
     /* flush writable stream list to avoid dangling references */
@@ -575,7 +655,7 @@ void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream *s) {
 
 static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
                        grpc_stream *gs, grpc_stream_refcount *refcount,
-                       const void *server_data) {
+                       const void *server_data, gpr_arena *arena) {
   GPR_TIMER_BEGIN("init_stream", 0);
   grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
   grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs;
@@ -585,16 +665,20 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
   /* We reserve one 'active stream' that's dropped when the stream is
      read-closed. The others are for incoming_byte_streams that are actively
      reading */
-  gpr_ref_init(&s->active_streams, 1);
   GRPC_CHTTP2_STREAM_REF(s, "chttp2");
 
-  grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[0]);
-  grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[1]);
+  grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[0], arena);
+  grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[1], arena);
   grpc_chttp2_data_parser_init(&s->data_parser);
   grpc_slice_buffer_init(&s->flow_controlled_buffer);
   s->deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
   grpc_closure_init(&s->complete_fetch_locked, complete_fetch_locked, s,
                     grpc_schedule_on_exec_ctx);
+  grpc_slice_buffer_init(&s->unprocessed_incoming_frames_buffer);
+  grpc_slice_buffer_init(&s->frame_storage);
+  s->pending_byte_stream = false;
+  grpc_closure_init(&s->reset_byte_stream, reset_byte_stream, s,
+                    grpc_combiner_scheduler(t->combiner, false));
 
   GRPC_CHTTP2_REF_TRANSPORT(t, "stream");
 
@@ -612,7 +696,6 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
 
 static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
                                   grpc_error *error) {
-  grpc_byte_stream *bs;
   grpc_chttp2_stream *s = sp;
   grpc_chttp2_transport *t = s->t;
 
@@ -623,9 +706,9 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
     GPR_ASSERT(grpc_chttp2_stream_map_find(&t->stream_map, s->id) == NULL);
   }
 
-  while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames))) {
-    incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE);
-  }
+  grpc_slice_buffer_destroy_internal(exec_ctx,
+                                     &s->unprocessed_incoming_frames_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &s->frame_storage);
 
   grpc_chttp2_list_remove_stalled_by_transport(t, s);
   grpc_chttp2_list_remove_stalled_by_stream(t, s);
@@ -652,6 +735,7 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
   grpc_slice_buffer_destroy_internal(exec_ctx, &s->flow_controlled_buffer);
   GRPC_ERROR_UNREF(s->read_closed_error);
   GRPC_ERROR_UNREF(s->write_closed_error);
+  GRPC_ERROR_UNREF(s->byte_stream_error);
 
   if (s->incoming_window_delta > 0) {
     GRPC_CHTTP2_FLOW_DEBIT_STREAM_INCOMING_WINDOW_DELTA(
@@ -665,16 +749,17 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
 
   GPR_TIMER_END("destroy_stream", 0);
 
-  gpr_free(s->destroy_stream_arg);
+  grpc_closure_sched(exec_ctx, s->destroy_stream_arg, GRPC_ERROR_NONE);
 }
 
 static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
-                           grpc_stream *gs, void *and_free_memory) {
+                           grpc_stream *gs,
+                           grpc_closure *then_schedule_closure) {
   GPR_TIMER_BEGIN("destroy_stream", 0);
   grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
   grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs;
 
-  s->destroy_stream_arg = and_free_memory;
+  s->destroy_stream_arg = then_schedule_closure;
   grpc_closure_sched(
       exec_ctx, grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s,
                                   grpc_combiner_scheduler(t->combiner, false)),
@@ -833,7 +918,8 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp,
   if (t->sent_goaway_state == GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED) {
     t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SENT;
     if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) {
-      close_transport_locked(exec_ctx, t, GRPC_ERROR_CREATE("goaway sent"));
+      close_transport_locked(
+          exec_ctx, t, GRPC_ERROR_CREATE_FROM_STATIC_STRING("goaway sent"));
     }
   }
 
@@ -897,22 +983,39 @@ void grpc_chttp2_add_incoming_goaway(grpc_exec_ctx *exec_ctx,
                                      grpc_chttp2_transport *t,
                                      uint32_t goaway_error,
                                      grpc_slice goaway_text) {
-  char *msg = grpc_dump_slice(goaway_text, GPR_DUMP_HEX | GPR_DUMP_ASCII);
-  GRPC_CHTTP2_IF_TRACING(
-      gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg));
-  grpc_slice_unref_internal(exec_ctx, goaway_text);
+  // GRPC_CHTTP2_IF_TRACING(
+  //     gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg));
   t->seen_goaway = 1;
+
+  /* When a client receives a GOAWAY with error code ENHANCE_YOUR_CALM and debug
+   * data equal to “too_many_pings”, it should log the occurrence at a log level
+   * that is enabled by default and double the configured KEEPALIVE_TIME used
+   * for new connections on that channel. */
+  if (t->is_client && goaway_error == GRPC_HTTP2_ENHANCE_YOUR_CALM &&
+      grpc_slice_str_cmp(goaway_text, "too_many_pings") == 0) {
+    gpr_log(GPR_ERROR,
+            "Received a GOAWAY with error code ENHANCE_YOUR_CALM and debug "
+            "data equal to \"too_many_pings\"");
+    double current_keepalive_time_ms =
+        gpr_timespec_to_micros(t->keepalive_time) / 1000;
+    t->keepalive_time =
+        current_keepalive_time_ms > INT_MAX / KEEPALIVE_TIME_BACKOFF_MULTIPLIER
+            ? gpr_inf_future(GPR_TIMESPAN)
+            : gpr_time_from_millis((int64_t)(current_keepalive_time_ms *
+                                             KEEPALIVE_TIME_BACKOFF_MULTIPLIER),
+                                   GPR_TIMESPAN);
+  }
+
   /* lie: use transient failure from the transport to indicate goaway has been
    * received */
   connectivity_state_set(
       exec_ctx, t, GRPC_CHANNEL_TRANSIENT_FAILURE,
       grpc_error_set_str(
-          grpc_error_set_int(GRPC_ERROR_CREATE("GOAWAY received"),
-                             GRPC_ERROR_INT_HTTP2_ERROR,
-                             (intptr_t)goaway_error),
-          GRPC_ERROR_STR_RAW_BYTES, msg),
+          grpc_error_set_int(
+              GRPC_ERROR_CREATE_FROM_STATIC_STRING("GOAWAY received"),
+              GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)goaway_error),
+          GRPC_ERROR_STR_RAW_BYTES, goaway_text),
       "got_goaway");
-  gpr_free(msg);
 }
 
 static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx,
@@ -935,9 +1038,10 @@ static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx,
     t->next_stream_id += 2;
 
     if (t->next_stream_id >= MAX_CLIENT_STREAM_ID) {
-      connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_TRANSIENT_FAILURE,
-                             GRPC_ERROR_CREATE("Stream IDs exhausted"),
-                             "no_more_stream_ids");
+      connectivity_state_set(
+          exec_ctx, t, GRPC_CHANNEL_TRANSIENT_FAILURE,
+          GRPC_ERROR_CREATE_FROM_STATIC_STRING("Stream IDs exhausted"),
+          "no_more_stream_ids");
     }
 
     grpc_chttp2_stream_map_add(&t->stream_map, s->id, s);
@@ -951,9 +1055,9 @@ static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx,
          grpc_chttp2_list_pop_waiting_for_concurrency(t, &s)) {
     grpc_chttp2_cancel_stream(
         exec_ctx, t, s,
-        grpc_error_set_int(GRPC_ERROR_CREATE("Stream IDs exhausted"),
-                           GRPC_ERROR_INT_GRPC_STATUS,
-                           GRPC_STATUS_UNAVAILABLE));
+        grpc_error_set_int(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Stream IDs exhausted"),
+            GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE));
   }
 }
 
@@ -1002,11 +1106,11 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx,
   }
   if (error != GRPC_ERROR_NONE) {
     if (closure->error_data.error == GRPC_ERROR_NONE) {
-      closure->error_data.error =
-          GRPC_ERROR_CREATE("Error in HTTP transport completing operation");
-      closure->error_data.error =
-          grpc_error_set_str(closure->error_data.error,
-                             GRPC_ERROR_STR_TARGET_ADDRESS, t->peer_string);
+      closure->error_data.error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "Error in HTTP transport completing operation");
+      closure->error_data.error = grpc_error_set_str(
+          closure->error_data.error, GRPC_ERROR_STR_TARGET_ADDRESS,
+          grpc_slice_from_copied_string(t->peer_string));
     }
     closure->error_data.error =
         grpc_error_add_child(closure->error_data.error, error);
@@ -1085,8 +1189,9 @@ static void continue_fetching_send_locked(grpc_exec_ctx *exec_ctx,
       s->fetching_send_message = NULL;
       return; /* early out */
     } else if (grpc_byte_stream_next(exec_ctx, s->fetching_send_message,
-                                     &s->fetching_slice, UINT32_MAX,
-                                     &s->complete_fetch)) {
+                                     UINT32_MAX, &s->complete_fetch_locked)) {
+      grpc_byte_stream_pull(exec_ctx, s->fetching_send_message,
+                            &s->fetching_slice);
       add_fetched_slice_locked(exec_ctx, t, s);
     }
   }
@@ -1097,9 +1202,15 @@ static void complete_fetch_locked(grpc_exec_ctx *exec_ctx, void *gs,
   grpc_chttp2_stream *s = gs;
   grpc_chttp2_transport *t = s->t;
   if (error == GRPC_ERROR_NONE) {
-    add_fetched_slice_locked(exec_ctx, t, s);
-    continue_fetching_send_locked(exec_ctx, t, s);
-  } else {
+    error = grpc_byte_stream_pull(exec_ctx, s->fetching_send_message,
+                                  &s->fetching_slice);
+    if (error == GRPC_ERROR_NONE) {
+      add_fetched_slice_locked(exec_ctx, t, s);
+      continue_fetching_send_locked(exec_ctx, t, s);
+    }
+  }
+
+  if (error != GRPC_ERROR_NONE) {
     /* TODO(ctiller): what to do here */
     abort();
   }
@@ -1124,20 +1235,23 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
                                      grpc_error *error_ignored) {
   GPR_TIMER_BEGIN("perform_stream_op_locked", 0);
 
-  grpc_transport_stream_op *op = stream_op;
-  grpc_chttp2_transport *t = op->handler_private.args[0];
-  grpc_chttp2_stream *s = op->handler_private.args[1];
+  grpc_transport_stream_op_batch *op = stream_op;
+  grpc_chttp2_stream *s = op->handler_private.extra_arg;
+  grpc_transport_stream_op_batch_payload *op_payload = op->payload;
+  grpc_chttp2_transport *t = s->t;
 
   if (grpc_http_trace) {
-    char *str = grpc_transport_stream_op_string(op);
+    char *str = grpc_transport_stream_op_batch_string(op);
     gpr_log(GPR_DEBUG, "perform_stream_op_locked: %s; on_complete = %p", str,
             op->on_complete);
     gpr_free(str);
     if (op->send_initial_metadata) {
-      log_metadata(op->send_initial_metadata, s->id, t->is_client, true);
+      log_metadata(op_payload->send_initial_metadata.send_initial_metadata,
+                   s->id, t->is_client, true);
     }
     if (op->send_trailing_metadata) {
-      log_metadata(op->send_trailing_metadata, s->id, t->is_client, false);
+      log_metadata(op_payload->send_trailing_metadata.send_trailing_metadata,
+                   s->id, t->is_client, false);
     }
   }
 
@@ -1152,23 +1266,25 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
   on_complete->next_data.scratch = CLOSURE_BARRIER_FIRST_REF_BIT;
   on_complete->error_data.error = GRPC_ERROR_NONE;
 
-  if (op->collect_stats != NULL) {
+  if (op->collect_stats) {
     GPR_ASSERT(s->collecting_stats == NULL);
-    s->collecting_stats = op->collect_stats;
+    s->collecting_stats = op_payload->collect_stats.collect_stats;
     on_complete->next_data.scratch |= CLOSURE_BARRIER_STATS_BIT;
   }
 
-  if (op->cancel_error != GRPC_ERROR_NONE) {
-    grpc_chttp2_cancel_stream(exec_ctx, t, s, op->cancel_error);
+  if (op->cancel_stream) {
+    grpc_chttp2_cancel_stream(exec_ctx, t, s,
+                              op_payload->cancel_stream.cancel_error);
   }
 
-  if (op->send_initial_metadata != NULL) {
+  if (op->send_initial_metadata) {
     GPR_ASSERT(s->send_initial_metadata_finished == NULL);
     on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE;
     s->send_initial_metadata_finished = add_closure_barrier(on_complete);
-    s->send_initial_metadata = op->send_initial_metadata;
+    s->send_initial_metadata =
+        op_payload->send_initial_metadata.send_initial_metadata;
     const size_t metadata_size =
-        grpc_metadata_batch_size(op->send_initial_metadata);
+        grpc_metadata_batch_size(s->send_initial_metadata);
     const size_t metadata_peer_limit =
         t->settings[GRPC_PEER_SETTINGS]
                    [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
@@ -1181,14 +1297,15 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
           exec_ctx, t, s,
           grpc_error_set_int(
               grpc_error_set_int(
-                  grpc_error_set_int(
-                      GRPC_ERROR_CREATE("to-be-sent initial metadata size "
-                                        "exceeds peer limit"),
-                      GRPC_ERROR_INT_SIZE, (intptr_t)metadata_size),
+                  grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                         "to-be-sent initial metadata size "
+                                         "exceeds peer limit"),
+                                     GRPC_ERROR_INT_SIZE,
+                                     (intptr_t)metadata_size),
                   GRPC_ERROR_INT_LIMIT, (intptr_t)metadata_peer_limit),
               GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
     } else {
-      if (contains_non_ok_status(op->send_initial_metadata)) {
+      if (contains_non_ok_status(s->send_initial_metadata)) {
         s->seen_error = true;
       }
       if (!s->write_closed) {
@@ -1200,21 +1317,27 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
           } else {
             grpc_chttp2_cancel_stream(
                 exec_ctx, t, s,
-                grpc_error_set_int(GRPC_ERROR_CREATE("Transport closed"),
-                                   GRPC_ERROR_INT_GRPC_STATUS,
-                                   GRPC_STATUS_UNAVAILABLE));
+                grpc_error_set_int(
+                    GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport closed"),
+                    GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE));
           }
         } else {
           GPR_ASSERT(s->id != 0);
-          grpc_chttp2_become_writable(exec_ctx, t, s,
-                                      GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED,
+          grpc_chttp2_stream_write_type write_type =
+              GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED;
+          if (op->send_message &&
+              (op->payload->send_message.send_message->flags &
+               GRPC_WRITE_BUFFER_HINT)) {
+            write_type = GRPC_CHTTP2_STREAM_WRITE_PIGGYBACK;
+          }
+          grpc_chttp2_become_writable(exec_ctx, t, s, write_type,
                                       "op.send_initial_metadata");
         }
       } else {
         s->send_initial_metadata = NULL;
         grpc_chttp2_complete_closure_step(
             exec_ctx, t, s, &s->send_initial_metadata_finished,
-            GRPC_ERROR_CREATE_REFERENCING(
+            GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
                 "Attempt to send initial metadata after stream was closed",
                 &s->write_closed_error, 1),
             "send_initial_metadata_finished");
@@ -1222,13 +1345,13 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
     }
   }
 
-  if (op->send_message != NULL) {
+  if (op->send_message) {
     on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE;
     s->fetching_send_message_finished = add_closure_barrier(op->on_complete);
     if (s->write_closed) {
       grpc_chttp2_complete_closure_step(
           exec_ctx, t, s, &s->fetching_send_message_finished,
-          GRPC_ERROR_CREATE_REFERENCING(
+          GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
               "Attempt to send message after stream was closed",
               &s->write_closed_error, 1),
           "fetching_send_message_finished");
@@ -1236,14 +1359,14 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
       GPR_ASSERT(s->fetching_send_message == NULL);
       uint8_t *frame_hdr =
           grpc_slice_buffer_tiny_add(&s->flow_controlled_buffer, 5);
-      uint32_t flags = op->send_message->flags;
+      uint32_t flags = op_payload->send_message.send_message->flags;
       frame_hdr[0] = (flags & GRPC_WRITE_INTERNAL_COMPRESS) != 0;
-      size_t len = op->send_message->length;
+      size_t len = op_payload->send_message.send_message->length;
       frame_hdr[1] = (uint8_t)(len >> 24);
       frame_hdr[2] = (uint8_t)(len >> 16);
       frame_hdr[3] = (uint8_t)(len >> 8);
       frame_hdr[4] = (uint8_t)(len);
-      s->fetching_send_message = op->send_message;
+      s->fetching_send_message = op_payload->send_message.send_message;
       s->fetched_send_message_length = 0;
       s->next_message_end_offset = s->flow_controlled_bytes_written +
                                    (int64_t)s->flow_controlled_buffer.length +
@@ -1260,14 +1383,15 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
     }
   }
 
-  if (op->send_trailing_metadata != NULL) {
+  if (op->send_trailing_metadata) {
     GPR_ASSERT(s->send_trailing_metadata_finished == NULL);
     on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE;
     s->send_trailing_metadata_finished = add_closure_barrier(on_complete);
-    s->send_trailing_metadata = op->send_trailing_metadata;
+    s->send_trailing_metadata =
+        op_payload->send_trailing_metadata.send_trailing_metadata;
     s->write_buffering = false;
     const size_t metadata_size =
-        grpc_metadata_batch_size(op->send_trailing_metadata);
+        grpc_metadata_batch_size(s->send_trailing_metadata);
     const size_t metadata_peer_limit =
         t->settings[GRPC_PEER_SETTINGS]
                    [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
@@ -1276,24 +1400,27 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
           exec_ctx, t, s,
           grpc_error_set_int(
               grpc_error_set_int(
-                  grpc_error_set_int(
-                      GRPC_ERROR_CREATE("to-be-sent trailing metadata size "
-                                        "exceeds peer limit"),
-                      GRPC_ERROR_INT_SIZE, (intptr_t)metadata_size),
+                  grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                         "to-be-sent trailing metadata size "
+                                         "exceeds peer limit"),
+                                     GRPC_ERROR_INT_SIZE,
+                                     (intptr_t)metadata_size),
                   GRPC_ERROR_INT_LIMIT, (intptr_t)metadata_peer_limit),
               GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
     } else {
-      if (contains_non_ok_status(op->send_trailing_metadata)) {
+      if (contains_non_ok_status(s->send_trailing_metadata)) {
         s->seen_error = true;
       }
       if (s->write_closed) {
         s->send_trailing_metadata = NULL;
         grpc_chttp2_complete_closure_step(
             exec_ctx, t, s, &s->send_trailing_metadata_finished,
-            grpc_metadata_batch_is_empty(op->send_trailing_metadata)
+            grpc_metadata_batch_is_empty(
+                op->payload->send_trailing_metadata.send_trailing_metadata)
                 ? GRPC_ERROR_NONE
-                : GRPC_ERROR_CREATE("Attempt to send trailing metadata after "
-                                    "stream was closed"),
+                : GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                      "Attempt to send trailing metadata after "
+                      "stream was closed"),
             "send_trailing_metadata_finished");
       } else if (s->id != 0) {
         /* TODO(ctiller): check if there's flow control for any outstanding
@@ -1305,28 +1432,39 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
     }
   }
 
-  if (op->recv_initial_metadata != NULL) {
+  if (op->recv_initial_metadata) {
     GPR_ASSERT(s->recv_initial_metadata_ready == NULL);
-    s->recv_initial_metadata_ready = op->recv_initial_metadata_ready;
-    s->recv_initial_metadata = op->recv_initial_metadata;
+    s->recv_initial_metadata_ready =
+        op_payload->recv_initial_metadata.recv_initial_metadata_ready;
+    s->recv_initial_metadata =
+        op_payload->recv_initial_metadata.recv_initial_metadata;
     grpc_chttp2_maybe_complete_recv_initial_metadata(exec_ctx, t, s);
   }
 
-  if (op->recv_message != NULL) {
+  if (op->recv_message) {
+    size_t already_received;
     GPR_ASSERT(s->recv_message_ready == NULL);
-    s->recv_message_ready = op->recv_message_ready;
-    s->recv_message = op->recv_message;
-    if (s->id != 0 &&
-        (s->incoming_frames.head == NULL || s->incoming_frames.head->is_tail)) {
-      incoming_byte_stream_update_flow_control(exec_ctx, t, s, 5, 0);
+    GPR_ASSERT(!s->pending_byte_stream);
+    s->recv_message_ready = op_payload->recv_message.recv_message_ready;
+    s->recv_message = op_payload->recv_message.recv_message;
+    if (s->id != 0) {
+      if (s->pending_byte_stream) {
+        already_received = s->frame_storage.length;
+      } else {
+        already_received = s->frame_storage.length +
+                           s->unprocessed_incoming_frames_buffer.length;
+      }
+      incoming_byte_stream_update_flow_control(exec_ctx, t, s, 5,
+                                               already_received);
     }
     grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
   }
 
-  if (op->recv_trailing_metadata != NULL) {
+  if (op->recv_trailing_metadata) {
     GPR_ASSERT(s->recv_trailing_metadata_finished == NULL);
     s->recv_trailing_metadata_finished = add_closure_barrier(on_complete);
-    s->recv_trailing_metadata = op->recv_trailing_metadata;
+    s->recv_trailing_metadata =
+        op_payload->recv_trailing_metadata.recv_trailing_metadata;
     s->final_metadata_requested = true;
     grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
   }
@@ -1339,19 +1477,19 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
 }
 
 static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
-                              grpc_stream *gs, grpc_transport_stream_op *op) {
+                              grpc_stream *gs,
+                              grpc_transport_stream_op_batch *op) {
   GPR_TIMER_BEGIN("perform_stream_op", 0);
   grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
   grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs;
 
   if (grpc_http_trace) {
-    char *str = grpc_transport_stream_op_string(op);
+    char *str = grpc_transport_stream_op_batch_string(op);
     gpr_log(GPR_DEBUG, "perform_stream_op[s=%p/%d]: %s", s, s->id, str);
     gpr_free(str);
   }
 
-  op->handler_private.args[0] = gt;
-  op->handler_private.args[1] = gs;
+  op->handler_private.extra_arg = gs;
   GRPC_CHTTP2_STREAM_REF(s, "perform_stream_op");
   grpc_closure_sched(
       exec_ctx,
@@ -1388,6 +1526,13 @@ static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
   }
 }
 
+static void retry_initiate_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
+                                       grpc_error *error) {
+  grpc_chttp2_transport *t = tp;
+  t->ping_state.is_delayed_ping_timer_set = false;
+  grpc_chttp2_initiate_write(exec_ctx, t, false, "retry_send_ping");
+}
+
 void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
                           uint64_t id) {
   grpc_chttp2_ping_queue *pq =
@@ -1408,20 +1553,35 @@ static void send_goaway(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
                         grpc_error *error) {
   t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED;
   grpc_http2_error_code http_error;
-  const char *msg;
-  grpc_error_get_status(error, gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL, &msg,
-                        &http_error);
+  grpc_slice slice;
+  grpc_error_get_status(error, gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL,
+                        &slice, &http_error);
   grpc_chttp2_goaway_append(t->last_new_stream_id, (uint32_t)http_error,
-                            grpc_slice_from_copied_string(msg), &t->qbuf);
+                            grpc_slice_ref_internal(slice), &t->qbuf);
   grpc_chttp2_initiate_write(exec_ctx, t, false, "goaway_sent");
   GRPC_ERROR_UNREF(error);
 }
 
+void grpc_chttp2_add_ping_strike(grpc_exec_ctx *exec_ctx,
+                                 grpc_chttp2_transport *t) {
+  gpr_log(GPR_DEBUG, "PING strike");
+  if (++t->ping_recv_state.ping_strikes > t->ping_policy.max_ping_strikes &&
+      t->ping_policy.max_ping_strikes != 0) {
+    send_goaway(exec_ctx, t,
+                grpc_error_set_int(
+                    GRPC_ERROR_CREATE_FROM_STATIC_STRING("too_many_pings"),
+                    GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_ENHANCE_YOUR_CALM));
+    /*The transport will be closed after the write is done */
+    close_transport_locked(
+        exec_ctx, t, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many pings"));
+  }
+}
+
 static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
                                         void *stream_op,
                                         grpc_error *error_ignored) {
   grpc_transport_op *op = stream_op;
-  grpc_chttp2_transport *t = op->transport_private.args[0];
+  grpc_chttp2_transport *t = op->handler_private.extra_arg;
   grpc_error *close_transport = op->disconnect_with_error;
 
   if (op->on_connectivity_state_change != NULL) {
@@ -1467,10 +1627,10 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
   grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
   char *msg = grpc_transport_op_string(op);
   gpr_free(msg);
-  op->transport_private.args[0] = gt;
+  op->handler_private.extra_arg = gt;
   GRPC_CHTTP2_REF_TRANSPORT(t, "transport_op");
   grpc_closure_sched(
-      exec_ctx, grpc_closure_init(&op->transport_private.closure,
+      exec_ctx, grpc_closure_init(&op->handler_private.closure,
                                   perform_transport_op_locked, op,
                                   grpc_combiner_scheduler(t->combiner, false)),
       GRPC_ERROR_NONE);
@@ -1483,13 +1643,13 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
 void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx,
                                                       grpc_chttp2_transport *t,
                                                       grpc_chttp2_stream *s) {
-  grpc_byte_stream *bs;
   if (s->recv_initial_metadata_ready != NULL &&
       s->published_metadata[0] != GRPC_METADATA_NOT_PUBLISHED) {
     if (s->seen_error) {
-      while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) !=
-             NULL) {
-        incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE);
+      grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage);
+      if (!s->pending_byte_stream) {
+        grpc_slice_buffer_reset_and_unref_internal(
+            exec_ctx, &s->unprocessed_incoming_frames_buffer);
       }
     }
     grpc_chttp2_incoming_metadata_buffer_publish(
@@ -1502,39 +1662,65 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx,
 void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx,
                                              grpc_chttp2_transport *t,
                                              grpc_chttp2_stream *s) {
-  grpc_byte_stream *bs;
+  grpc_error *error = GRPC_ERROR_NONE;
   if (s->recv_message_ready != NULL) {
-    while (s->final_metadata_requested && s->seen_error &&
-           (bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) !=
-               NULL) {
-      incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE);
+    *s->recv_message = NULL;
+    if (s->final_metadata_requested && s->seen_error) {
+      grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage);
+      if (!s->pending_byte_stream) {
+        grpc_slice_buffer_reset_and_unref_internal(
+            exec_ctx, &s->unprocessed_incoming_frames_buffer);
+      }
+    }
+    if (!s->pending_byte_stream) {
+      while (s->unprocessed_incoming_frames_buffer.length > 0 ||
+             s->frame_storage.length > 0) {
+        if (s->unprocessed_incoming_frames_buffer.length == 0) {
+          grpc_slice_buffer_swap(&s->unprocessed_incoming_frames_buffer,
+                                 &s->frame_storage);
+        }
+        error = grpc_deframe_unprocessed_incoming_frames(
+            exec_ctx, &s->data_parser, s,
+            &s->unprocessed_incoming_frames_buffer, NULL, s->recv_message);
+        if (error != GRPC_ERROR_NONE) {
+          s->seen_error = true;
+          grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
+                                                     &s->frame_storage);
+          grpc_slice_buffer_reset_and_unref_internal(
+              exec_ctx, &s->unprocessed_incoming_frames_buffer);
+          break;
+        } else if (*s->recv_message != NULL) {
+          break;
+        }
+      }
     }
-    if (s->incoming_frames.head != NULL) {
-      *s->recv_message =
-          grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames);
-      GPR_ASSERT(*s->recv_message != NULL);
+    if (error == GRPC_ERROR_NONE && *s->recv_message != NULL) {
       null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE);
     } else if (s->published_metadata[1] != GRPC_METADATA_NOT_PUBLISHED) {
       *s->recv_message = NULL;
       null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE);
     }
+    GRPC_ERROR_UNREF(error);
   }
 }
 
 void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx,
                                                        grpc_chttp2_transport *t,
                                                        grpc_chttp2_stream *s) {
-  grpc_byte_stream *bs;
   grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
   if (s->recv_trailing_metadata_finished != NULL && s->read_closed &&
       s->write_closed) {
     if (s->seen_error) {
-      while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) !=
-             NULL) {
-        incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE);
+      grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage);
+      if (!s->pending_byte_stream) {
+        grpc_slice_buffer_reset_and_unref_internal(
+            exec_ctx, &s->unprocessed_incoming_frames_buffer);
       }
     }
-    if (s->all_incoming_byte_streams_finished &&
+    bool pending_data = s->pending_byte_stream ||
+                        s->unprocessed_incoming_frames_buffer.length > 0;
+    if (s->read_closed && s->frame_storage.length == 0 &&
+        (!pending_data || s->seen_error) &&
         s->recv_trailing_metadata_finished != NULL) {
       grpc_chttp2_incoming_metadata_buffer_publish(
           exec_ctx, &s->metadata_buffer[1], s->recv_trailing_metadata);
@@ -1545,14 +1731,6 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx,
   }
 }
 
-static void decrement_active_streams_locked(grpc_exec_ctx *exec_ctx,
-                                            grpc_chttp2_transport *t,
-                                            grpc_chttp2_stream *s) {
-  if ((s->all_incoming_byte_streams_finished = gpr_unref(&s->active_streams))) {
-    grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
-  }
-}
-
 static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
                           uint32_t id, grpc_error *error) {
   grpc_chttp2_stream *s = grpc_chttp2_stream_map_delete(&t->stream_map, id);
@@ -1561,10 +1739,19 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
     t->incoming_stream = NULL;
     grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
   }
-  if (s->data_parser.parsing_frame != NULL) {
-    grpc_chttp2_incoming_byte_stream_finished(
-        exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error));
-    s->data_parser.parsing_frame = NULL;
+  if (s->pending_byte_stream) {
+    if (s->on_next != NULL) {
+      grpc_chttp2_incoming_byte_stream *bs = s->data_parser.parsing_frame;
+      if (error == GRPC_ERROR_NONE) {
+        error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message");
+      }
+      incoming_byte_stream_publish_error(exec_ctx, bs, error);
+      incoming_byte_stream_unref(exec_ctx, bs);
+      s->data_parser.parsing_frame = NULL;
+    } else {
+      GRPC_ERROR_UNREF(s->byte_stream_error);
+      s->byte_stream_error = GRPC_ERROR_REF(error);
+    }
   }
 
   if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) {
@@ -1572,7 +1759,7 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
     if (t->sent_goaway_state == GRPC_CHTTP2_GOAWAY_SENT) {
       close_transport_locked(
           exec_ctx, t,
-          GRPC_ERROR_CREATE_REFERENCING(
+          GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
               "Last stream closed after sending GOAWAY", &error, 1));
     }
   }
@@ -1613,8 +1800,8 @@ void grpc_chttp2_cancel_stream(grpc_exec_ctx *exec_ctx,
 void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
                              grpc_chttp2_stream *s, grpc_error *error) {
   grpc_status_code status;
-  const char *msg;
-  grpc_error_get_status(error, s->deadline, &status, &msg, NULL);
+  grpc_slice slice;
+  grpc_error_get_status(error, s->deadline, &status, &slice, NULL);
 
   if (status != GRPC_STATUS_OK) {
     s->seen_error = true;
@@ -1629,15 +1816,19 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
       s->recv_trailing_metadata_finished != NULL) {
     char status_string[GPR_LTOA_MIN_BUFSIZE];
     gpr_ltoa(status, status_string);
-    grpc_chttp2_incoming_metadata_buffer_replace_or_add(
-        exec_ctx, &s->metadata_buffer[1],
-        grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_STATUS,
-                                grpc_slice_from_copied_string(status_string)));
-    if (msg != NULL) {
-      grpc_chttp2_incoming_metadata_buffer_replace_or_add(
-          exec_ctx, &s->metadata_buffer[1],
-          grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
-                                  grpc_slice_from_copied_string(msg)));
+    GRPC_LOG_IF_ERROR("add_status",
+                      grpc_chttp2_incoming_metadata_buffer_replace_or_add(
+                          exec_ctx, &s->metadata_buffer[1],
+                          grpc_mdelem_from_slices(
+                              exec_ctx, GRPC_MDSTR_GRPC_STATUS,
+                              grpc_slice_from_copied_string(status_string))));
+    if (!GRPC_SLICE_IS_EMPTY(slice)) {
+      GRPC_LOG_IF_ERROR(
+          "add_status_message",
+          grpc_chttp2_incoming_metadata_buffer_replace_or_add(
+              exec_ctx, &s->metadata_buffer[1],
+              grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
+                                      grpc_slice_ref_internal(slice))));
     }
     s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE;
     grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
@@ -1666,7 +1857,8 @@ static grpc_error *removal_error(grpc_error *extra_error, grpc_chttp2_stream *s,
   add_error(extra_error, refs, &nrefs);
   grpc_error *error = GRPC_ERROR_NONE;
   if (nrefs > 0) {
-    error = GRPC_ERROR_CREATE_REFERENCING(master_error_msg, refs, nrefs);
+    error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(master_error_msg,
+                                                             refs, nrefs);
   }
   GRPC_ERROR_UNREF(extra_error);
   return error;
@@ -1745,7 +1937,6 @@ void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx,
         s->published_metadata[i] = GPRC_METADATA_PUBLISHED_AT_CLOSE;
       }
     }
-    decrement_active_streams_locked(exec_ctx, t, s);
     grpc_chttp2_maybe_complete_recv_initial_metadata(exec_ctx, t, s);
     grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
   }
@@ -1760,12 +1951,14 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
                            grpc_chttp2_stream *s, grpc_error *error) {
   grpc_slice hdr;
   grpc_slice status_hdr;
+  grpc_slice http_status_hdr;
+  grpc_slice content_type_hdr;
   grpc_slice message_pfx;
   uint8_t *p;
   uint32_t len = 0;
   grpc_status_code grpc_status;
-  const char *msg;
-  grpc_error_get_status(error, s->deadline, &grpc_status, &msg, NULL);
+  grpc_slice slice;
+  grpc_error_get_status(error, s->deadline, &grpc_status, &slice, NULL);
 
   GPR_ASSERT(grpc_status >= 0 && (int)grpc_status < 100);
 
@@ -1775,7 +1968,63 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
      It's complicated by the fact that our send machinery would be dead by
      the time we got around to sending this, so instead we ignore HPACK
      compression and just write the uncompressed bytes onto the wire. */
-  status_hdr = grpc_slice_malloc(15 + (grpc_status >= 10));
+  if (!s->sent_initial_metadata) {
+    http_status_hdr = GRPC_SLICE_MALLOC(13);
+    p = GRPC_SLICE_START_PTR(http_status_hdr);
+    *p++ = 0x00;
+    *p++ = 7;
+    *p++ = ':';
+    *p++ = 's';
+    *p++ = 't';
+    *p++ = 'a';
+    *p++ = 't';
+    *p++ = 'u';
+    *p++ = 's';
+    *p++ = 3;
+    *p++ = '2';
+    *p++ = '0';
+    *p++ = '0';
+    GPR_ASSERT(p == GRPC_SLICE_END_PTR(http_status_hdr));
+    len += (uint32_t)GRPC_SLICE_LENGTH(http_status_hdr);
+
+    content_type_hdr = GRPC_SLICE_MALLOC(31);
+    p = GRPC_SLICE_START_PTR(content_type_hdr);
+    *p++ = 0x00;
+    *p++ = 12;
+    *p++ = 'c';
+    *p++ = 'o';
+    *p++ = 'n';
+    *p++ = 't';
+    *p++ = 'e';
+    *p++ = 'n';
+    *p++ = 't';
+    *p++ = '-';
+    *p++ = 't';
+    *p++ = 'y';
+    *p++ = 'p';
+    *p++ = 'e';
+    *p++ = 16;
+    *p++ = 'a';
+    *p++ = 'p';
+    *p++ = 'p';
+    *p++ = 'l';
+    *p++ = 'i';
+    *p++ = 'c';
+    *p++ = 'a';
+    *p++ = 't';
+    *p++ = 'i';
+    *p++ = 'o';
+    *p++ = 'n';
+    *p++ = '/';
+    *p++ = 'g';
+    *p++ = 'r';
+    *p++ = 'p';
+    *p++ = 'c';
+    GPR_ASSERT(p == GRPC_SLICE_END_PTR(content_type_hdr));
+    len += (uint32_t)GRPC_SLICE_LENGTH(content_type_hdr);
+  }
+
+  status_hdr = GRPC_SLICE_MALLOC(15 + (grpc_status >= 10));
   p = GRPC_SLICE_START_PTR(status_hdr);
   *p++ = 0x00; /* literal header, not indexed */
   *p++ = 11;   /* len(grpc-status) */
@@ -1801,34 +2050,32 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
   GPR_ASSERT(p == GRPC_SLICE_END_PTR(status_hdr));
   len += (uint32_t)GRPC_SLICE_LENGTH(status_hdr);
 
-  if (msg != NULL) {
-    size_t msg_len = strlen(msg);
-    GPR_ASSERT(msg_len <= UINT32_MAX);
-    uint32_t msg_len_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)msg_len, 0);
-    message_pfx = grpc_slice_malloc(14 + msg_len_len);
-    p = GRPC_SLICE_START_PTR(message_pfx);
-    *p++ = 0x00; /* literal header, not indexed */
-    *p++ = 12;   /* len(grpc-message) */
-    *p++ = 'g';
-    *p++ = 'r';
-    *p++ = 'p';
-    *p++ = 'c';
-    *p++ = '-';
-    *p++ = 'm';
-    *p++ = 'e';
-    *p++ = 's';
-    *p++ = 's';
-    *p++ = 'a';
-    *p++ = 'g';
-    *p++ = 'e';
-    GRPC_CHTTP2_WRITE_VARINT((uint32_t)msg_len, 0, 0, p, (uint32_t)msg_len_len);
-    p += msg_len_len;
-    GPR_ASSERT(p == GRPC_SLICE_END_PTR(message_pfx));
-    len += (uint32_t)GRPC_SLICE_LENGTH(message_pfx);
-    len += (uint32_t)msg_len;
-  }
-
-  hdr = grpc_slice_malloc(9);
+  size_t msg_len = GRPC_SLICE_LENGTH(slice);
+  GPR_ASSERT(msg_len <= UINT32_MAX);
+  uint32_t msg_len_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)msg_len, 1);
+  message_pfx = GRPC_SLICE_MALLOC(14 + msg_len_len);
+  p = GRPC_SLICE_START_PTR(message_pfx);
+  *p++ = 0x00; /* literal header, not indexed */
+  *p++ = 12;   /* len(grpc-message) */
+  *p++ = 'g';
+  *p++ = 'r';
+  *p++ = 'p';
+  *p++ = 'c';
+  *p++ = '-';
+  *p++ = 'm';
+  *p++ = 'e';
+  *p++ = 's';
+  *p++ = 's';
+  *p++ = 'a';
+  *p++ = 'g';
+  *p++ = 'e';
+  GRPC_CHTTP2_WRITE_VARINT((uint32_t)msg_len, 1, 0, p, (uint32_t)msg_len_len);
+  p += msg_len_len;
+  GPR_ASSERT(p == GRPC_SLICE_END_PTR(message_pfx));
+  len += (uint32_t)GRPC_SLICE_LENGTH(message_pfx);
+  len += (uint32_t)msg_len;
+
+  hdr = GRPC_SLICE_MALLOC(9);
   p = GRPC_SLICE_START_PTR(hdr);
   *p++ = (uint8_t)(len >> 16);
   *p++ = (uint8_t)(len >> 8);
@@ -1842,11 +2089,13 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
   GPR_ASSERT(p == GRPC_SLICE_END_PTR(hdr));
 
   grpc_slice_buffer_add(&t->qbuf, hdr);
-  grpc_slice_buffer_add(&t->qbuf, status_hdr);
-  if (msg != NULL) {
-    grpc_slice_buffer_add(&t->qbuf, message_pfx);
-    grpc_slice_buffer_add(&t->qbuf, grpc_slice_from_copied_string(msg));
+  if (!s->sent_initial_metadata) {
+    grpc_slice_buffer_add(&t->qbuf, http_status_hdr);
+    grpc_slice_buffer_add(&t->qbuf, content_type_hdr);
   }
+  grpc_slice_buffer_add(&t->qbuf, status_hdr);
+  grpc_slice_buffer_add(&t->qbuf, message_pfx);
+  grpc_slice_buffer_add(&t->qbuf, grpc_slice_ref_internal(slice));
   grpc_slice_buffer_add(
       &t->qbuf, grpc_chttp2_rst_stream_create(s->id, GRPC_HTTP2_NO_ERROR,
                                               &s->stats.outgoing));
@@ -1901,6 +2150,7 @@ static void update_bdp(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
             (int)bdp);
   }
   push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, bdp);
+  push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE, bdp);
 }
 
 static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx,
@@ -1921,9 +2171,9 @@ static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx,
   if (parse_error == GRPC_ERROR_NONE &&
       (parse_error = grpc_http_parser_eof(&parser)) == GRPC_ERROR_NONE) {
     error = grpc_error_set_int(
-        grpc_error_set_int(
-            GRPC_ERROR_CREATE("Trying to connect an http1.x server"),
-            GRPC_ERROR_INT_HTTP_STATUS, response.status),
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                               "Trying to connect an http1.x server"),
+                           GRPC_ERROR_INT_HTTP_STATUS, response.status),
         GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
   }
   GRPC_ERROR_UNREF(parse_error);
@@ -1944,9 +2194,10 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
 
   grpc_error *err = error;
   if (err != GRPC_ERROR_NONE) {
-    err = grpc_error_set_int(
-        GRPC_ERROR_CREATE_REFERENCING("Endpoint read failed", &err, 1),
-        GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state);
+    err = grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                                 "Endpoint read failed", &err, 1),
+                             GRPC_ERROR_INT_OCCURRED_DURING_WRITE,
+                             t->write_state);
   }
   GPR_SWAP(grpc_error *, err, error);
   GRPC_ERROR_UNREF(err);
@@ -1967,8 +2218,8 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
     if (errors[1] != GRPC_ERROR_NONE) {
       errors[2] = try_http_parsing(exec_ctx, t);
       GRPC_ERROR_UNREF(error);
-      error = GRPC_ERROR_CREATE_REFERENCING("Failed parsing HTTP/2", errors,
-                                            GPR_ARRAY_SIZE(errors));
+      error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+          "Failed parsing HTTP/2", errors, GPR_ARRAY_SIZE(errors));
     }
     for (i = 0; i < GPR_ARRAY_SIZE(errors); i++) {
       GRPC_ERROR_UNREF(errors[i]);
@@ -1993,7 +2244,7 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
   GPR_TIMER_BEGIN("post_reading_action_locked", 0);
   bool keep_reading = false;
   if (error == GRPC_ERROR_NONE && t->closed) {
-    error = GRPC_ERROR_CREATE("Transport closed");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport closed");
   }
   if (error != GRPC_ERROR_NONE) {
     close_transport_locked(exec_ctx, t, GRPC_ERROR_REF(error));
@@ -2057,6 +2308,10 @@ static void start_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
   if (grpc_http_trace) {
     gpr_log(GPR_DEBUG, "%s: Start BDP ping", t->peer_string);
   }
+  /* Reset the keepalive ping timer */
+  if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING) {
+    grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer);
+  }
   grpc_bdp_estimator_start_ping(&t->bdp_estimator);
 }
 
@@ -2071,12 +2326,53 @@ static void finish_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
   GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "bdp_ping");
 }
 
+void grpc_chttp2_config_default_keepalive_args(grpc_channel_args *args,
+                                               bool is_client) {
+  size_t i;
+  if (args) {
+    for (i = 0; i < args->num_args; i++) {
+      if (0 == strcmp(args->args[i].key, GRPC_ARG_KEEPALIVE_TIME_MS)) {
+        const int value = grpc_channel_arg_get_integer(
+            &args->args[i],
+            (grpc_integer_options){g_default_client_keepalive_time_ms, 1,
+                                   INT_MAX});
+        if (is_client) {
+          g_default_client_keepalive_time_ms = value;
+        } else {
+          g_default_server_keepalive_time_ms = value;
+        }
+      } else if (0 ==
+                 strcmp(args->args[i].key, GRPC_ARG_KEEPALIVE_TIMEOUT_MS)) {
+        const int value = grpc_channel_arg_get_integer(
+            &args->args[i],
+            (grpc_integer_options){g_default_client_keepalive_timeout_ms, 0,
+                                   INT_MAX});
+        if (is_client) {
+          g_default_client_keepalive_timeout_ms = value;
+        } else {
+          g_default_server_keepalive_timeout_ms = value;
+        }
+      } else if (0 == strcmp(args->args[i].key,
+                             GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS)) {
+        g_default_keepalive_permit_without_calls =
+            (uint32_t)grpc_channel_arg_get_integer(
+                &args->args[i],
+                (grpc_integer_options){g_default_keepalive_permit_without_calls,
+                                       0, 1});
+      }
+    }
+  }
+}
+
 static void init_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
                                        grpc_error *error) {
   grpc_chttp2_transport *t = arg;
   GPR_ASSERT(t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING);
-  if (error == GRPC_ERROR_NONE && !(t->destroying || t->closed)) {
-    if (t->keepalive_permit_without_calls || t->stream_map.count > 0) {
+  if (t->destroying || t->closed) {
+    t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING;
+  } else if (error == GRPC_ERROR_NONE) {
+    if (t->keepalive_permit_without_calls ||
+        grpc_chttp2_stream_map_size(&t->stream_map) > 0) {
       t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_PINGING;
       GRPC_CHTTP2_REF_TRANSPORT(t, "keepalive ping end");
       send_ping_locked(exec_ctx, t, GRPC_CHTTP2_PING_ON_NEXT_WRITE,
@@ -2089,6 +2385,13 @@ static void init_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
           gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), t->keepalive_time),
           &t->init_keepalive_ping_locked, gpr_now(GPR_CLOCK_MONOTONIC));
     }
+  } else if (error == GRPC_ERROR_CANCELLED) {
+    /* The keepalive ping timer may be cancelled by bdp */
+    GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping");
+    grpc_timer_init(
+        exec_ctx, &t->keepalive_ping_timer,
+        gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), t->keepalive_time),
+        &t->init_keepalive_ping_locked, gpr_now(GPR_CLOCK_MONOTONIC));
   }
   GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "init keepalive ping");
 }
@@ -2114,9 +2417,7 @@ static void finish_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
       grpc_timer_init(
           exec_ctx, &t->keepalive_ping_timer,
           gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), t->keepalive_time),
-          grpc_closure_create(init_keepalive_ping_locked, t,
-                              grpc_combiner_scheduler(t->combiner, false)),
-          gpr_now(GPR_CLOCK_MONOTONIC));
+          &t->init_keepalive_ping_locked, gpr_now(GPR_CLOCK_MONOTONIC));
     }
   }
   GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keepalive ping end");
@@ -2128,12 +2429,12 @@ static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg,
   if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) {
     if (error == GRPC_ERROR_NONE) {
       t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING;
-      close_transport_locked(exec_ctx, t,
-                             GRPC_ERROR_CREATE("keepalive watchdog timeout"));
+      close_transport_locked(exec_ctx, t, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                              "keepalive watchdog timeout"));
     }
   } else {
-    /** The watchdog timer should have been cancelled by
-        finish_keepalive_ping_locked. */
+    /* The watchdog timer should have been cancelled by
+     * finish_keepalive_ping_locked. */
     if (error != GRPC_ERROR_CANCELLED) {
       gpr_log(GPR_ERROR, "keepalive_ping_end state error: %d (expect: %d)",
               t->keepalive_state, GRPC_CHTTP2_KEEPALIVE_STATE_PINGING);
@@ -2176,12 +2477,28 @@ static void set_pollset_set(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
  * BYTE STREAM
  */
 
+static void reset_byte_stream(grpc_exec_ctx *exec_ctx, void *arg,
+                              grpc_error *error) {
+  grpc_chttp2_stream *s = (grpc_chttp2_stream *)arg;
+
+  s->pending_byte_stream = false;
+  if (error == GRPC_ERROR_NONE) {
+    grpc_chttp2_maybe_complete_recv_message(exec_ctx, s->t, s);
+    grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, s->t, s);
+  } else {
+    GPR_ASSERT(error != GRPC_ERROR_NONE);
+    grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_REF(error));
+    s->on_next = NULL;
+    GRPC_ERROR_UNREF(s->byte_stream_error);
+    s->byte_stream_error = GRPC_ERROR_NONE;
+    grpc_chttp2_cancel_stream(exec_ctx, s->t, s, GRPC_ERROR_REF(error));
+    s->byte_stream_error = error;
+  }
+}
+
 static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx,
                                        grpc_chttp2_incoming_byte_stream *bs) {
   if (gpr_unref(&bs->refs)) {
-    GRPC_ERROR_UNREF(bs->error);
-    grpc_slice_buffer_destroy_internal(exec_ctx, &bs->slices);
-    gpr_mu_destroy(&bs->slice_mu);
     gpr_free(bs);
   }
 }
@@ -2241,47 +2558,91 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx,
   grpc_chttp2_transport *t = bs->transport;
   grpc_chttp2_stream *s = bs->stream;
 
-  if (bs->is_tail) {
-    gpr_mu_lock(&bs->slice_mu);
-    size_t cur_length = bs->slices.length;
-    gpr_mu_unlock(&bs->slice_mu);
-    incoming_byte_stream_update_flow_control(
-        exec_ctx, t, s, bs->next_action.max_size_hint, cur_length);
-  }
-  gpr_mu_lock(&bs->slice_mu);
-  if (bs->slices.count > 0) {
-    *bs->next_action.slice = grpc_slice_buffer_take_first(&bs->slices);
-    grpc_closure_run(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE);
-  } else if (bs->error != GRPC_ERROR_NONE) {
-    grpc_closure_run(exec_ctx, bs->next_action.on_complete,
-                     GRPC_ERROR_REF(bs->error));
+  size_t cur_length = s->frame_storage.length;
+  incoming_byte_stream_update_flow_control(
+      exec_ctx, t, s, bs->next_action.max_size_hint, cur_length);
+
+  GPR_ASSERT(s->unprocessed_incoming_frames_buffer.length == 0);
+  if (s->frame_storage.length > 0) {
+    grpc_slice_buffer_swap(&s->frame_storage,
+                           &s->unprocessed_incoming_frames_buffer);
+    grpc_closure_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE);
+  } else if (s->byte_stream_error != GRPC_ERROR_NONE) {
+    grpc_closure_sched(exec_ctx, bs->next_action.on_complete,
+                       GRPC_ERROR_REF(s->byte_stream_error));
+    if (s->data_parser.parsing_frame != NULL) {
+      incoming_byte_stream_unref(exec_ctx, s->data_parser.parsing_frame);
+      s->data_parser.parsing_frame = NULL;
+    }
+  } else if (s->read_closed) {
+    if (bs->remaining_bytes != 0) {
+      s->byte_stream_error =
+          GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message");
+      grpc_closure_sched(exec_ctx, bs->next_action.on_complete,
+                         GRPC_ERROR_REF(s->byte_stream_error));
+      if (s->data_parser.parsing_frame != NULL) {
+        incoming_byte_stream_unref(exec_ctx, s->data_parser.parsing_frame);
+        s->data_parser.parsing_frame = NULL;
+      }
+    } else {
+      /* Should never reach here. */
+      GPR_ASSERT(false);
+    }
   } else {
-    bs->on_next = bs->next_action.on_complete;
-    bs->next = bs->next_action.slice;
+    s->on_next = bs->next_action.on_complete;
   }
-  gpr_mu_unlock(&bs->slice_mu);
   incoming_byte_stream_unref(exec_ctx, bs);
 }
 
-static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx,
-                                     grpc_byte_stream *byte_stream,
-                                     grpc_slice *slice, size_t max_size_hint,
-                                     grpc_closure *on_complete) {
+static bool incoming_byte_stream_next(grpc_exec_ctx *exec_ctx,
+                                      grpc_byte_stream *byte_stream,
+                                      size_t max_size_hint,
+                                      grpc_closure *on_complete) {
   GPR_TIMER_BEGIN("incoming_byte_stream_next", 0);
   grpc_chttp2_incoming_byte_stream *bs =
       (grpc_chttp2_incoming_byte_stream *)byte_stream;
-  gpr_ref(&bs->refs);
-  bs->next_action.slice = slice;
-  bs->next_action.max_size_hint = max_size_hint;
-  bs->next_action.on_complete = on_complete;
-  grpc_closure_sched(
-      exec_ctx,
-      grpc_closure_init(
-          &bs->next_action.closure, incoming_byte_stream_next_locked, bs,
-          grpc_combiner_scheduler(bs->transport->combiner, false)),
-      GRPC_ERROR_NONE);
-  GPR_TIMER_END("incoming_byte_stream_next", 0);
-  return 0;
+  grpc_chttp2_stream *s = bs->stream;
+  if (s->unprocessed_incoming_frames_buffer.length > 0) {
+    GPR_TIMER_END("incoming_byte_stream_next", 0);
+    return true;
+  } else {
+    gpr_ref(&bs->refs);
+    bs->next_action.max_size_hint = max_size_hint;
+    bs->next_action.on_complete = on_complete;
+    grpc_closure_sched(
+        exec_ctx,
+        grpc_closure_init(
+            &bs->next_action.closure, incoming_byte_stream_next_locked, bs,
+            grpc_combiner_scheduler(bs->transport->combiner, false)),
+        GRPC_ERROR_NONE);
+    GPR_TIMER_END("incoming_byte_stream_next", 0);
+    return false;
+  }
+}
+
+static grpc_error *incoming_byte_stream_pull(grpc_exec_ctx *exec_ctx,
+                                             grpc_byte_stream *byte_stream,
+                                             grpc_slice *slice) {
+  GPR_TIMER_BEGIN("incoming_byte_stream_pull", 0);
+  grpc_chttp2_incoming_byte_stream *bs =
+      (grpc_chttp2_incoming_byte_stream *)byte_stream;
+  grpc_chttp2_stream *s = bs->stream;
+
+  if (s->unprocessed_incoming_frames_buffer.length > 0) {
+    grpc_error *error = grpc_deframe_unprocessed_incoming_frames(
+        exec_ctx, &s->data_parser, s, &s->unprocessed_incoming_frames_buffer,
+        slice, NULL);
+    if (error != GRPC_ERROR_NONE) {
+      return error;
+    }
+  } else {
+    grpc_error *error =
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message");
+    grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error));
+    return error;
+  }
+  GPR_TIMER_END("incoming_byte_stream_pull", 0);
+  return GRPC_ERROR_NONE;
 }
 
 static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
@@ -2291,9 +2652,14 @@ static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx,
                                                 void *byte_stream,
                                                 grpc_error *error_ignored) {
   grpc_chttp2_incoming_byte_stream *bs = byte_stream;
+  grpc_chttp2_stream *s = bs->stream;
+  grpc_chttp2_transport *t = s->t;
+
   GPR_ASSERT(bs->base.destroy == incoming_byte_stream_destroy);
-  decrement_active_streams_locked(exec_ctx, bs->transport, bs->stream);
   incoming_byte_stream_unref(exec_ctx, bs);
+  s->pending_byte_stream = false;
+  grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
+  grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
 }
 
 static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
@@ -2313,49 +2679,53 @@ static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
 static void incoming_byte_stream_publish_error(
     grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
     grpc_error *error) {
+  grpc_chttp2_stream *s = bs->stream;
+
   GPR_ASSERT(error != GRPC_ERROR_NONE);
-  grpc_closure_sched(exec_ctx, bs->on_next, GRPC_ERROR_REF(error));
-  bs->on_next = NULL;
-  GRPC_ERROR_UNREF(bs->error);
+  grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_REF(error));
+  s->on_next = NULL;
+  GRPC_ERROR_UNREF(s->byte_stream_error);
+  s->byte_stream_error = GRPC_ERROR_REF(error);
   grpc_chttp2_cancel_stream(exec_ctx, bs->transport, bs->stream,
                             GRPC_ERROR_REF(error));
-  bs->error = error;
 }
 
-void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx,
-                                           grpc_chttp2_incoming_byte_stream *bs,
-                                           grpc_slice slice) {
-  gpr_mu_lock(&bs->slice_mu);
+grpc_error *grpc_chttp2_incoming_byte_stream_push(
+    grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
+    grpc_slice slice, grpc_slice *slice_out) {
+  grpc_chttp2_stream *s = bs->stream;
+
   if (bs->remaining_bytes < GRPC_SLICE_LENGTH(slice)) {
-    incoming_byte_stream_publish_error(
-        exec_ctx, bs, GRPC_ERROR_CREATE("Too many bytes in stream"));
+    grpc_error *error =
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many bytes in stream");
+
+    grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error));
+    grpc_slice_unref_internal(exec_ctx, slice);
+    return error;
   } else {
     bs->remaining_bytes -= (uint32_t)GRPC_SLICE_LENGTH(slice);
-    if (bs->on_next != NULL) {
-      *bs->next = slice;
-      grpc_closure_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE);
-      bs->on_next = NULL;
-    } else {
-      grpc_slice_buffer_add(&bs->slices, slice);
+    if (slice_out != NULL) {
+      *slice_out = slice;
     }
+    return GRPC_ERROR_NONE;
   }
-  gpr_mu_unlock(&bs->slice_mu);
 }
 
-void grpc_chttp2_incoming_byte_stream_finished(
+grpc_error *grpc_chttp2_incoming_byte_stream_finished(
     grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
-    grpc_error *error) {
+    grpc_error *error, bool reset_on_error) {
+  grpc_chttp2_stream *s = bs->stream;
+
   if (error == GRPC_ERROR_NONE) {
-    gpr_mu_lock(&bs->slice_mu);
     if (bs->remaining_bytes != 0) {
-      error = GRPC_ERROR_CREATE("Truncated message");
+      error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message");
     }
-    gpr_mu_unlock(&bs->slice_mu);
   }
-  if (error != GRPC_ERROR_NONE) {
-    incoming_byte_stream_publish_error(exec_ctx, bs, error);
+  if (error != GRPC_ERROR_NONE && reset_on_error) {
+    grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error));
   }
   incoming_byte_stream_unref(exec_ctx, bs);
+  return error;
 }
 
 grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create(
@@ -2367,26 +2737,12 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create(
   incoming_byte_stream->remaining_bytes = frame_size;
   incoming_byte_stream->base.flags = flags;
   incoming_byte_stream->base.next = incoming_byte_stream_next;
+  incoming_byte_stream->base.pull = incoming_byte_stream_pull;
   incoming_byte_stream->base.destroy = incoming_byte_stream_destroy;
-  gpr_mu_init(&incoming_byte_stream->slice_mu);
   gpr_ref_init(&incoming_byte_stream->refs, 2);
-  incoming_byte_stream->next_message = NULL;
   incoming_byte_stream->transport = t;
   incoming_byte_stream->stream = s;
-  gpr_ref(&incoming_byte_stream->stream->active_streams);
-  grpc_slice_buffer_init(&incoming_byte_stream->slices);
-  incoming_byte_stream->on_next = NULL;
-  incoming_byte_stream->is_tail = 1;
-  incoming_byte_stream->error = GRPC_ERROR_NONE;
-  grpc_chttp2_incoming_frame_queue *q = &s->incoming_frames;
-  if (q->head == NULL) {
-    q->head = incoming_byte_stream;
-  } else {
-    q->tail->is_tail = 0;
-    q->tail->next_message = incoming_byte_stream;
-  }
-  q->tail = incoming_byte_stream;
-  grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
+  s->byte_stream_error = GRPC_ERROR_NONE;
   return incoming_byte_stream;
 }
 
@@ -2428,9 +2784,9 @@ static void benign_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg,
               t->peer_string);
     }
     send_goaway(exec_ctx, t,
-                grpc_error_set_int(GRPC_ERROR_CREATE("Buffers full"),
-                                   GRPC_ERROR_INT_HTTP2_ERROR,
-                                   GRPC_HTTP2_ENHANCE_YOUR_CALM));
+                grpc_error_set_int(
+                    GRPC_ERROR_CREATE_FROM_STATIC_STRING("Buffers full"),
+                    GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_ENHANCE_YOUR_CALM));
   } else if (error == GRPC_ERROR_NONE && grpc_resource_quota_trace) {
     gpr_log(GPR_DEBUG,
             "HTTP2: %s - skip benign reclamation, there are still %" PRIdPTR
@@ -2457,9 +2813,10 @@ static void destructive_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg,
               s->id);
     }
     grpc_chttp2_cancel_stream(
-        exec_ctx, t, s, grpc_error_set_int(GRPC_ERROR_CREATE("Buffers full"),
-                                           GRPC_ERROR_INT_HTTP2_ERROR,
-                                           GRPC_HTTP2_ENHANCE_YOUR_CALM));
+        exec_ctx, t, s,
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Buffers full"),
+                           GRPC_ERROR_INT_HTTP2_ERROR,
+                           GRPC_HTTP2_ENHANCE_YOUR_CALM));
     if (n > 1) {
       /* Since we cancel one stream per destructive reclamation, if
          there are more streams left, we can immediately post a new
diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c
index f9b9e1b309274d0831896f96e05de295b14c40a0..8cb8489794966dc89180d5cbea0994d672670aef 100644
--- a/src/core/ext/transport/chttp2/transport/frame_data.c
+++ b/src/core/ext/transport/chttp2/transport/frame_data.c
@@ -40,6 +40,7 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
 #include "src/core/ext/transport/chttp2/transport/internal.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/transport.h"
@@ -53,66 +54,36 @@ grpc_error *grpc_chttp2_data_parser_init(grpc_chttp2_data_parser *parser) {
 void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx,
                                      grpc_chttp2_data_parser *parser) {
   if (parser->parsing_frame != NULL) {
-    grpc_chttp2_incoming_byte_stream_finished(
-        exec_ctx, parser->parsing_frame, GRPC_ERROR_CREATE("Parser destroyed"));
+    GRPC_ERROR_UNREF(grpc_chttp2_incoming_byte_stream_finished(
+        exec_ctx, parser->parsing_frame,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Parser destroyed"), false));
   }
   GRPC_ERROR_UNREF(parser->error);
 }
 
 grpc_error *grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser *parser,
                                                 uint8_t flags,
-                                                uint32_t stream_id) {
+                                                uint32_t stream_id,
+                                                grpc_chttp2_stream *s) {
   if (flags & ~GRPC_CHTTP2_DATA_FLAG_END_STREAM) {
     char *msg;
     gpr_asprintf(&msg, "unsupported data flags: 0x%02x", flags);
-    grpc_error *err = grpc_error_set_int(
-        GRPC_ERROR_CREATE(msg), GRPC_ERROR_INT_STREAM_ID, (intptr_t)stream_id);
+    grpc_error *err =
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg),
+                           GRPC_ERROR_INT_STREAM_ID, (intptr_t)stream_id);
     gpr_free(msg);
     return err;
   }
 
   if (flags & GRPC_CHTTP2_DATA_FLAG_END_STREAM) {
-    parser->is_last_frame = 1;
+    s->received_last_frame = true;
   } else {
-    parser->is_last_frame = 0;
+    s->received_last_frame = false;
   }
 
   return GRPC_ERROR_NONE;
 }
 
-void grpc_chttp2_incoming_frame_queue_merge(
-    grpc_chttp2_incoming_frame_queue *head_dst,
-    grpc_chttp2_incoming_frame_queue *tail_src) {
-  if (tail_src->head == NULL) {
-    return;
-  }
-
-  if (head_dst->head == NULL) {
-    *head_dst = *tail_src;
-    memset(tail_src, 0, sizeof(*tail_src));
-    return;
-  }
-
-  head_dst->tail->next_message = tail_src->head;
-  head_dst->tail = tail_src->tail;
-  memset(tail_src, 0, sizeof(*tail_src));
-}
-
-grpc_byte_stream *grpc_chttp2_incoming_frame_queue_pop(
-    grpc_chttp2_incoming_frame_queue *q) {
-  grpc_byte_stream *out;
-  if (q->head == NULL) {
-    return NULL;
-  }
-  out = &q->head->base;
-  if (q->head == q->tail) {
-    memset(q, 0, sizeof(*q));
-  } else {
-    q->head = q->head->next_message;
-  }
-  return out;
-}
-
 void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf,
                              uint32_t write_bytes, int is_eof,
                              grpc_transport_one_way_stats *stats,
@@ -121,7 +92,7 @@ void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf,
   uint8_t *p;
   static const size_t header_size = 9;
 
-  hdr = grpc_slice_malloc(header_size);
+  hdr = GRPC_SLICE_MALLOC(header_size);
   p = GRPC_SLICE_START_PTR(hdr);
   GPR_ASSERT(write_bytes < (1 << 24));
   *p++ = (uint8_t)(write_bytes >> 16);
@@ -135,150 +106,221 @@ void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf,
   *p++ = (uint8_t)(id);
   grpc_slice_buffer_add(outbuf, hdr);
 
-  grpc_slice_buffer_move_first(inbuf, write_bytes, outbuf);
+  grpc_slice_buffer_move_first_no_ref(inbuf, write_bytes, outbuf);
 
   stats->framing_bytes += header_size;
   stats->data_bytes += write_bytes;
 }
 
-static grpc_error *parse_inner(grpc_exec_ctx *exec_ctx,
-                               grpc_chttp2_data_parser *p,
-                               grpc_chttp2_transport *t, grpc_chttp2_stream *s,
-                               grpc_slice slice) {
-  uint8_t *const beg = GRPC_SLICE_START_PTR(slice);
-  uint8_t *const end = GRPC_SLICE_END_PTR(slice);
-  uint8_t *cur = beg;
-  uint32_t message_flags;
-  grpc_chttp2_incoming_byte_stream *incoming_byte_stream;
-  char *msg;
+grpc_error *grpc_deframe_unprocessed_incoming_frames(
+    grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, grpc_chttp2_stream *s,
+    grpc_slice_buffer *slices, grpc_slice *slice_out,
+    grpc_byte_stream **stream_out) {
+  grpc_error *error = GRPC_ERROR_NONE;
+  grpc_chttp2_transport *t = s->t;
 
-  if (cur == end) {
-    return GRPC_ERROR_NONE;
-  }
+  while (slices->count > 0) {
+    uint8_t *beg = NULL;
+    uint8_t *end = NULL;
+    uint8_t *cur = NULL;
 
-  switch (p->state) {
-    case GRPC_CHTTP2_DATA_ERROR:
-      p->state = GRPC_CHTTP2_DATA_ERROR;
-      return GRPC_ERROR_REF(p->error);
-    fh_0:
-    case GRPC_CHTTP2_DATA_FH_0:
-      s->stats.incoming.framing_bytes++;
-      p->frame_type = *cur;
-      switch (p->frame_type) {
-        case 0:
-          p->is_frame_compressed = 0; /* GPR_FALSE */
-          break;
-        case 1:
-          p->is_frame_compressed = 1; /* GPR_TRUE */
-          break;
-        default:
-          gpr_asprintf(&msg, "Bad GRPC frame type 0x%02x", p->frame_type);
-          p->error = GRPC_ERROR_CREATE(msg);
-          p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID,
-                                        (intptr_t)s->id);
-          gpr_free(msg);
-          msg = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
-          p->error =
-              grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, msg);
-          gpr_free(msg);
-          p->error =
-              grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg);
-          p->state = GRPC_CHTTP2_DATA_ERROR;
-          return GRPC_ERROR_REF(p->error);
-      }
-      if (++cur == end) {
-        p->state = GRPC_CHTTP2_DATA_FH_1;
-        return GRPC_ERROR_NONE;
-      }
-    /* fallthrough */
-    case GRPC_CHTTP2_DATA_FH_1:
-      s->stats.incoming.framing_bytes++;
-      p->frame_size = ((uint32_t)*cur) << 24;
-      if (++cur == end) {
-        p->state = GRPC_CHTTP2_DATA_FH_2;
-        return GRPC_ERROR_NONE;
-      }
-    /* fallthrough */
-    case GRPC_CHTTP2_DATA_FH_2:
-      s->stats.incoming.framing_bytes++;
-      p->frame_size |= ((uint32_t)*cur) << 16;
-      if (++cur == end) {
-        p->state = GRPC_CHTTP2_DATA_FH_3;
-        return GRPC_ERROR_NONE;
-      }
-    /* fallthrough */
-    case GRPC_CHTTP2_DATA_FH_3:
-      s->stats.incoming.framing_bytes++;
-      p->frame_size |= ((uint32_t)*cur) << 8;
-      if (++cur == end) {
-        p->state = GRPC_CHTTP2_DATA_FH_4;
-        return GRPC_ERROR_NONE;
-      }
-    /* fallthrough */
-    case GRPC_CHTTP2_DATA_FH_4:
-      s->stats.incoming.framing_bytes++;
-      p->frame_size |= ((uint32_t)*cur);
-      p->state = GRPC_CHTTP2_DATA_FRAME;
-      ++cur;
-      message_flags = 0;
-      if (p->is_frame_compressed) {
-        message_flags |= GRPC_WRITE_INTERNAL_COMPRESS;
-      }
-      p->parsing_frame = incoming_byte_stream =
-          grpc_chttp2_incoming_byte_stream_create(exec_ctx, t, s, p->frame_size,
-                                                  message_flags);
-    /* fallthrough */
-    case GRPC_CHTTP2_DATA_FRAME:
-      if (cur == end) {
-        return GRPC_ERROR_NONE;
-      }
-      uint32_t remaining = (uint32_t)(end - cur);
-      if (remaining == p->frame_size) {
-        s->stats.incoming.data_bytes += p->frame_size;
-        grpc_chttp2_incoming_byte_stream_push(
-            exec_ctx, p->parsing_frame,
-            grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg)));
-        grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame,
-                                                  GRPC_ERROR_NONE);
-        p->parsing_frame = NULL;
-        p->state = GRPC_CHTTP2_DATA_FH_0;
-        return GRPC_ERROR_NONE;
-      } else if (remaining > p->frame_size) {
-        s->stats.incoming.data_bytes += p->frame_size;
-        grpc_chttp2_incoming_byte_stream_push(
-            exec_ctx, p->parsing_frame,
-            grpc_slice_sub(slice, (size_t)(cur - beg),
-                           (size_t)(cur + p->frame_size - beg)));
-        grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame,
-                                                  GRPC_ERROR_NONE);
-        p->parsing_frame = NULL;
-        cur += p->frame_size;
-        goto fh_0; /* loop */
-      } else {
-        GPR_ASSERT(remaining <= p->frame_size);
-        grpc_chttp2_incoming_byte_stream_push(
-            exec_ctx, p->parsing_frame,
-            grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg)));
-        p->frame_size -= remaining;
-        s->stats.incoming.data_bytes += remaining;
+    grpc_slice slice = grpc_slice_buffer_take_first(slices);
+
+    beg = GRPC_SLICE_START_PTR(slice);
+    end = GRPC_SLICE_END_PTR(slice);
+    cur = beg;
+    uint32_t message_flags;
+    char *msg;
+
+    if (cur == end) {
+      grpc_slice_unref_internal(exec_ctx, slice);
+      continue;
+    }
+
+    switch (p->state) {
+      case GRPC_CHTTP2_DATA_ERROR:
+        p->state = GRPC_CHTTP2_DATA_ERROR;
+        grpc_slice_unref_internal(exec_ctx, slice);
+        return GRPC_ERROR_REF(p->error);
+      case GRPC_CHTTP2_DATA_FH_0:
+        p->frame_type = *cur;
+        switch (p->frame_type) {
+          case 0:
+            p->is_frame_compressed = false; /* GPR_FALSE */
+            break;
+          case 1:
+            p->is_frame_compressed = true; /* GPR_TRUE */
+            break;
+          default:
+            gpr_asprintf(&msg, "Bad GRPC frame type 0x%02x", p->frame_type);
+            p->error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
+            p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID,
+                                          (intptr_t)s->id);
+            gpr_free(msg);
+            msg = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
+            p->error = grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES,
+                                          grpc_slice_from_copied_string(msg));
+            gpr_free(msg);
+            p->error =
+                grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg);
+            p->state = GRPC_CHTTP2_DATA_ERROR;
+            grpc_slice_unref_internal(exec_ctx, slice);
+            return GRPC_ERROR_REF(p->error);
+        }
+        if (++cur == end) {
+          p->state = GRPC_CHTTP2_DATA_FH_1;
+          grpc_slice_unref_internal(exec_ctx, slice);
+          continue;
+        }
+      /* fallthrough */
+      case GRPC_CHTTP2_DATA_FH_1:
+        p->frame_size = ((uint32_t)*cur) << 24;
+        if (++cur == end) {
+          p->state = GRPC_CHTTP2_DATA_FH_2;
+          grpc_slice_unref_internal(exec_ctx, slice);
+          continue;
+        }
+      /* fallthrough */
+      case GRPC_CHTTP2_DATA_FH_2:
+        p->frame_size |= ((uint32_t)*cur) << 16;
+        if (++cur == end) {
+          p->state = GRPC_CHTTP2_DATA_FH_3;
+          grpc_slice_unref_internal(exec_ctx, slice);
+          continue;
+        }
+      /* fallthrough */
+      case GRPC_CHTTP2_DATA_FH_3:
+        p->frame_size |= ((uint32_t)*cur) << 8;
+        if (++cur == end) {
+          p->state = GRPC_CHTTP2_DATA_FH_4;
+          grpc_slice_unref_internal(exec_ctx, slice);
+          continue;
+        }
+      /* fallthrough */
+      case GRPC_CHTTP2_DATA_FH_4:
+        GPR_ASSERT(stream_out != NULL);
+        GPR_ASSERT(p->parsing_frame == NULL);
+        p->frame_size |= ((uint32_t)*cur);
+        p->state = GRPC_CHTTP2_DATA_FRAME;
+        ++cur;
+        message_flags = 0;
+        if (p->is_frame_compressed) {
+          message_flags |= GRPC_WRITE_INTERNAL_COMPRESS;
+        }
+        p->parsing_frame = grpc_chttp2_incoming_byte_stream_create(
+            exec_ctx, t, s, p->frame_size, message_flags);
+        *stream_out = &p->parsing_frame->base;
+        if (p->parsing_frame->remaining_bytes == 0) {
+          GRPC_ERROR_UNREF(grpc_chttp2_incoming_byte_stream_finished(
+              exec_ctx, p->parsing_frame, GRPC_ERROR_NONE, true));
+          p->parsing_frame = NULL;
+          p->state = GRPC_CHTTP2_DATA_FH_0;
+        }
+        s->pending_byte_stream = true;
+
+        if (cur != end) {
+          grpc_slice_buffer_undo_take_first(
+              &s->unprocessed_incoming_frames_buffer,
+              grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg)));
+        }
+        grpc_slice_unref_internal(exec_ctx, slice);
         return GRPC_ERROR_NONE;
+      case GRPC_CHTTP2_DATA_FRAME: {
+        GPR_ASSERT(p->parsing_frame != NULL);
+        GPR_ASSERT(slice_out != NULL);
+        if (cur == end) {
+          grpc_slice_unref_internal(exec_ctx, slice);
+          continue;
+        }
+        uint32_t remaining = (uint32_t)(end - cur);
+        if (remaining == p->frame_size) {
+          if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_push(
+                                      exec_ctx, p->parsing_frame,
+                                      grpc_slice_sub(slice, (size_t)(cur - beg),
+                                                     (size_t)(end - beg)),
+                                      slice_out))) {
+            grpc_slice_unref_internal(exec_ctx, slice);
+            return error;
+          }
+          if (GRPC_ERROR_NONE !=
+              (error = grpc_chttp2_incoming_byte_stream_finished(
+                   exec_ctx, p->parsing_frame, GRPC_ERROR_NONE, true))) {
+            grpc_slice_unref_internal(exec_ctx, slice);
+            return error;
+          }
+          p->parsing_frame = NULL;
+          p->state = GRPC_CHTTP2_DATA_FH_0;
+          grpc_slice_unref_internal(exec_ctx, slice);
+          return GRPC_ERROR_NONE;
+        } else if (remaining < p->frame_size) {
+          if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_push(
+                                      exec_ctx, p->parsing_frame,
+                                      grpc_slice_sub(slice, (size_t)(cur - beg),
+                                                     (size_t)(end - beg)),
+                                      slice_out))) {
+            return error;
+          }
+          p->frame_size -= remaining;
+          grpc_slice_unref_internal(exec_ctx, slice);
+          return GRPC_ERROR_NONE;
+        } else {
+          GPR_ASSERT(remaining > p->frame_size);
+          if (GRPC_ERROR_NONE !=
+              (grpc_chttp2_incoming_byte_stream_push(
+                  exec_ctx, p->parsing_frame,
+                  grpc_slice_sub(slice, (size_t)(cur - beg),
+                                 (size_t)(cur + p->frame_size - beg)),
+                  slice_out))) {
+            grpc_slice_unref_internal(exec_ctx, slice);
+            return error;
+          }
+          if (GRPC_ERROR_NONE !=
+              (error = grpc_chttp2_incoming_byte_stream_finished(
+                   exec_ctx, p->parsing_frame, GRPC_ERROR_NONE, true))) {
+            grpc_slice_unref_internal(exec_ctx, slice);
+            return error;
+          }
+          p->parsing_frame = NULL;
+          p->state = GRPC_CHTTP2_DATA_FH_0;
+          cur += p->frame_size;
+          grpc_slice_buffer_undo_take_first(
+              &s->unprocessed_incoming_frames_buffer,
+              grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg)));
+          grpc_slice_unref_internal(exec_ctx, slice);
+          return GRPC_ERROR_NONE;
+        }
       }
+    }
   }
 
-  GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here"));
+  return GRPC_ERROR_NONE;
 }
 
 grpc_error *grpc_chttp2_data_parser_parse(grpc_exec_ctx *exec_ctx, void *parser,
                                           grpc_chttp2_transport *t,
                                           grpc_chttp2_stream *s,
                                           grpc_slice slice, int is_last) {
-  grpc_chttp2_data_parser *p = parser;
-  grpc_error *error = parse_inner(exec_ctx, p, t, s, slice);
+  /* grpc_error *error = parse_inner_buffer(exec_ctx, p, t, s, slice); */
+  s->stats.incoming.framing_bytes += GRPC_SLICE_LENGTH(slice);
+  if (!s->pending_byte_stream) {
+    grpc_slice_ref_internal(slice);
+    grpc_slice_buffer_add(&s->frame_storage, slice);
+    grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
+  } else if (s->on_next) {
+    GPR_ASSERT(s->frame_storage.length == 0);
+    grpc_slice_ref_internal(slice);
+    grpc_slice_buffer_add(&s->unprocessed_incoming_frames_buffer, slice);
+    grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_NONE);
+    s->on_next = NULL;
+  } else {
+    grpc_slice_ref_internal(slice);
+    grpc_slice_buffer_add(&s->frame_storage, slice);
+  }
 
-  if (is_last && p->is_last_frame) {
+  if (is_last && s->received_last_frame) {
     grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false,
                                    GRPC_ERROR_NONE);
   }
 
-  return error;
+  return GRPC_ERROR_NONE;
 }
diff --git a/src/core/ext/transport/chttp2/transport/frame_data.h b/src/core/ext/transport/chttp2/transport/frame_data.h
index 264ad1460856d78b0c0de055122afcdd13690f48..9ed4ad0f2184121fe638437b49f077ad0f2f36b9 100644
--- a/src/core/ext/transport/chttp2/transport/frame_data.h
+++ b/src/core/ext/transport/chttp2/transport/frame_data.h
@@ -56,28 +56,16 @@ typedef enum {
 typedef struct grpc_chttp2_incoming_byte_stream
     grpc_chttp2_incoming_byte_stream;
 
-typedef struct grpc_chttp2_incoming_frame_queue {
-  grpc_chttp2_incoming_byte_stream *head;
-  grpc_chttp2_incoming_byte_stream *tail;
-} grpc_chttp2_incoming_frame_queue;
-
 typedef struct {
   grpc_chttp2_stream_state state;
-  uint8_t is_last_frame;
   uint8_t frame_type;
   uint32_t frame_size;
   grpc_error *error;
 
-  int is_frame_compressed;
+  bool is_frame_compressed;
   grpc_chttp2_incoming_byte_stream *parsing_frame;
 } grpc_chttp2_data_parser;
 
-void grpc_chttp2_incoming_frame_queue_merge(
-    grpc_chttp2_incoming_frame_queue *head_dst,
-    grpc_chttp2_incoming_frame_queue *tail_src);
-grpc_byte_stream *grpc_chttp2_incoming_frame_queue_pop(
-    grpc_chttp2_incoming_frame_queue *q);
-
 /* initialize per-stream state for data frame parsing */
 grpc_error *grpc_chttp2_data_parser_init(grpc_chttp2_data_parser *parser);
 
@@ -87,7 +75,8 @@ void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx,
 /* start processing a new data frame */
 grpc_error *grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser *parser,
                                                 uint8_t flags,
-                                                uint32_t stream_id);
+                                                uint32_t stream_id,
+                                                grpc_chttp2_stream *s);
 
 /* handle a slice of a data frame - is_last indicates the last slice of a
    frame */
@@ -101,4 +90,9 @@ void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf,
                              grpc_transport_one_way_stats *stats,
                              grpc_slice_buffer *outbuf);
 
+grpc_error *grpc_deframe_unprocessed_incoming_frames(
+    grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, grpc_chttp2_stream *s,
+    grpc_slice_buffer *slices, grpc_slice *slice_out,
+    grpc_byte_stream **stream_out);
+
 #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_DATA_H */
diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.c b/src/core/ext/transport/chttp2/transport/frame_goaway.c
index d99d486c1bd6b1192d2a96af42e14416aa6b7e5c..0f1c8b0772f49c667dbf0008e3e74eabf7ef64a1 100644
--- a/src/core/ext/transport/chttp2/transport/frame_goaway.c
+++ b/src/core/ext/transport/chttp2/transport/frame_goaway.c
@@ -54,7 +54,7 @@ grpc_error *grpc_chttp2_goaway_parser_begin_frame(grpc_chttp2_goaway_parser *p,
   if (length < 8) {
     char *msg;
     gpr_asprintf(&msg, "goaway frame too short (%d bytes)", length);
-    grpc_error *err = GRPC_ERROR_CREATE(msg);
+    grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return err;
   }
@@ -156,13 +156,14 @@ grpc_error *grpc_chttp2_goaway_parser_parse(grpc_exec_ctx *exec_ctx,
       }
       return GRPC_ERROR_NONE;
   }
-  GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here"));
+  GPR_UNREACHABLE_CODE(
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here"));
 }
 
 void grpc_chttp2_goaway_append(uint32_t last_stream_id, uint32_t error_code,
                                grpc_slice debug_data,
                                grpc_slice_buffer *slice_buffer) {
-  grpc_slice header = grpc_slice_malloc(9 + 4 + 4);
+  grpc_slice header = GRPC_SLICE_MALLOC(9 + 4 + 4);
   uint8_t *p = GRPC_SLICE_START_PTR(header);
   uint32_t frame_length;
   GPR_ASSERT(GRPC_SLICE_LENGTH(debug_data) < UINT32_MAX - 4 - 4);
diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.c b/src/core/ext/transport/chttp2/transport/frame_ping.c
index f487533c4145376c751fedea9b211548fc800256..f09ca60739758c67befda894a0168be13368629c 100644
--- a/src/core/ext/transport/chttp2/transport/frame_ping.c
+++ b/src/core/ext/transport/chttp2/transport/frame_ping.c
@@ -40,8 +40,10 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
+static bool g_disable_ping_ack = false;
+
 grpc_slice grpc_chttp2_ping_create(uint8_t ack, uint64_t opaque_8bytes) {
-  grpc_slice slice = grpc_slice_malloc(9 + 8);
+  grpc_slice slice = GRPC_SLICE_MALLOC(9 + 8);
   uint8_t *p = GRPC_SLICE_START_PTR(slice);
 
   *p++ = 0;
@@ -71,7 +73,7 @@ grpc_error *grpc_chttp2_ping_parser_begin_frame(grpc_chttp2_ping_parser *parser,
   if (flags & 0xfe || length != 8) {
     char *msg;
     gpr_asprintf(&msg, "invalid ping: length=%d, flags=%02x", length, flags);
-    grpc_error *error = GRPC_ERROR_CREATE(msg);
+    grpc_error *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return error;
   }
@@ -91,7 +93,7 @@ grpc_error *grpc_chttp2_ping_parser_parse(grpc_exec_ctx *exec_ctx, void *parser,
   grpc_chttp2_ping_parser *p = parser;
 
   while (p->byte != 8 && cur != end) {
-    p->opaque_8bytes |= (((uint64_t)*cur) << (8 * p->byte));
+    p->opaque_8bytes |= (((uint64_t)*cur) << (56 - 8 * p->byte));
     cur++;
     p->byte++;
   }
@@ -101,15 +103,43 @@ grpc_error *grpc_chttp2_ping_parser_parse(grpc_exec_ctx *exec_ctx, void *parser,
     if (p->is_ack) {
       grpc_chttp2_ack_ping(exec_ctx, t, p->opaque_8bytes);
     } else {
-      if (t->ping_ack_count == t->ping_ack_capacity) {
-        t->ping_ack_capacity = GPR_MAX(t->ping_ack_capacity * 3 / 2, 3);
-        t->ping_acks = gpr_realloc(
-            t->ping_acks, t->ping_ack_capacity * sizeof(*t->ping_acks));
+      if (!t->is_client) {
+        gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
+        gpr_timespec next_allowed_ping =
+            gpr_time_add(t->ping_recv_state.last_ping_recv_time,
+                         t->ping_policy.min_ping_interval_without_data);
+
+        if (t->keepalive_permit_without_calls == 0 &&
+            grpc_chttp2_stream_map_size(&t->stream_map) == 0) {
+          /* According to RFC1122, the interval of TCP Keep-Alive is default to
+             no less than two hours. When there is no outstanding streams, we
+             restrict the number of PINGS equivalent to TCP Keep-Alive. */
+          next_allowed_ping =
+              gpr_time_add(t->ping_recv_state.last_ping_recv_time,
+                           gpr_time_from_seconds(7200, GPR_TIMESPAN));
+        }
+
+        if (gpr_time_cmp(next_allowed_ping, now) > 0) {
+          grpc_chttp2_add_ping_strike(exec_ctx, t);
+        }
+
+        t->ping_recv_state.last_ping_recv_time = now;
+      }
+      if (!g_disable_ping_ack) {
+        if (t->ping_ack_count == t->ping_ack_capacity) {
+          t->ping_ack_capacity = GPR_MAX(t->ping_ack_capacity * 3 / 2, 3);
+          t->ping_acks = gpr_realloc(
+              t->ping_acks, t->ping_ack_capacity * sizeof(*t->ping_acks));
+        }
+        t->ping_acks[t->ping_ack_count++] = p->opaque_8bytes;
+        grpc_chttp2_initiate_write(exec_ctx, t, false, "ping response");
       }
-      t->ping_acks[t->ping_ack_count++] = p->opaque_8bytes;
-      grpc_chttp2_initiate_write(exec_ctx, t, false, "ping response");
     }
   }
 
   return GRPC_ERROR_NONE;
 }
+
+void grpc_set_disable_ping_ack(bool disable_ping_ack) {
+  g_disable_ping_ack = disable_ping_ack;
+}
diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.h b/src/core/ext/transport/chttp2/transport/frame_ping.h
index ef642465d7ecb970137497a85a8f3e20f4252c08..01983d2b127ec66a4b4f100eb9467fe849d0e363 100644
--- a/src/core/ext/transport/chttp2/transport/frame_ping.h
+++ b/src/core/ext/transport/chttp2/transport/frame_ping.h
@@ -53,4 +53,7 @@ grpc_error *grpc_chttp2_ping_parser_parse(grpc_exec_ctx *exec_ctx, void *parser,
                                           grpc_chttp2_stream *s,
                                           grpc_slice slice, int is_last);
 
+/* Test-only function for disabling ping ack */
+void grpc_set_disable_ping_ack(bool disable_ping_ack);
+
 #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_PING_H */
diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c
index cb017e75f04b4942673a26f2e5249970b7c70559..e0caa50e92ef7b8feaa7c90b0148cece2aabc474 100644
--- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c
+++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c
@@ -44,7 +44,7 @@
 grpc_slice grpc_chttp2_rst_stream_create(uint32_t id, uint32_t code,
                                          grpc_transport_one_way_stats *stats) {
   static const size_t frame_size = 13;
-  grpc_slice slice = grpc_slice_malloc(frame_size);
+  grpc_slice slice = GRPC_SLICE_MALLOC(frame_size);
   stats->framing_bytes += frame_size;
   uint8_t *p = GRPC_SLICE_START_PTR(slice);
 
@@ -76,7 +76,7 @@ grpc_error *grpc_chttp2_rst_stream_parser_begin_frame(
     char *msg;
     gpr_asprintf(&msg, "invalid rst_stream: length=%d, flags=%02x", length,
                  flags);
-    grpc_error *err = GRPC_ERROR_CREATE(msg);
+    grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return err;
   }
@@ -112,8 +112,9 @@ grpc_error *grpc_chttp2_rst_stream_parser_parse(grpc_exec_ctx *exec_ctx,
       char *message;
       gpr_asprintf(&message, "Received RST_STREAM with error code %d", reason);
       error = grpc_error_set_int(
-          grpc_error_set_str(GRPC_ERROR_CREATE("RST_STREAM"),
-                             GRPC_ERROR_STR_GRPC_MESSAGE, message),
+          grpc_error_set_str(GRPC_ERROR_CREATE_FROM_STATIC_STRING("RST_STREAM"),
+                             GRPC_ERROR_STR_GRPC_MESSAGE,
+                             grpc_slice_from_copied_string(message)),
           GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)reason);
       gpr_free(message);
     }
diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.c b/src/core/ext/transport/chttp2/transport/frame_settings.c
index 82290e34cdeedaa75bd979a185639b168e139329..e3cd70d3f3bcbe7696361001df15e052f9a4f46a 100644
--- a/src/core/ext/transport/chttp2/transport/frame_settings.c
+++ b/src/core/ext/transport/chttp2/transport/frame_settings.c
@@ -46,29 +46,6 @@
 #include "src/core/lib/debug/trace.h"
 #include "src/core/lib/transport/http2_errors.h"
 
-#define MAX_MAX_HEADER_LIST_SIZE (1024 * 1024 * 1024)
-
-/* HTTP/2 mandated initial connection settings */
-const grpc_chttp2_setting_parameters
-    grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS] = {
-        {NULL, 0, 0, 0, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE,
-         GRPC_HTTP2_PROTOCOL_ERROR},
-        {"HEADER_TABLE_SIZE", 4096, 0, 0xffffffff,
-         GRPC_CHTTP2_CLAMP_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR},
-        {"ENABLE_PUSH", 1, 0, 1, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE,
-         GRPC_HTTP2_PROTOCOL_ERROR},
-        {"MAX_CONCURRENT_STREAMS", 0xffffffffu, 0, 0xffffffffu,
-         GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR},
-        {"INITIAL_WINDOW_SIZE", 65535, 0, 0x7fffffffu,
-         GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE,
-         GRPC_HTTP2_FLOW_CONTROL_ERROR},
-        {"MAX_FRAME_SIZE", 16384, 16384, 16777215,
-         GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR},
-        {"MAX_HEADER_LIST_SIZE", MAX_MAX_HEADER_LIST_SIZE, 0,
-         MAX_MAX_HEADER_LIST_SIZE, GRPC_CHTTP2_CLAMP_INVALID_VALUE,
-         GRPC_HTTP2_PROTOCOL_ERROR},
-};
-
 static uint8_t *fill_header(uint8_t *out, uint32_t length, uint8_t flags) {
   *out++ = (uint8_t)(length >> 16);
   *out++ = (uint8_t)(length >> 8);
@@ -93,14 +70,13 @@ grpc_slice grpc_chttp2_settings_create(uint32_t *old, const uint32_t *new,
     n += (new[i] != old[i] || (force_mask & (1u << i)) != 0);
   }
 
-  output = grpc_slice_malloc(9 + 6 * n);
+  output = GRPC_SLICE_MALLOC(9 + 6 * n);
   p = fill_header(GRPC_SLICE_START_PTR(output), 6 * n, 0);
 
   for (i = 0; i < count; i++) {
     if (new[i] != old[i] || (force_mask & (1u << i)) != 0) {
-      GPR_ASSERT(i);
-      *p++ = (uint8_t)(i >> 8);
-      *p++ = (uint8_t)(i);
+      *p++ = (uint8_t)(grpc_setting_id_to_wire_id[i] >> 8);
+      *p++ = (uint8_t)(grpc_setting_id_to_wire_id[i]);
       *p++ = (uint8_t)(new[i] >> 24);
       *p++ = (uint8_t)(new[i] >> 16);
       *p++ = (uint8_t)(new[i] >> 8);
@@ -115,7 +91,7 @@ grpc_slice grpc_chttp2_settings_create(uint32_t *old, const uint32_t *new,
 }
 
 grpc_slice grpc_chttp2_settings_ack_create(void) {
-  grpc_slice output = grpc_slice_malloc(9);
+  grpc_slice output = GRPC_SLICE_MALLOC(9);
   fill_header(GRPC_SLICE_START_PTR(output), 0, GRPC_CHTTP2_FLAG_ACK);
   return output;
 }
@@ -131,13 +107,16 @@ grpc_error *grpc_chttp2_settings_parser_begin_frame(
   if (flags == GRPC_CHTTP2_FLAG_ACK) {
     parser->is_ack = 1;
     if (length != 0) {
-      return GRPC_ERROR_CREATE("non-empty settings ack frame received");
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "non-empty settings ack frame received");
     }
     return GRPC_ERROR_NONE;
   } else if (flags != 0) {
-    return GRPC_ERROR_CREATE("invalid flags on settings frame");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "invalid flags on settings frame");
   } else if (length % 6 != 0) {
-    return GRPC_ERROR_CREATE("settings frames must be a multiple of six bytes");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "settings frames must be a multiple of six bytes");
   } else {
     return GRPC_ERROR_NONE;
   }
@@ -151,6 +130,7 @@ grpc_error *grpc_chttp2_settings_parser_parse(grpc_exec_ctx *exec_ctx, void *p,
   const uint8_t *cur = GRPC_SLICE_START_PTR(slice);
   const uint8_t *end = GRPC_SLICE_END_PTR(slice);
   char *msg;
+  grpc_chttp2_setting_id id;
 
   if (parser->is_ack) {
     return GRPC_ERROR_NONE;
@@ -213,9 +193,9 @@ grpc_error *grpc_chttp2_settings_parser_parse(grpc_exec_ctx *exec_ctx, void *p,
         parser->value |= *cur;
         cur++;
 
-        if (parser->id > 0 && parser->id < GRPC_CHTTP2_NUM_SETTINGS) {
+        if (grpc_wire_id_to_setting_id(parser->id, &id)) {
           const grpc_chttp2_setting_parameters *sp =
-              &grpc_chttp2_settings_parameters[parser->id];
+              &grpc_chttp2_settings_parameters[id];
           if (parser->value < sp->min_value || parser->value > sp->max_value) {
             switch (sp->invalid_value_behavior) {
               case GRPC_CHTTP2_CLAMP_INVALID_VALUE:
@@ -229,24 +209,24 @@ grpc_error *grpc_chttp2_settings_parser_parse(grpc_exec_ctx *exec_ctx, void *p,
                     &t->qbuf);
                 gpr_asprintf(&msg, "invalid value %u passed for %s",
                              parser->value, sp->name);
-                grpc_error *err = GRPC_ERROR_CREATE(msg);
+                grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
                 gpr_free(msg);
                 return err;
             }
           }
-          if (parser->id == GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE &&
-              parser->incoming_settings[parser->id] != parser->value) {
+          if (id == GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE &&
+              parser->incoming_settings[id] != parser->value) {
             t->initial_window_update +=
-                (int64_t)parser->value - parser->incoming_settings[parser->id];
+                (int64_t)parser->value - parser->incoming_settings[id];
             if (grpc_http_trace) {
               gpr_log(GPR_DEBUG, "adding %d for initial_window change",
                       (int)t->initial_window_update);
             }
           }
-          parser->incoming_settings[parser->id] = parser->value;
+          parser->incoming_settings[id] = parser->value;
           if (grpc_http_trace) {
-            gpr_log(GPR_DEBUG, "CHTTP2:%s:%s: got setting %d = %d",
-                    t->is_client ? "CLI" : "SVR", t->peer_string, parser->id,
+            gpr_log(GPR_DEBUG, "CHTTP2:%s:%s: got setting %s = %d",
+                    t->is_client ? "CLI" : "SVR", t->peer_string, sp->name,
                     parser->value);
           }
         } else if (grpc_http_trace) {
diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.h b/src/core/ext/transport/chttp2/transport/frame_settings.h
index 44137798c064b0e3a3f5c980eb72c9bdb2498266..2a85d0dba7688296ee90629ca6fc52b4b2ebd56c 100644
--- a/src/core/ext/transport/chttp2/transport/frame_settings.h
+++ b/src/core/ext/transport/chttp2/transport/frame_settings.h
@@ -37,6 +37,7 @@
 #include <grpc/slice.h>
 #include <grpc/support/port_platform.h>
 #include "src/core/ext/transport/chttp2/transport/frame.h"
+#include "src/core/ext/transport/chttp2/transport/http2_settings.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
 
 typedef enum {
@@ -48,17 +49,6 @@ typedef enum {
   GRPC_CHTTP2_SPS_VAL3
 } grpc_chttp2_settings_parse_state;
 
-/* The things HTTP/2 defines as connection level settings */
-typedef enum {
-  GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE = 1,
-  GRPC_CHTTP2_SETTINGS_ENABLE_PUSH = 2,
-  GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS = 3,
-  GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 4,
-  GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE = 5,
-  GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 6,
-  GRPC_CHTTP2_NUM_SETTINGS
-} grpc_chttp2_setting_id;
-
 typedef struct {
   grpc_chttp2_settings_parse_state state;
   uint32_t *target_settings;
@@ -68,24 +58,6 @@ typedef struct {
   uint32_t incoming_settings[GRPC_CHTTP2_NUM_SETTINGS];
 } grpc_chttp2_settings_parser;
 
-typedef enum {
-  GRPC_CHTTP2_CLAMP_INVALID_VALUE,
-  GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE
-} grpc_chttp2_invalid_value_behavior;
-
-typedef struct {
-  const char *name;
-  uint32_t default_value;
-  uint32_t min_value;
-  uint32_t max_value;
-  grpc_chttp2_invalid_value_behavior invalid_value_behavior;
-  uint32_t error_value;
-} grpc_chttp2_setting_parameters;
-
-/* HTTP/2 mandated connection setting parameters */
-extern const grpc_chttp2_setting_parameters
-    grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS];
-
 /* Create a settings frame by diffing old & new, and updating old to be new */
 grpc_slice grpc_chttp2_settings_create(uint32_t *old, const uint32_t *newval,
                                        uint32_t force_mask, size_t count);
diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.c b/src/core/ext/transport/chttp2/transport/frame_window_update.c
index 8fa0bb471ae4a294f4323e646b40916483d2c908..8ed72dddca043e5d32387d8266e84a363d7bf600 100644
--- a/src/core/ext/transport/chttp2/transport/frame_window_update.c
+++ b/src/core/ext/transport/chttp2/transport/frame_window_update.c
@@ -41,7 +41,7 @@
 grpc_slice grpc_chttp2_window_update_create(
     uint32_t id, uint32_t window_update, grpc_transport_one_way_stats *stats) {
   static const size_t frame_size = 13;
-  grpc_slice slice = grpc_slice_malloc(frame_size);
+  grpc_slice slice = GRPC_SLICE_MALLOC(frame_size);
   stats->header_bytes += frame_size;
   uint8_t *p = GRPC_SLICE_START_PTR(slice);
 
@@ -70,7 +70,7 @@ grpc_error *grpc_chttp2_window_update_parser_begin_frame(
     char *msg;
     gpr_asprintf(&msg, "invalid window update: length=%d, flags=%02x", length,
                  flags);
-    grpc_error *err = GRPC_ERROR_CREATE(msg);
+    grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return err;
   }
@@ -102,7 +102,7 @@ grpc_error *grpc_chttp2_window_update_parser_parse(
     if (received_update == 0 || (received_update & 0x80000000u)) {
       char *msg;
       gpr_asprintf(&msg, "invalid window update bytes: %d", p->amount);
-      grpc_error *err = GRPC_ERROR_CREATE(msg);
+      grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
       gpr_free(msg);
       return err;
     }
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
index 84586cd99887416ca88c53dd383310a302c87a53..8fdd4ee77c1386dd83333400be782f7f171c3dc2 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
@@ -86,6 +86,7 @@ typedef struct {
   grpc_transport_one_way_stats *stats;
   /* maximum size of a frame */
   size_t max_frame_size;
+  bool use_true_binary_metadata;
 } framer_state;
 
 /* fills p (which is expected to be 9 bytes long) with a data frame header */
@@ -122,7 +123,7 @@ static void finish_frame(framer_state *st, int is_header_boundary,
    output before beginning */
 static void begin_frame(framer_state *st) {
   st->header_idx =
-      grpc_slice_buffer_add_indexed(st->output, grpc_slice_malloc(9));
+      grpc_slice_buffer_add_indexed(st->output, GRPC_SLICE_MALLOC(9));
   st->output_length_at_start_of_frame = st->output->length;
 }
 
@@ -290,86 +291,113 @@ static void emit_indexed(grpc_chttp2_hpack_compressor *c, uint32_t elem_index,
                            len);
 }
 
-static grpc_slice get_wire_value(grpc_mdelem elem, uint8_t *huffman_prefix) {
+typedef struct {
+  grpc_slice data;
+  uint8_t huffman_prefix;
+  bool insert_null_before_wire_value;
+} wire_value;
+
+static wire_value get_wire_value(grpc_mdelem elem, bool true_binary_enabled) {
   if (grpc_is_binary_header(GRPC_MDKEY(elem))) {
-    *huffman_prefix = 0x80;
-    return grpc_chttp2_base64_encode_and_huffman_compress(GRPC_MDVALUE(elem));
+    if (true_binary_enabled) {
+      return (wire_value){
+          .huffman_prefix = 0x00,
+          .insert_null_before_wire_value = true,
+          .data = grpc_slice_ref_internal(GRPC_MDVALUE(elem)),
+      };
+    } else {
+      return (wire_value){
+          .huffman_prefix = 0x80,
+          .insert_null_before_wire_value = false,
+          .data = grpc_chttp2_base64_encode_and_huffman_compress(
+              GRPC_MDVALUE(elem)),
+      };
+    }
+  } else {
+    /* TODO(ctiller): opportunistically compress non-binary headers */
+    return (wire_value){
+        .huffman_prefix = 0x00,
+        .insert_null_before_wire_value = false,
+        .data = grpc_slice_ref_internal(GRPC_MDVALUE(elem)),
+    };
   }
-  /* TODO(ctiller): opportunistically compress non-binary headers */
-  *huffman_prefix = 0x00;
-  return grpc_slice_ref_internal(GRPC_MDVALUE(elem));
+}
+
+static size_t wire_value_length(wire_value v) {
+  return GPR_SLICE_LENGTH(v.data) + v.insert_null_before_wire_value;
+}
+
+static void add_wire_value(framer_state *st, wire_value v) {
+  if (v.insert_null_before_wire_value) *add_tiny_header_data(st, 1) = 0;
+  add_header_data(st, v.data);
 }
 
 static void emit_lithdr_incidx(grpc_chttp2_hpack_compressor *c,
                                uint32_t key_index, grpc_mdelem elem,
                                framer_state *st) {
   uint32_t len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 2);
-  uint8_t huffman_prefix;
-  grpc_slice value_slice = get_wire_value(elem, &huffman_prefix);
-  size_t len_val = GRPC_SLICE_LENGTH(value_slice);
+  wire_value value = get_wire_value(elem, st->use_true_binary_metadata);
+  size_t len_val = wire_value_length(value);
   uint32_t len_val_len;
   GPR_ASSERT(len_val <= UINT32_MAX);
   len_val_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)len_val, 1);
   GRPC_CHTTP2_WRITE_VARINT(key_index, 2, 0x40,
                            add_tiny_header_data(st, len_pfx), len_pfx);
-  GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, huffman_prefix,
+  GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, value.huffman_prefix,
                            add_tiny_header_data(st, len_val_len), len_val_len);
-  add_header_data(st, value_slice);
+  add_wire_value(st, value);
 }
 
 static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor *c,
                               uint32_t key_index, grpc_mdelem elem,
                               framer_state *st) {
   uint32_t len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 4);
-  uint8_t huffman_prefix;
-  grpc_slice value_slice = get_wire_value(elem, &huffman_prefix);
-  size_t len_val = GRPC_SLICE_LENGTH(value_slice);
+  wire_value value = get_wire_value(elem, st->use_true_binary_metadata);
+  size_t len_val = wire_value_length(value);
   uint32_t len_val_len;
   GPR_ASSERT(len_val <= UINT32_MAX);
   len_val_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)len_val, 1);
   GRPC_CHTTP2_WRITE_VARINT(key_index, 4, 0x00,
                            add_tiny_header_data(st, len_pfx), len_pfx);
-  GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, huffman_prefix,
+  GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, value.huffman_prefix,
                            add_tiny_header_data(st, len_val_len), len_val_len);
-  add_header_data(st, value_slice);
+  add_wire_value(st, value);
 }
 
 static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor *c,
                                  grpc_mdelem elem, framer_state *st) {
   uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
-  uint8_t huffman_prefix;
-  grpc_slice value_slice = get_wire_value(elem, &huffman_prefix);
-  uint32_t len_val = (uint32_t)GRPC_SLICE_LENGTH(value_slice);
+  wire_value value = get_wire_value(elem, st->use_true_binary_metadata);
+  uint32_t len_val = (uint32_t)wire_value_length(value);
   uint32_t len_key_len = GRPC_CHTTP2_VARINT_LENGTH(len_key, 1);
   uint32_t len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1);
   GPR_ASSERT(len_key <= UINT32_MAX);
-  GPR_ASSERT(GRPC_SLICE_LENGTH(value_slice) <= UINT32_MAX);
+  GPR_ASSERT(wire_value_length(value) <= UINT32_MAX);
   *add_tiny_header_data(st, 1) = 0x40;
   GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00,
                            add_tiny_header_data(st, len_key_len), len_key_len);
   add_header_data(st, grpc_slice_ref_internal(GRPC_MDKEY(elem)));
-  GRPC_CHTTP2_WRITE_VARINT(len_val, 1, huffman_prefix,
+  GRPC_CHTTP2_WRITE_VARINT(len_val, 1, value.huffman_prefix,
                            add_tiny_header_data(st, len_val_len), len_val_len);
-  add_header_data(st, value_slice);
+  add_wire_value(st, value);
 }
 
 static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor *c,
                                 grpc_mdelem elem, framer_state *st) {
   uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
-  uint8_t huffman_prefix;
-  grpc_slice value_slice = get_wire_value(elem, &huffman_prefix);
-  uint32_t len_val = (uint32_t)GRPC_SLICE_LENGTH(value_slice);
+  wire_value value = get_wire_value(elem, st->use_true_binary_metadata);
+  uint32_t len_val = (uint32_t)wire_value_length(value);
   uint32_t len_key_len = GRPC_CHTTP2_VARINT_LENGTH(len_key, 1);
   uint32_t len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1);
   GPR_ASSERT(len_key <= UINT32_MAX);
-  GPR_ASSERT(GRPC_SLICE_LENGTH(value_slice) <= UINT32_MAX);
+  GPR_ASSERT(wire_value_length(value) <= UINT32_MAX);
   *add_tiny_header_data(st, 1) = 0x00;
   GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00,
                            add_tiny_header_data(st, len_key_len), len_key_len);
   add_header_data(st, grpc_slice_ref_internal(GRPC_MDKEY(elem)));
-  GRPC_CHTTP2_WRITE_VARINT(len_val, 1, huffman_prefix,
+  GRPC_CHTTP2_WRITE_VARINT(len_val, 1, value.huffman_prefix,
                            add_tiny_header_data(st, len_val_len), len_val_len);
-  add_header_data(st, value_slice);
+  add_wire_value(st, value);
 }
 
 static void emit_advertise_table_size_change(grpc_chttp2_hpack_compressor *c,
@@ -595,23 +623,22 @@ void grpc_chttp2_hpack_compressor_set_max_table_size(
 
 void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx,
                                grpc_chttp2_hpack_compressor *c,
-                               uint32_t stream_id,
-                               grpc_metadata_batch *metadata, int is_eof,
-                               size_t max_frame_size,
-                               grpc_transport_one_way_stats *stats,
+                               grpc_metadata_batch *metadata,
+                               const grpc_encode_header_options *options,
                                grpc_slice_buffer *outbuf) {
   framer_state st;
   grpc_linked_mdelem *l;
   gpr_timespec deadline;
 
-  GPR_ASSERT(stream_id != 0);
+  GPR_ASSERT(options->stream_id != 0);
 
   st.seen_regular_header = 0;
-  st.stream_id = stream_id;
+  st.stream_id = options->stream_id;
   st.output = outbuf;
   st.is_first_frame = 1;
-  st.stats = stats;
-  st.max_frame_size = max_frame_size;
+  st.stats = options->stats;
+  st.max_frame_size = options->max_frame_size;
+  st.use_true_binary_metadata = options->use_true_binary_metadata;
 
   /* Encode a metadata batch; store the returned values, representing
      a metadata element that needs to be unreffed back into the metadata
@@ -630,5 +657,5 @@ void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx,
     deadline_enc(exec_ctx, c, deadline, &st);
   }
 
-  finish_frame(&st, 1, is_eof);
+  finish_frame(&st, 1, options->is_eof);
 }
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
index 83ba5b1b3e0107b76a57e52cecb0c46868105cb8..6ce3209604601aade6836be8d699b9b49e47e464 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
@@ -90,11 +90,18 @@ void grpc_chttp2_hpack_compressor_set_max_table_size(
 void grpc_chttp2_hpack_compressor_set_max_usable_size(
     grpc_chttp2_hpack_compressor *c, uint32_t max_table_size);
 
+typedef struct {
+  uint32_t stream_id;
+  bool is_eof;
+  bool use_true_binary_metadata;
+  size_t max_frame_size;
+  grpc_transport_one_way_stats *stats;
+} grpc_encode_header_options;
+
 void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx,
-                               grpc_chttp2_hpack_compressor *c, uint32_t id,
-                               grpc_metadata_batch *metadata, int is_eof,
-                               size_t max_frame_size,
-                               grpc_transport_one_way_stats *stats,
+                               grpc_chttp2_hpack_compressor *c,
+                               grpc_metadata_batch *metadata,
+                               const grpc_encode_header_options *options,
                                grpc_slice_buffer *outbuf);
 
 #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_ENCODER_H */
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c
index 40f5120308c13de9d9818f894ca2e01acf8ee317..1846a85fc65f37bc5de2fe31b0cc9f73c066e31f 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c
@@ -38,11 +38,6 @@
 #include <stddef.h>
 #include <string.h>
 
-/* This is here for grpc_is_binary_header
- * TODO(murgatroid99): Remove this
- */
-#include <grpc/grpc.h>
-
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/port_platform.h>
@@ -55,13 +50,11 @@
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/http2_errors.h"
 
-/* TODO(ctiller): remove before submission */
-#include "src/core/lib/slice/slice_string_helpers.h"
-
 extern int grpc_http_trace;
 
 typedef enum {
   NOT_BINARY,
+  BINARY_BEGIN,
   B64_BYTE0,
   B64_BYTE1,
   B64_BYTE2,
@@ -693,7 +686,7 @@ static grpc_error *on_hdr(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_parser *p,
   }
   if (p->on_header == NULL) {
     GRPC_MDELEM_UNREF(exec_ctx, md);
-    return GRPC_ERROR_CREATE("on_header callback not set");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("on_header callback not set");
   }
   p->on_header(exec_ctx, p->on_header_user_data, md);
   return GRPC_ERROR_NONE;
@@ -810,7 +803,8 @@ static grpc_error *finish_indexed_field(grpc_exec_ctx *exec_ctx,
   grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
   if (GRPC_MDISNULL(md)) {
     return grpc_error_set_int(
-        grpc_error_set_int(GRPC_ERROR_CREATE("Invalid HPACK index received"),
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                               "Invalid HPACK index received"),
                            GRPC_ERROR_INT_INDEX, (intptr_t)p->index),
         GRPC_ERROR_INT_SIZE, (intptr_t)p->table.num_ents);
   }
@@ -1074,7 +1068,7 @@ static grpc_error *parse_max_tbl_size(grpc_exec_ctx *exec_ctx,
   if (p->dynamic_table_update_allowed == 0) {
     return parse_error(
         exec_ctx, p, cur, end,
-        GRPC_ERROR_CREATE(
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING(
             "More than two max table size changes in a single frame"));
   }
   p->dynamic_table_update_allowed--;
@@ -1092,7 +1086,7 @@ static grpc_error *parse_max_tbl_size_x(grpc_exec_ctx *exec_ctx,
   if (p->dynamic_table_update_allowed == 0) {
     return parse_error(
         exec_ctx, p, cur, end,
-        GRPC_ERROR_CREATE(
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING(
             "More than two max table size changes in a single frame"));
   }
   p->dynamic_table_update_allowed--;
@@ -1126,7 +1120,7 @@ static grpc_error *parse_illegal_op(grpc_exec_ctx *exec_ctx,
   GPR_ASSERT(cur != end);
   char *msg;
   gpr_asprintf(&msg, "Illegal hpack op code %d", *cur);
-  grpc_error *err = GRPC_ERROR_CREATE(msg);
+  grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
   gpr_free(msg);
   return parse_error(exec_ctx, p, cur, end, err);
 }
@@ -1246,7 +1240,7 @@ error:
                "integer overflow in hpack integer decoding: have 0x%08x, "
                "got byte 0x%02x on byte 5",
                *p->parsing.value, *cur);
-  grpc_error *err = GRPC_ERROR_CREATE(msg);
+  grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
   gpr_free(msg);
   return parse_error(exec_ctx, p, cur, end, err);
 }
@@ -1275,7 +1269,7 @@ static grpc_error *parse_value5up(grpc_exec_ctx *exec_ctx,
                "integer overflow in hpack integer decoding: have 0x%08x, "
                "got byte 0x%02x sometime after byte 5",
                *p->parsing.value, *cur);
-  grpc_error *err = GRPC_ERROR_CREATE(msg);
+  grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
   gpr_free(msg);
   return parse_error(exec_ctx, p, cur, end, err);
 }
@@ -1324,6 +1318,19 @@ static grpc_error *append_string(grpc_exec_ctx *exec_ctx,
     case NOT_BINARY:
       append_bytes(str, cur, (size_t)(end - cur));
       return GRPC_ERROR_NONE;
+    case BINARY_BEGIN:
+      if (cur == end) {
+        p->binary = BINARY_BEGIN;
+        return GRPC_ERROR_NONE;
+      }
+      if (*cur == 0) {
+        /* 'true-binary' case */
+        ++cur;
+        p->binary = NOT_BINARY;
+        append_bytes(str, cur, (size_t)(end - cur));
+        return GRPC_ERROR_NONE;
+      }
+    /* fallthrough */
     b64_byte0:
     case B64_BYTE0:
       if (cur == end) {
@@ -1333,8 +1340,9 @@ static grpc_error *append_string(grpc_exec_ctx *exec_ctx,
       bits = inverse_base64[*cur];
       ++cur;
       if (bits == 255)
-        return parse_error(exec_ctx, p, cur, end,
-                           GRPC_ERROR_CREATE("Illegal base64 character"));
+        return parse_error(
+            exec_ctx, p, cur, end,
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character"));
       else if (bits == 64)
         goto b64_byte0;
       p->base64_buffer = bits << 18;
@@ -1348,8 +1356,9 @@ static grpc_error *append_string(grpc_exec_ctx *exec_ctx,
       bits = inverse_base64[*cur];
       ++cur;
       if (bits == 255)
-        return parse_error(exec_ctx, p, cur, end,
-                           GRPC_ERROR_CREATE("Illegal base64 character"));
+        return parse_error(
+            exec_ctx, p, cur, end,
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character"));
       else if (bits == 64)
         goto b64_byte1;
       p->base64_buffer |= bits << 12;
@@ -1363,8 +1372,9 @@ static grpc_error *append_string(grpc_exec_ctx *exec_ctx,
       bits = inverse_base64[*cur];
       ++cur;
       if (bits == 255)
-        return parse_error(exec_ctx, p, cur, end,
-                           GRPC_ERROR_CREATE("Illegal base64 character"));
+        return parse_error(
+            exec_ctx, p, cur, end,
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character"));
       else if (bits == 64)
         goto b64_byte2;
       p->base64_buffer |= bits << 6;
@@ -1378,8 +1388,9 @@ static grpc_error *append_string(grpc_exec_ctx *exec_ctx,
       bits = inverse_base64[*cur];
       ++cur;
       if (bits == 255)
-        return parse_error(exec_ctx, p, cur, end,
-                           GRPC_ERROR_CREATE("Illegal base64 character"));
+        return parse_error(
+            exec_ctx, p, cur, end,
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character"));
       else if (bits == 64)
         goto b64_byte3;
       p->base64_buffer |= bits;
@@ -1391,7 +1402,8 @@ static grpc_error *append_string(grpc_exec_ctx *exec_ctx,
       goto b64_byte0;
   }
   GPR_UNREACHABLE_CODE(return parse_error(
-      exec_ctx, p, cur, end, GRPC_ERROR_CREATE("Should never reach here")));
+      exec_ctx, p, cur, end,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here")));
 }
 
 static grpc_error *finish_str(grpc_exec_ctx *exec_ctx,
@@ -1403,19 +1415,21 @@ static grpc_error *finish_str(grpc_exec_ctx *exec_ctx,
   switch ((binary_state)p->binary) {
     case NOT_BINARY:
       break;
+    case BINARY_BEGIN:
+      break;
     case B64_BYTE0:
       break;
     case B64_BYTE1:
-      return parse_error(
-          exec_ctx, p, cur, end,
-          GRPC_ERROR_CREATE("illegal base64 encoding")); /* illegal encoding */
+      return parse_error(exec_ctx, p, cur, end,
+                         GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                             "illegal base64 encoding")); /* illegal encoding */
     case B64_BYTE2:
       bits = p->base64_buffer;
       if (bits & 0xffff) {
         char *msg;
         gpr_asprintf(&msg, "trailing bits in base64 encoding: 0x%04x",
                      bits & 0xffff);
-        grpc_error *err = GRPC_ERROR_CREATE(msg);
+        grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
         gpr_free(msg);
         return parse_error(exec_ctx, p, cur, end, err);
       }
@@ -1428,7 +1442,7 @@ static grpc_error *finish_str(grpc_exec_ctx *exec_ctx,
         char *msg;
         gpr_asprintf(&msg, "trailing bits in base64 encoding: 0x%02x",
                      bits & 0xff);
-        grpc_error *err = GRPC_ERROR_CREATE(msg);
+        grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
         gpr_free(msg);
         return parse_error(exec_ctx, p, cur, end, err);
       }
@@ -1550,7 +1564,8 @@ static grpc_error *is_binary_indexed_header(grpc_chttp2_hpack_parser *p,
   grpc_mdelem elem = grpc_chttp2_hptbl_lookup(&p->table, p->index);
   if (GRPC_MDISNULL(elem)) {
     return grpc_error_set_int(
-        grpc_error_set_int(GRPC_ERROR_CREATE("Invalid HPACK index received"),
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                               "Invalid HPACK index received"),
                            GRPC_ERROR_INT_INDEX, (intptr_t)p->index),
         GRPC_ERROR_INT_SIZE, (intptr_t)p->table.num_ents);
   }
@@ -1564,7 +1579,7 @@ static grpc_error *parse_value_string(grpc_exec_ctx *exec_ctx,
                                       const uint8_t *cur, const uint8_t *end,
                                       bool is_binary) {
   return begin_parse_string(exec_ctx, p, cur, end,
-                            is_binary ? B64_BYTE0 : NOT_BINARY, &p->value);
+                            is_binary ? BINARY_BEGIN : NOT_BINARY, &p->value);
 }
 
 static grpc_error *parse_value_string_with_indexed_key(
@@ -1620,13 +1635,18 @@ void grpc_chttp2_hpack_parser_destroy(grpc_exec_ctx *exec_ctx,
 grpc_error *grpc_chttp2_hpack_parser_parse(grpc_exec_ctx *exec_ctx,
                                            grpc_chttp2_hpack_parser *p,
                                            grpc_slice slice) {
-  /* TODO(ctiller): limit the distance of end from beg, and perform multiple
-     steps in the event of a large chunk of data to limit
-     stack space usage when no tail call optimization is
-     available */
+/* max number of bytes to parse at a time... limits call stack depth on
+ * compilers without TCO */
+#define MAX_PARSE_LENGTH 1024
   p->current_slice_refcount = slice.refcount;
-  grpc_error *error = p->state(exec_ctx, p, GRPC_SLICE_START_PTR(slice),
-                               GRPC_SLICE_END_PTR(slice));
+  uint8_t *start = GRPC_SLICE_START_PTR(slice);
+  uint8_t *end = GRPC_SLICE_END_PTR(slice);
+  grpc_error *error = GRPC_ERROR_NONE;
+  while (start != end && error == GRPC_ERROR_NONE) {
+    uint8_t *target = start + GPR_MIN(MAX_PARSE_LENGTH, end - start);
+    error = p->state(exec_ctx, p, start, target);
+    start = target;
+  }
   p->current_slice_refcount = NULL;
   return error;
 }
@@ -1670,7 +1690,7 @@ grpc_error *grpc_chttp2_header_parser_parse(grpc_exec_ctx *exec_ctx,
   if (is_last) {
     if (parser->is_boundary && parser->state != parse_begin) {
       GPR_TIMER_END("grpc_chttp2_hpack_parser_parse", 0);
-      return GRPC_ERROR_CREATE(
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
           "end of header frame not aligned with a hpack record boundary");
     }
     /* need to check for null stream: this can occur if we receive an invalid
@@ -1678,7 +1698,8 @@ grpc_error *grpc_chttp2_header_parser_parse(grpc_exec_ctx *exec_ctx,
     if (s != NULL) {
       if (parser->is_boundary) {
         if (s->header_frames_received == GPR_ARRAY_SIZE(s->metadata_buffer)) {
-          return GRPC_ERROR_CREATE("Too many trailer frames");
+          return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+              "Too many trailer frames");
         }
         s->published_metadata[s->header_frames_received] =
             GRPC_METADATA_PUBLISHED_FROM_WIRE;
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.c b/src/core/ext/transport/chttp2/transport/hpack_table.c
index 62dd1b8cab4c3ee22207edcd88d38fcf31f10c5e..9dd41fdbe16caefdcf3a38c320bbbea5aeab7673 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.c
@@ -280,7 +280,7 @@ grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_exec_ctx *exec_ctx,
     gpr_asprintf(&msg,
                  "Attempt to make hpack table %d bytes when max is %d bytes",
                  bytes, tbl->max_bytes);
-    grpc_error *err = GRPC_ERROR_CREATE(msg);
+    grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return err;
   }
@@ -317,7 +317,7 @@ grpc_error *grpc_chttp2_hptbl_add(grpc_exec_ctx *exec_ctx,
         "HPACK max table size reduced to %d but not reflected by hpack "
         "stream (still at %d)",
         tbl->max_bytes, tbl->current_table_bytes);
-    grpc_error *err = GRPC_ERROR_CREATE(msg);
+    grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return err;
   }
diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.c b/src/core/ext/transport/chttp2/transport/http2_settings.c
new file mode 100644
index 0000000000000000000000000000000000000000..d4905107efe9e71a6ae61b83fda0c8707d3dc662
--- /dev/null
+++ b/src/core/ext/transport/chttp2/transport/http2_settings.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2017, 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 by tools/codegen/core/gen_settings_ids.py
+ */
+
+#include "src/core/ext/transport/chttp2/transport/http2_settings.h"
+
+#include <grpc/support/useful.h>
+#include "src/core/lib/transport/http2_errors.h"
+
+const uint16_t grpc_setting_id_to_wire_id[] = {1, 2, 3, 4, 5, 6, 65027};
+
+bool grpc_wire_id_to_setting_id(uint32_t wire_id, grpc_chttp2_setting_id *out) {
+  uint32_t i = wire_id - 1;
+  uint32_t x = i % 256;
+  uint32_t y = i / 256;
+  uint32_t h = x;
+  switch (y) {
+    case 254:
+      h += 4;
+      break;
+  }
+  *out = (grpc_chttp2_setting_id)h;
+  return h < GPR_ARRAY_SIZE(grpc_setting_id_to_wire_id) &&
+         grpc_setting_id_to_wire_id[h] == wire_id;
+}
+
+const grpc_chttp2_setting_parameters
+    grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS] = {
+        {"HEADER_TABLE_SIZE", 4096u, 0u, 4294967295u,
+         GRPC_CHTTP2_CLAMP_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR},
+        {"ENABLE_PUSH", 1u, 0u, 1u, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE,
+         GRPC_HTTP2_PROTOCOL_ERROR},
+        {"MAX_CONCURRENT_STREAMS", 4294967295u, 0u, 4294967295u,
+         GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR},
+        {"INITIAL_WINDOW_SIZE", 65535u, 0u, 2147483647u,
+         GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE,
+         GRPC_HTTP2_FLOW_CONTROL_ERROR},
+        {"MAX_FRAME_SIZE", 16384u, 16384u, 16777215u,
+         GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR},
+        {"MAX_HEADER_LIST_SIZE", 16777216u, 0u, 16777216u,
+         GRPC_CHTTP2_CLAMP_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR},
+        {"GRPC_ALLOW_TRUE_BINARY_METADATA", 0u, 0u, 1u,
+         GRPC_CHTTP2_CLAMP_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR},
+};
diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.h b/src/core/ext/transport/chttp2/transport/http2_settings.h
new file mode 100644
index 0000000000000000000000000000000000000000..9781cdc9893ac794fdb7f1454101f9e9013b1589
--- /dev/null
+++ b/src/core/ext/transport/chttp2/transport/http2_settings.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2017, 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 by tools/codegen/core/gen_settings_ids.py
+ */
+
+#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H
+#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+typedef enum {
+  GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE = 0,               /* wire id 1 */
+  GRPC_CHTTP2_SETTINGS_ENABLE_PUSH = 1,                     /* wire id 2 */
+  GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS = 2,          /* wire id 3 */
+  GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 3,             /* wire id 4 */
+  GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE = 4,                  /* wire id 5 */
+  GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 5,            /* wire id 6 */
+  GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA = 6, /* wire id 65027 */
+} grpc_chttp2_setting_id;
+
+#define GRPC_CHTTP2_NUM_SETTINGS 7
+extern const uint16_t grpc_setting_id_to_wire_id[];
+
+bool grpc_wire_id_to_setting_id(uint32_t wire_id, grpc_chttp2_setting_id *out);
+
+typedef enum {
+  GRPC_CHTTP2_CLAMP_INVALID_VALUE,
+  GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE
+} grpc_chttp2_invalid_value_behavior;
+
+typedef struct {
+  const char *name;
+  uint32_t default_value;
+  uint32_t min_value;
+  uint32_t max_value;
+  grpc_chttp2_invalid_value_behavior invalid_value_behavior;
+  uint32_t error_value;
+} grpc_chttp2_setting_parameters;
+
+extern const grpc_chttp2_setting_parameters
+    grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS];
+
+#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H */
diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.c b/src/core/ext/transport/chttp2/transport/incoming_metadata.c
index c91b019aa0591c0747ce3f9ea4b2363a0216c334..da0a34d32a08f009c4eab9657ce0baa80ca310d5 100644
--- a/src/core/ext/transport/chttp2/transport/incoming_metadata.c
+++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.c
@@ -41,69 +41,48 @@
 #include <grpc/support/log.h>
 
 void grpc_chttp2_incoming_metadata_buffer_init(
-    grpc_chttp2_incoming_metadata_buffer *buffer) {
-  buffer->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
+    grpc_chttp2_incoming_metadata_buffer *buffer, gpr_arena *arena) {
+  buffer->arena = arena;
+  grpc_metadata_batch_init(&buffer->batch);
+  buffer->batch.deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
 }
 
 void grpc_chttp2_incoming_metadata_buffer_destroy(
     grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer) {
-  size_t i;
-  if (!buffer->published) {
-    for (i = 0; i < buffer->count; i++) {
-      GRPC_MDELEM_UNREF(exec_ctx, buffer->elems[i].md);
-    }
-  }
-  gpr_free(buffer->elems);
+  grpc_metadata_batch_destroy(exec_ctx, &buffer->batch);
 }
 
-void grpc_chttp2_incoming_metadata_buffer_add(
-    grpc_chttp2_incoming_metadata_buffer *buffer, grpc_mdelem elem) {
-  GPR_ASSERT(!buffer->published);
-  if (buffer->capacity == buffer->count) {
-    buffer->capacity = GPR_MAX(8, 2 * buffer->capacity);
-    buffer->elems =
-        gpr_realloc(buffer->elems, sizeof(*buffer->elems) * buffer->capacity);
-  }
-  buffer->elems[buffer->count++].md = elem;
+grpc_error *grpc_chttp2_incoming_metadata_buffer_add(
+    grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer,
+    grpc_mdelem elem) {
   buffer->size += GRPC_MDELEM_LENGTH(elem);
+  return grpc_metadata_batch_add_tail(
+      exec_ctx, &buffer->batch,
+      gpr_arena_alloc(buffer->arena, sizeof(grpc_linked_mdelem)), elem);
 }
 
-void grpc_chttp2_incoming_metadata_buffer_replace_or_add(
+grpc_error *grpc_chttp2_incoming_metadata_buffer_replace_or_add(
     grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer,
     grpc_mdelem elem) {
-  for (size_t i = 0; i < buffer->count; i++) {
-    if (grpc_slice_eq(GRPC_MDKEY(buffer->elems[i].md), GRPC_MDKEY(elem))) {
-      GRPC_MDELEM_UNREF(exec_ctx, buffer->elems[i].md);
-      buffer->elems[i].md = elem;
-      return;
+  for (grpc_linked_mdelem *l = buffer->batch.list.head; l != NULL;
+       l = l->next) {
+    if (grpc_slice_eq(GRPC_MDKEY(l->md), GRPC_MDKEY(elem))) {
+      GRPC_MDELEM_UNREF(exec_ctx, l->md);
+      l->md = elem;
+      return GRPC_ERROR_NONE;
     }
   }
-  grpc_chttp2_incoming_metadata_buffer_add(buffer, elem);
+  return grpc_chttp2_incoming_metadata_buffer_add(exec_ctx, buffer, elem);
 }
 
 void grpc_chttp2_incoming_metadata_buffer_set_deadline(
     grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline) {
-  GPR_ASSERT(!buffer->published);
-  buffer->deadline = deadline;
+  buffer->batch.deadline = deadline;
 }
 
 void grpc_chttp2_incoming_metadata_buffer_publish(
     grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer,
     grpc_metadata_batch *batch) {
-  GPR_ASSERT(!buffer->published);
-  buffer->published = 1;
-  if (buffer->count > 0) {
-    size_t i;
-    for (i = 0; i < buffer->count; i++) {
-      /* TODO(ctiller): do something better here */
-      if (!GRPC_LOG_IF_ERROR("grpc_chttp2_incoming_metadata_buffer_publish",
-                             grpc_metadata_batch_link_tail(
-                                 exec_ctx, batch, &buffer->elems[i]))) {
-        GRPC_MDELEM_UNREF(exec_ctx, buffer->elems[i].md);
-      }
-    }
-  } else {
-    batch->list.head = batch->list.tail = NULL;
-  }
-  batch->deadline = buffer->deadline;
+  *batch = buffer->batch;
+  grpc_metadata_batch_init(&buffer->batch);
 }
diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.h b/src/core/ext/transport/chttp2/transport/incoming_metadata.h
index 1eac6fc1504112d724392f3844e7cd4eca7ffe1e..288c917e65a96fad5cd2d5629c6ce3b232565433 100644
--- a/src/core/ext/transport/chttp2/transport/incoming_metadata.h
+++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.h
@@ -37,28 +37,26 @@
 #include "src/core/lib/transport/transport.h"
 
 typedef struct {
-  grpc_linked_mdelem *elems;
-  size_t count;
-  size_t capacity;
-  gpr_timespec deadline;
-  int published;
+  gpr_arena *arena;
+  grpc_metadata_batch batch;
   size_t size;  // total size of metadata
 } grpc_chttp2_incoming_metadata_buffer;
 
 /** assumes everything initially zeroed */
 void grpc_chttp2_incoming_metadata_buffer_init(
-    grpc_chttp2_incoming_metadata_buffer *buffer);
+    grpc_chttp2_incoming_metadata_buffer *buffer, gpr_arena *arena);
 void grpc_chttp2_incoming_metadata_buffer_destroy(
     grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer);
 void grpc_chttp2_incoming_metadata_buffer_publish(
     grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer,
     grpc_metadata_batch *batch);
 
-void grpc_chttp2_incoming_metadata_buffer_add(
-    grpc_chttp2_incoming_metadata_buffer *buffer, grpc_mdelem elem);
-void grpc_chttp2_incoming_metadata_buffer_replace_or_add(
+grpc_error *grpc_chttp2_incoming_metadata_buffer_add(
     grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer,
-    grpc_mdelem elem);
+    grpc_mdelem elem) GRPC_MUST_USE_RESULT;
+grpc_error *grpc_chttp2_incoming_metadata_buffer_replace_or_add(
+    grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer,
+    grpc_mdelem elem) GRPC_MUST_USE_RESULT;
 void grpc_chttp2_incoming_metadata_buffer_set_deadline(
     grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline);
 
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index d26812ad6be357f870527176ff08a1a35408bfbb..0aaa4aebe5f973f51d385573bad8c03a40568c4a 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -97,13 +97,22 @@ typedef struct {
 typedef struct {
   gpr_timespec min_time_between_pings;
   int max_pings_without_data;
+  int max_ping_strikes;
+  gpr_timespec min_ping_interval_without_data;
 } grpc_chttp2_repeated_ping_policy;
 
 typedef struct {
   gpr_timespec last_ping_sent_time;
   int pings_before_data_required;
+  grpc_timer delayed_ping_timer;
+  bool is_delayed_ping_timer_set;
 } grpc_chttp2_repeated_ping_state;
 
+typedef struct {
+  gpr_timespec last_ping_recv_time;
+  int ping_strikes;
+} grpc_chttp2_server_ping_recv_state;
+
 /* deframer state for the overall http2 stream of bytes */
 typedef enum {
   /* prefix: one entry per http2 connection prefix byte */
@@ -186,22 +195,20 @@ typedef struct grpc_chttp2_write_cb {
 struct grpc_chttp2_incoming_byte_stream {
   grpc_byte_stream base;
   gpr_refcount refs;
-  struct grpc_chttp2_incoming_byte_stream *next_message;
-  grpc_error *error;
 
-  grpc_chttp2_transport *transport;
-  grpc_chttp2_stream *stream;
-  bool is_tail;
+  grpc_chttp2_transport *transport; /* immutable */
+  grpc_chttp2_stream *stream;       /* immutable */
 
-  gpr_mu slice_mu;  // protects slices, on_next
-  grpc_slice_buffer slices;
-  grpc_closure *on_next;
-  grpc_slice *next;
+  /* Accessed only by transport thread when stream->pending_byte_stream == false
+   * Accessed only by application thread when stream->pending_byte_stream ==
+   * true */
   uint32_t remaining_bytes;
 
+  /* Accessed only by transport thread when stream->pending_byte_stream == false
+   * Accessed only by application thread when stream->pending_byte_stream ==
+   * true */
   struct {
     grpc_closure closure;
-    grpc_slice *slice;
     size_t max_size_hint;
     grpc_closure *on_complete;
   } next_action;
@@ -213,6 +220,7 @@ typedef enum {
   GRPC_CHTTP2_KEEPALIVE_STATE_WAITING,
   GRPC_CHTTP2_KEEPALIVE_STATE_PINGING,
   GRPC_CHTTP2_KEEPALIVE_STATE_DYING,
+  GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED,
 } grpc_chttp2_keepalive_state;
 
 struct grpc_chttp2_transport {
@@ -308,11 +316,13 @@ struct grpc_chttp2_transport {
   grpc_chttp2_repeated_ping_policy ping_policy;
   grpc_chttp2_repeated_ping_state ping_state;
   uint64_t ping_ctr; /* unique id for pings */
+  grpc_closure retry_initiate_ping_locked;
 
   /** ping acks */
   size_t ping_ack_count;
   size_t ping_ack_capacity;
   uint64_t *ping_acks;
+  grpc_chttp2_server_ping_recv_state ping_recv_state;
 
   /** parser for headers */
   grpc_chttp2_hpack_parser hpack_parser;
@@ -425,7 +435,7 @@ struct grpc_chttp2_stream {
   grpc_stream_refcount *refcount;
 
   grpc_closure destroy_stream;
-  void *destroy_stream_arg;
+  grpc_closure *destroy_stream_arg;
 
   grpc_chttp2_stream_link links[STREAM_LIST_COUNT];
   uint8_t included[STREAM_LIST_COUNT];
@@ -434,8 +444,8 @@ struct grpc_chttp2_stream {
   uint32_t id;
 
   /** window available for us to send to peer, over or under the initial window
-    * size of the transport... ie:
-    * outgoing_window = outgoing_window_delta + transport.initial_window_size */
+   * size of the transport... ie:
+   * outgoing_window = outgoing_window_delta + transport.initial_window_size */
   int64_t outgoing_window_delta;
   /** things the upper layers would like to send */
   grpc_metadata_batch *send_initial_metadata;
@@ -449,7 +459,6 @@ struct grpc_chttp2_stream {
   int64_t next_message_end_offset;
   int64_t flow_controlled_bytes_written;
   bool complete_fetch_covered_by_poller;
-  grpc_closure complete_fetch;
   grpc_closure complete_fetch_locked;
   grpc_closure *fetching_send_message_finished;
 
@@ -463,9 +472,6 @@ struct grpc_chttp2_stream {
   grpc_transport_stream_stats *collecting_stats;
   grpc_transport_stream_stats stats;
 
-  /** number of streams that are currently being read */
-  gpr_refcount active_streams;
-
   /** Is this stream closed for writing. */
   bool write_closed;
   /** Is this stream reading half-closed. */
@@ -489,7 +495,17 @@ struct grpc_chttp2_stream {
 
   grpc_chttp2_incoming_metadata_buffer metadata_buffer[2];
 
-  grpc_chttp2_incoming_frame_queue incoming_frames;
+  grpc_slice_buffer frame_storage; /* protected by t combiner */
+
+  /* Accessed only by transport thread when stream->pending_byte_stream == false
+   * Accessed only by application thread when stream->pending_byte_stream ==
+   * true */
+  grpc_slice_buffer unprocessed_incoming_frames_buffer;
+  grpc_closure *on_next;    /* protected by t combiner */
+  bool pending_byte_stream; /* protected by t combiner */
+  grpc_closure reset_byte_stream;
+  grpc_error *byte_stream_error; /* protected by t combiner */
+  bool received_last_frame;      /* protected by t combiner */
 
   gpr_timespec deadline;
 
@@ -502,6 +518,9 @@ struct grpc_chttp2_stream {
    * incoming_window = incoming_window_delta + transport.initial_window_size */
   int64_t incoming_window_delta;
   /** parsing state for data frames */
+  /* Accessed only by transport thread when stream->pending_byte_stream == false
+   * Accessed only by application thread when stream->pending_byte_stream ==
+   * true */
   grpc_chttp2_data_parser data_parser;
   /** number of bytes received - reset at end of parse thread execution */
   int64_t received_bytes;
@@ -780,16 +799,26 @@ void grpc_chttp2_ref_transport(grpc_chttp2_transport *t);
 grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create(
     grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s,
     uint32_t frame_size, uint32_t flags);
-void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx,
-                                           grpc_chttp2_incoming_byte_stream *bs,
-                                           grpc_slice slice);
-void grpc_chttp2_incoming_byte_stream_finished(
+grpc_error *grpc_chttp2_incoming_byte_stream_push(
+    grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
+    grpc_slice slice, grpc_slice *slice_out);
+grpc_error *grpc_chttp2_incoming_byte_stream_finished(
+    grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
+    grpc_error *error, bool reset_on_error);
+void grpc_chttp2_incoming_byte_stream_notify(
     grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
     grpc_error *error);
 
 void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
                           uint64_t id);
 
+/** Add a new ping strike to ping_recv_state.ping_strikes. If
+    ping_recv_state.ping_strikes > ping_policy.max_ping_strikes, it sends GOAWAY
+    with error code ENHANCE_YOUR_CALM and additional debug data resembling
+    “too_many_pings” followed by immediately closing the connection. */
+void grpc_chttp2_add_ping_strike(grpc_exec_ctx *exec_ctx,
+                                 grpc_chttp2_transport *t);
+
 typedef enum {
   /* don't initiate a transport write, but piggyback on the next one */
   GRPC_CHTTP2_STREAM_WRITE_PIGGYBACK,
@@ -827,4 +856,9 @@ void grpc_chttp2_fail_pending_writes(grpc_exec_ctx *exec_ctx,
 
 uint32_t grpc_chttp2_target_incoming_window(grpc_chttp2_transport *t);
 
+/** Set the default keepalive configurations, must only be called at
+    initialization */
+void grpc_chttp2_config_default_keepalive_args(grpc_channel_args *args,
+                                               bool is_client);
+
 #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_INTERNAL_H */
diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c
index 7ed00522c3ea3ee88afa1dee8479aaa1b7dc9881..638b137316fdd14773466d248a7aa06604f0b19d 100644
--- a/src/core/ext/transport/chttp2/transport/parsing.c
+++ b/src/core/ext/transport/chttp2/transport/parsing.c
@@ -116,7 +116,7 @@ grpc_error *grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx,
               GRPC_CHTTP2_CLIENT_CONNECT_STRING[t->deframe_state],
               (int)(uint8_t)GRPC_CHTTP2_CLIENT_CONNECT_STRING[t->deframe_state],
               *cur, (int)*cur, t->deframe_state);
-          err = GRPC_ERROR_CREATE(msg);
+          err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
           gpr_free(msg);
           return err;
         }
@@ -219,7 +219,7 @@ grpc_error *grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx,
                      t->incoming_frame_size,
                      t->settings[GRPC_ACKED_SETTINGS]
                                 [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]);
-        err = GRPC_ERROR_CREATE(msg);
+        err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
         gpr_free(msg);
         return err;
       }
@@ -278,7 +278,7 @@ static grpc_error *init_frame_parser(grpc_exec_ctx *exec_ctx,
     gpr_asprintf(
         &msg, "Expected SETTINGS frame as the first frame, got frame type %d",
         t->incoming_frame_type);
-    grpc_error *err = GRPC_ERROR_CREATE(msg);
+    grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return err;
   }
@@ -288,7 +288,7 @@ static grpc_error *init_frame_parser(grpc_exec_ctx *exec_ctx,
       char *msg;
       gpr_asprintf(&msg, "Expected CONTINUATION frame, got frame type %02x",
                    t->incoming_frame_type);
-      grpc_error *err = GRPC_ERROR_CREATE(msg);
+      grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
       gpr_free(msg);
       return err;
     }
@@ -299,7 +299,7 @@ static grpc_error *init_frame_parser(grpc_exec_ctx *exec_ctx,
           "Expected CONTINUATION frame for grpc_chttp2_stream %08x, got "
           "grpc_chttp2_stream %08x",
           t->expect_continuation_stream_id, t->incoming_stream_id);
-      grpc_error *err = GRPC_ERROR_CREATE(msg);
+      grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
       gpr_free(msg);
       return err;
     }
@@ -311,7 +311,8 @@ static grpc_error *init_frame_parser(grpc_exec_ctx *exec_ctx,
     case GRPC_CHTTP2_FRAME_HEADER:
       return init_header_frame_parser(exec_ctx, t, 0);
     case GRPC_CHTTP2_FRAME_CONTINUATION:
-      return GRPC_ERROR_CREATE("Unexpected CONTINUATION frame");
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "Unexpected CONTINUATION frame");
     case GRPC_CHTTP2_FRAME_RST_STREAM:
       return init_rst_stream_parser(exec_ctx, t);
     case GRPC_CHTTP2_FRAME_SETTINGS:
@@ -371,7 +372,7 @@ static grpc_error *update_incoming_window(grpc_exec_ctx *exec_ctx,
     char *msg;
     gpr_asprintf(&msg, "frame of size %d overflows incoming window of %" PRId64,
                  t->incoming_frame_size, t->incoming_window);
-    grpc_error *err = GRPC_ERROR_CREATE(msg);
+    grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return err;
   }
@@ -381,16 +382,38 @@ static grpc_error *update_incoming_window(grpc_exec_ctx *exec_ctx,
         s->incoming_window_delta +
             t->settings[GRPC_ACKED_SETTINGS]
                        [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]) {
-      char *msg;
-      gpr_asprintf(&msg,
-                   "frame of size %d overflows incoming window of %" PRId64,
-                   t->incoming_frame_size,
-                   s->incoming_window_delta +
-                       t->settings[GRPC_ACKED_SETTINGS]
-                                  [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
-      grpc_error *err = GRPC_ERROR_CREATE(msg);
-      gpr_free(msg);
-      return err;
+      if (incoming_frame_size <=
+          s->incoming_window_delta +
+              t->settings[GRPC_SENT_SETTINGS]
+                         [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]) {
+        gpr_log(
+            GPR_ERROR,
+            "Incoming frame of size %d exceeds incoming window size of %" PRId64
+            ".\n"
+            "The (un-acked, future) window size would be %" PRId64
+            " which is not exceeded.\n"
+            "This would usually cause a disconnection, but allowing it due to "
+            "broken HTTP2 implementations in the wild.\n"
+            "See (for example) https://github.com/netty/netty/issues/6520.",
+            t->incoming_frame_size,
+            s->incoming_window_delta +
+                t->settings[GRPC_ACKED_SETTINGS]
+                           [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE],
+            s->incoming_window_delta +
+                t->settings[GRPC_SENT_SETTINGS]
+                           [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
+      } else {
+        char *msg;
+        gpr_asprintf(&msg,
+                     "frame of size %d overflows incoming window of %" PRId64,
+                     t->incoming_frame_size,
+                     s->incoming_window_delta +
+                         t->settings[GRPC_ACKED_SETTINGS]
+                                    [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
+        grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
+        gpr_free(msg);
+        return err;
+      }
     }
 
     GRPC_CHTTP2_FLOW_DEBIT_STREAM_INCOMING_WINDOW_DELTA("parse", t, s,
@@ -435,12 +458,13 @@ static grpc_error *init_data_frame_parser(grpc_exec_ctx *exec_ctx,
     return init_skip_frame_parser(exec_ctx, t, 0);
   }
   if (err == GRPC_ERROR_NONE) {
-    err = grpc_chttp2_data_parser_begin_frame(&s->data_parser,
-                                              t->incoming_frame_flags, s->id);
+    err = grpc_chttp2_data_parser_begin_frame(
+        &s->data_parser, t->incoming_frame_flags, s->id, s);
   }
 error_handler:
   if (err == GRPC_ERROR_NONE) {
     t->incoming_stream = s;
+    /* t->parser = grpc_chttp2_data_parser_parse;*/
     t->parser = grpc_chttp2_data_parser_parse;
     t->parser_data = &s->data_parser;
     return GRPC_ERROR_NONE;
@@ -520,13 +544,21 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp,
       grpc_chttp2_cancel_stream(
           exec_ctx, t, s,
           grpc_error_set_int(
-              GRPC_ERROR_CREATE("received initial metadata size exceeds limit"),
+              GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                  "received initial metadata size exceeds limit"),
               GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
       grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
       s->seen_error = true;
       GRPC_MDELEM_UNREF(exec_ctx, md);
     } else {
-      grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[0], md);
+      grpc_error *error = grpc_chttp2_incoming_metadata_buffer_add(
+          exec_ctx, &s->metadata_buffer[0], md);
+      if (error != GRPC_ERROR_NONE) {
+        grpc_chttp2_cancel_stream(exec_ctx, t, s, error);
+        grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
+        s->seen_error = true;
+        GRPC_MDELEM_UNREF(exec_ctx, md);
+      }
     }
   }
 
@@ -569,14 +601,22 @@ static void on_trailing_header(grpc_exec_ctx *exec_ctx, void *tp,
             new_size, metadata_size_limit);
     grpc_chttp2_cancel_stream(
         exec_ctx, t, s,
-        grpc_error_set_int(
-            GRPC_ERROR_CREATE("received trailing metadata size exceeds limit"),
-            GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                               "received trailing metadata size exceeds limit"),
+                           GRPC_ERROR_INT_GRPC_STATUS,
+                           GRPC_STATUS_RESOURCE_EXHAUSTED));
     grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
     s->seen_error = true;
     GRPC_MDELEM_UNREF(exec_ctx, md);
   } else {
-    grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[1], md);
+    grpc_error *error = grpc_chttp2_incoming_metadata_buffer_add(
+        exec_ctx, &s->metadata_buffer[1], md);
+    if (error != GRPC_ERROR_NONE) {
+      grpc_chttp2_cancel_stream(exec_ctx, t, s, error);
+      grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
+      s->seen_error = true;
+      GRPC_MDELEM_UNREF(exec_ctx, md);
+    }
   }
 
   GPR_TIMER_END("on_trailing_header", 0);
@@ -735,7 +775,8 @@ static grpc_error *init_goaway_parser(grpc_exec_ctx *exec_ctx,
 static grpc_error *init_settings_frame_parser(grpc_exec_ctx *exec_ctx,
                                               grpc_chttp2_transport *t) {
   if (t->incoming_stream_id != 0) {
-    return GRPC_ERROR_CREATE("Settings frame received for grpc_chttp2_stream");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Settings frame received for grpc_chttp2_stream");
   }
 
   grpc_error *err = grpc_chttp2_settings_parser_begin_frame(
diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c
index 2b9d93cae7cc0b3db995d081c3684a57e4509891..069780ae5af0bd0087b1c431ec692b114a13c0e8 100644
--- a/src/core/ext/transport/chttp2/transport/writing.c
+++ b/src/core/ext/transport/chttp2/transport/writing.c
@@ -101,6 +101,14 @@ static void maybe_initiate_ping(grpc_exec_ctx *exec_ctx,
               "Ping delayed [%p]: not enough time elapsed since last ping",
               t->peer_string);
     }
+    if (!t->ping_state.is_delayed_ping_timer_set) {
+      t->ping_state.is_delayed_ping_timer_set = true;
+      grpc_timer_init(exec_ctx, &t->ping_state.delayed_ping_timer,
+                      gpr_time_add(t->ping_state.last_ping_sent_time,
+                                   t->ping_policy.min_time_between_pings),
+                      &t->retry_initiate_ping_locked,
+                      gpr_now(GPR_CLOCK_MONOTONIC));
+    }
     return;
   }
   /* coalesce equivalent pings into this one */
@@ -211,16 +219,29 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
 
     /* send initial metadata if it's available */
     if (!sent_initial_metadata && s->send_initial_metadata) {
-      grpc_chttp2_encode_header(
-          exec_ctx, &t->hpack_compressor, s->id, s->send_initial_metadata, 0,
-          t->settings[GRPC_ACKED_SETTINGS][GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
-          &s->stats.outgoing, &t->outbuf);
+      grpc_encode_header_options hopt = {
+          .stream_id = s->id,
+          .is_eof = false,
+          .use_true_binary_metadata =
+              t->settings
+                  [GRPC_PEER_SETTINGS]
+                  [GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA] != 0,
+          .max_frame_size = t->settings[GRPC_PEER_SETTINGS]
+                                       [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
+          .stats = &s->stats.outgoing};
+      grpc_chttp2_encode_header(exec_ctx, &t->hpack_compressor,
+                                s->send_initial_metadata, &hopt, &t->outbuf);
       s->send_initial_metadata = NULL;
       s->sent_initial_metadata = true;
       sent_initial_metadata = true;
       now_writing = true;
       t->ping_state.pings_before_data_required =
           t->ping_policy.max_pings_without_data;
+      if (!t->is_client) {
+        t->ping_recv_state.last_ping_recv_time =
+            gpr_inf_past(GPR_CLOCK_MONOTONIC);
+        t->ping_recv_state.ping_strikes = 0;
+      }
     }
     /* send any window updates */
     if (s->announce_window > 0) {
@@ -230,6 +251,11 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
                                 s->id, s->announce_window, &s->stats.outgoing));
       t->ping_state.pings_before_data_required =
           t->ping_policy.max_pings_without_data;
+      if (!t->is_client) {
+        t->ping_recv_state.last_ping_recv_time =
+            gpr_inf_past(GPR_CLOCK_MONOTONIC);
+        t->ping_recv_state.ping_strikes = 0;
+      }
       GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, announce_window, announce);
     }
     if (sent_initial_metadata) {
@@ -241,7 +267,7 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
                 (int64_t)t->settings[GRPC_PEER_SETTINGS]
                                     [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
         uint32_t max_outgoing = (uint32_t)GPR_MIN(
-            t->settings[GRPC_ACKED_SETTINGS]
+            t->settings[GRPC_PEER_SETTINGS]
                        [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
             GPR_MIN(stream_outgoing_window, t->outgoing_window));
         if (max_outgoing > 0) {
@@ -262,6 +288,11 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
                                            send_bytes);
           t->ping_state.pings_before_data_required =
               t->ping_policy.max_pings_without_data;
+          if (!t->is_client) {
+            t->ping_recv_state.last_ping_recv_time =
+                gpr_inf_past(GPR_CLOCK_MONOTONIC);
+            t->ping_recv_state.ping_strikes = 0;
+          }
           if (is_last_frame) {
             s->send_trailing_metadata = NULL;
             s->sent_trailing_metadata = true;
@@ -292,11 +323,21 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
           grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, 0, true,
                                   &s->stats.outgoing, &t->outbuf);
         } else {
-          grpc_chttp2_encode_header(
-              exec_ctx, &t->hpack_compressor, s->id, s->send_trailing_metadata,
-              true, t->settings[GRPC_ACKED_SETTINGS]
-                               [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
-              &s->stats.outgoing, &t->outbuf);
+          grpc_encode_header_options hopt = {
+              .stream_id = s->id,
+              .is_eof = true,
+              .use_true_binary_metadata =
+                  t->settings
+                      [GRPC_PEER_SETTINGS]
+                      [GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA] !=
+                  0,
+              .max_frame_size =
+                  t->settings[GRPC_PEER_SETTINGS]
+                             [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
+              .stats = &s->stats.outgoing};
+          grpc_chttp2_encode_header(exec_ctx, &t->hpack_compressor,
+                                    s->send_trailing_metadata, &hopt,
+                                    &t->outbuf);
         }
         s->send_trailing_metadata = NULL;
         s->sent_trailing_metadata = true;
@@ -337,6 +378,11 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
                                           0, announced, &throwaway_stats));
     t->ping_state.pings_before_data_required =
         t->ping_policy.max_pings_without_data;
+    if (!t->is_client) {
+      t->ping_recv_state.last_ping_recv_time =
+          gpr_inf_past(GPR_CLOCK_MONOTONIC);
+      t->ping_recv_state.ping_strikes = 0;
+    }
   }
 
   for (size_t i = 0; i < t->ping_ack_count; i++) {
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
index 01a03533daf16338068cfe7a114760e782d2ce6f..67974b0b6a696743531ff41f9255b74d5fcf31f5 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.c
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -54,6 +54,7 @@
 #include "third_party/objective_c/Cronet/bidirectional_stream_c.h"
 
 #define GRPC_HEADER_SIZE_IN_BYTES 5
+#define GRPC_FLUSH_READ_SIZE 4096
 
 #define CRONET_LOG(...)                          \
   do {                                           \
@@ -127,6 +128,7 @@ struct read_state {
   int received_bytes;
   int remaining_bytes;
   int length_field;
+  bool compressed;
   char grpc_header_bytes[GRPC_HEADER_SIZE_IN_BYTES];
   char *payload_field;
   bool read_stream_closed;
@@ -151,11 +153,17 @@ struct write_state {
 struct op_state {
   bool state_op_done[OP_NUM_OPS];
   bool state_callback_received[OP_NUM_OPS];
+  /* A non-zero gRPC status code has been seen */
   bool fail_state;
+  /* Transport is discarding all buffered messages */
   bool flush_read;
   bool flush_cronet_when_ready;
   bool pending_write_for_trailer;
-  bool unprocessed_send_message;
+  bool pending_send_message;
+  /* User requested RECV_TRAILING_METADATA */
+  bool pending_recv_trailing_metadata;
+  /* Cronet has not issued a callback of a bidirectional read */
+  bool pending_read_from_cronet;
   grpc_error *cancel_error;
   /* data structure for storing data coming from server */
   struct read_state rs;
@@ -164,7 +172,7 @@ struct op_state {
 };
 
 struct op_and_state {
-  grpc_transport_stream_op op;
+  grpc_transport_stream_op_batch op;
   struct op_state state;
   bool done;
   struct stream_obj *s;      /* Pointer back to the stream object */
@@ -177,8 +185,9 @@ struct op_storage {
 };
 
 struct stream_obj {
+  gpr_arena *arena;
   struct op_and_state *oas;
-  grpc_transport_stream_op *curr_op;
+  grpc_transport_stream_op_batch *curr_op;
   grpc_cronet_transport *curr_ct;
   grpc_stream *curr_gs;
   bidirectional_stream *cbs;
@@ -248,16 +257,40 @@ static const char *op_id_string(enum e_op_id i) {
   return "UNKNOWN";
 }
 
-static void free_read_buffer(stream_obj *s) {
+static void null_and_maybe_free_read_buffer(stream_obj *s) {
   if (s->state.rs.read_buffer &&
       s->state.rs.read_buffer != s->state.rs.grpc_header_bytes) {
     gpr_free(s->state.rs.read_buffer);
-    s->state.rs.read_buffer = NULL;
+  }
+  s->state.rs.read_buffer = NULL;
+}
+
+static void maybe_flush_read(stream_obj *s) {
+  /* To enter flush read state (discarding all the buffered messages in
+   * transport layer), two conditions must be satisfied: 1) non-zero grpc status
+   * has been received, and 2) an op requesting the status code
+   * (RECV_TRAILING_METADATA) is issued by the user. (See
+   * doc/status_ordering.md) */
+  /* Whenever the evaluation of any of the two condition is changed, we check
+   * whether we should enter the flush read state. */
+  if (s->state.pending_recv_trailing_metadata && s->state.fail_state) {
+    if (!s->state.flush_read && !s->state.rs.read_stream_closed) {
+      CRONET_LOG(GPR_DEBUG, "%p: Flush read", s);
+      s->state.flush_read = true;
+      null_and_maybe_free_read_buffer(s);
+      s->state.rs.read_buffer = gpr_malloc(GRPC_FLUSH_READ_SIZE);
+      if (!s->state.pending_read_from_cronet) {
+        CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
+        bidirectional_stream_read(s->cbs, s->state.rs.read_buffer,
+                                  GRPC_FLUSH_READ_SIZE);
+        s->state.pending_read_from_cronet = true;
+      }
+    }
   }
 }
 
 static grpc_error *make_error_with_desc(int error_code, const char *desc) {
-  grpc_error *error = GRPC_ERROR_CREATE(desc);
+  grpc_error *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(desc);
   error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, error_code);
   return error;
 }
@@ -265,12 +298,13 @@ static grpc_error *make_error_with_desc(int error_code, const char *desc) {
 /*
   Add a new stream op to op storage.
 */
-static void add_to_storage(struct stream_obj *s, grpc_transport_stream_op *op) {
+static void add_to_storage(struct stream_obj *s,
+                           grpc_transport_stream_op_batch *op) {
   struct op_storage *storage = &s->storage;
   /* add new op at the beginning of the linked list. The memory is freed
   in remove_from_storage */
   struct op_and_state *new_op = gpr_malloc(sizeof(struct op_and_state));
-  memcpy(&new_op->op, op, sizeof(grpc_transport_stream_op));
+  memcpy(&new_op->op, op, sizeof(grpc_transport_stream_op_batch));
   memset(&new_op->state, 0, sizeof(new_op->state));
   new_op->s = s;
   new_op->done = false;
@@ -279,7 +313,11 @@ static void add_to_storage(struct stream_obj *s, grpc_transport_stream_op *op) {
   storage->head = new_op;
   storage->num_pending_ops++;
   if (op->send_message) {
-    s->state.unprocessed_send_message = true;
+    s->state.pending_send_message = true;
+  }
+  if (op->recv_trailing_metadata) {
+    s->state.pending_recv_trailing_metadata = true;
+    maybe_flush_read(s);
   }
   CRONET_LOG(GPR_DEBUG, "adding new op %p. %d in the queue.", new_op,
              storage->num_pending_ops);
@@ -367,7 +405,7 @@ static void on_failed(bidirectional_stream *stream, int net_error) {
     gpr_free(s->state.ws.write_buffer);
     s->state.ws.write_buffer = NULL;
   }
-  free_read_buffer(s);
+  null_and_maybe_free_read_buffer(s);
   gpr_mu_unlock(&s->mu);
   execute_from_storage(s);
 }
@@ -390,7 +428,7 @@ static void on_canceled(bidirectional_stream *stream) {
     gpr_free(s->state.ws.write_buffer);
     s->state.ws.write_buffer = NULL;
   }
-  free_read_buffer(s);
+  null_and_maybe_free_read_buffer(s);
   gpr_mu_unlock(&s->mu);
   execute_from_storage(s);
 }
@@ -405,7 +443,7 @@ static void on_succeeded(bidirectional_stream *stream) {
   bidirectional_stream_destroy(s->cbs);
   s->state.state_callback_received[OP_SUCCEEDED] = true;
   s->cbs = NULL;
-  free_read_buffer(s);
+  null_and_maybe_free_read_buffer(s);
   gpr_mu_unlock(&s->mu);
   execute_from_storage(s);
 }
@@ -448,18 +486,31 @@ static void on_response_headers_received(
   CRONET_LOG(GPR_DEBUG, "R: on_response_headers_received(%p, %p, %s)", stream,
              headers, negotiated_protocol);
   stream_obj *s = (stream_obj *)stream->annotation;
+
+  /* Identify if this is a header or a trailer (in a trailer-only response case)
+   */
+  for (size_t i = 0; i < headers->count; i++) {
+    if (0 == strcmp("grpc-status", headers->headers[i].key)) {
+      on_response_trailers_received(stream, headers);
+      return;
+    }
+  }
+
   gpr_mu_lock(&s->mu);
   memset(&s->state.rs.initial_metadata, 0,
          sizeof(s->state.rs.initial_metadata));
-  grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.initial_metadata);
+  grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.initial_metadata,
+                                            s->arena);
   for (size_t i = 0; i < headers->count; i++) {
-    grpc_chttp2_incoming_metadata_buffer_add(
-        &s->state.rs.initial_metadata,
-        grpc_mdelem_from_slices(
-            &exec_ctx, grpc_slice_intern(grpc_slice_from_static_string(
-                           headers->headers[i].key)),
-            grpc_slice_intern(
-                grpc_slice_from_static_string(headers->headers[i].value))));
+    GRPC_LOG_IF_ERROR(
+        "on_response_headers_received",
+        grpc_chttp2_incoming_metadata_buffer_add(
+            &exec_ctx, &s->state.rs.initial_metadata,
+            grpc_mdelem_from_slices(
+                &exec_ctx, grpc_slice_intern(grpc_slice_from_static_string(
+                               headers->headers[i].key)),
+                grpc_slice_intern(grpc_slice_from_static_string(
+                    headers->headers[i].value)))));
   }
   s->state.state_callback_received[OP_RECV_INITIAL_METADATA] = true;
   if (!(s->state.state_op_done[OP_CANCEL_ERROR] ||
@@ -468,11 +519,13 @@ static void on_response_headers_received(
      is closed */
     GPR_ASSERT(s->state.rs.length_field_received == false);
     s->state.rs.read_buffer = s->state.rs.grpc_header_bytes;
+    s->state.rs.compressed = false;
     s->state.rs.received_bytes = 0;
     s->state.rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES;
     CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
     bidirectional_stream_read(s->cbs, s->state.rs.read_buffer,
                               s->state.rs.remaining_bytes);
+    s->state.pending_read_from_cronet = true;
   }
   gpr_mu_unlock(&s->mu);
   grpc_exec_ctx_finish(&exec_ctx);
@@ -504,10 +557,13 @@ static void on_read_completed(bidirectional_stream *stream, char *data,
   CRONET_LOG(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data,
              count);
   gpr_mu_lock(&s->mu);
+  s->state.pending_read_from_cronet = false;
   s->state.state_callback_received[OP_RECV_MESSAGE] = true;
   if (count > 0 && s->state.flush_read) {
     CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
-    bidirectional_stream_read(s->cbs, s->state.rs.read_buffer, 4096);
+    bidirectional_stream_read(s->cbs, s->state.rs.read_buffer,
+                              GRPC_FLUSH_READ_SIZE);
+    s->state.pending_read_from_cronet = true;
     gpr_mu_unlock(&s->mu);
   } else if (count > 0) {
     s->state.rs.received_bytes += count;
@@ -518,16 +574,14 @@ static void on_read_completed(bidirectional_stream *stream, char *data,
       bidirectional_stream_read(
           s->cbs, s->state.rs.read_buffer + s->state.rs.received_bytes,
           s->state.rs.remaining_bytes);
+      s->state.pending_read_from_cronet = true;
       gpr_mu_unlock(&s->mu);
     } else {
       gpr_mu_unlock(&s->mu);
       execute_from_storage(s);
     }
   } else {
-    if (s->state.flush_read) {
-      gpr_free(s->state.rs.read_buffer);
-      s->state.rs.read_buffer = NULL;
-    }
+    null_and_maybe_free_read_buffer(s);
     s->state.rs.read_stream_closed = true;
     gpr_mu_unlock(&s->mu);
     execute_from_storage(s);
@@ -549,21 +603,25 @@ static void on_response_trailers_received(
   memset(&s->state.rs.trailing_metadata, 0,
          sizeof(s->state.rs.trailing_metadata));
   s->state.rs.trailing_metadata_valid = false;
-  grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.trailing_metadata);
+  grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.trailing_metadata,
+                                            s->arena);
   for (size_t i = 0; i < trailers->count; i++) {
     CRONET_LOG(GPR_DEBUG, "trailer key=%s, value=%s", trailers->headers[i].key,
                trailers->headers[i].value);
-    grpc_chttp2_incoming_metadata_buffer_add(
-        &s->state.rs.trailing_metadata,
-        grpc_mdelem_from_slices(
-            &exec_ctx, grpc_slice_intern(grpc_slice_from_static_string(
-                           trailers->headers[i].key)),
-            grpc_slice_intern(
-                grpc_slice_from_static_string(trailers->headers[i].value))));
+    GRPC_LOG_IF_ERROR(
+        "on_response_trailers_received",
+        grpc_chttp2_incoming_metadata_buffer_add(
+            &exec_ctx, &s->state.rs.trailing_metadata,
+            grpc_mdelem_from_slices(
+                &exec_ctx, grpc_slice_intern(grpc_slice_from_static_string(
+                               trailers->headers[i].key)),
+                grpc_slice_intern(grpc_slice_from_static_string(
+                    trailers->headers[i].value)))));
     s->state.rs.trailing_metadata_valid = true;
     if (0 == strcmp(trailers->headers[i].key, "grpc-status") &&
         0 != strcmp(trailers->headers[i].value, "0")) {
       s->state.fail_state = true;
+      maybe_flush_read(s);
     }
   }
   s->state.state_callback_received[OP_RECV_TRAILING_METADATA] = true;
@@ -596,7 +654,7 @@ static void on_response_trailers_received(
 */
 static void create_grpc_frame(grpc_slice_buffer *write_slice_buffer,
                               char **pp_write_buffer,
-                              size_t *p_write_buffer_size) {
+                              size_t *p_write_buffer_size, uint32_t flags) {
   grpc_slice slice = grpc_slice_buffer_take_first(write_slice_buffer);
   size_t length = GRPC_SLICE_LENGTH(slice);
   *p_write_buffer_size = length + GRPC_HEADER_SIZE_IN_BYTES;
@@ -605,7 +663,9 @@ static void create_grpc_frame(grpc_slice_buffer *write_slice_buffer,
   *pp_write_buffer = write_buffer;
   uint8_t *p = (uint8_t *)write_buffer;
   /* Append 5 byte header */
-  *p++ = 0;
+  /* Compressed flag */
+  *p++ = (flags & GRPC_WRITE_INTERNAL_COMPRESS) ? 1 : 0;
+  /* Message length */
   *p++ = (uint8_t)(length >> 24);
   *p++ = (uint8_t)(length >> 16);
   *p++ = (uint8_t)(length >> 8);
@@ -683,14 +743,16 @@ static void convert_metadata_to_cronet_headers(
   *p_num_headers = (size_t)num_headers;
 }
 
-static int parse_grpc_header(const uint8_t *data) {
+static void parse_grpc_header(const uint8_t *data, int *length,
+                              bool *compressed) {
+  const uint8_t c = *data;
   const uint8_t *p = data + 1;
-  int length = 0;
-  length |= ((uint8_t)*p++) << 24;
-  length |= ((uint8_t)*p++) << 16;
-  length |= ((uint8_t)*p++) << 8;
-  length |= ((uint8_t)*p++);
-  return length;
+  *compressed = ((c & 0x01) == 0x01);
+  *length = 0;
+  *length |= ((uint8_t)*p++) << 24;
+  *length |= ((uint8_t)*p++) << 16;
+  *length |= ((uint8_t)*p++) << 8;
+  *length |= ((uint8_t)*p++);
 }
 
 static bool header_has_authority(grpc_linked_mdelem *head) {
@@ -707,7 +769,7 @@ static bool header_has_authority(grpc_linked_mdelem *head) {
   Op Execution: Decide if one of the actions contained in the stream op can be
   executed. This is the heart of the state machine.
 */
-static bool op_can_be_run(grpc_transport_stream_op *curr_op,
+static bool op_can_be_run(grpc_transport_stream_op_batch *curr_op,
                           struct stream_obj *s, struct op_state *op_state,
                           enum e_op_id op_id) {
   struct op_state *stream_state = &s->state;
@@ -743,7 +805,8 @@ static bool op_can_be_run(grpc_transport_stream_op *curr_op,
     else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA])
       result = false;
     /* we haven't received headers yet. */
-    else if (!stream_state->state_callback_received[OP_RECV_INITIAL_METADATA])
+    else if (!stream_state->state_callback_received[OP_RECV_INITIAL_METADATA] &&
+             !stream_state->state_op_done[OP_RECV_TRAILING_METADATA])
       result = false;
   } else if (op_id == OP_SEND_MESSAGE) {
     /* already executed (note we're checking op specific state, not stream
@@ -756,7 +819,8 @@ static bool op_can_be_run(grpc_transport_stream_op *curr_op,
     /* already executed */
     if (op_state->state_op_done[OP_RECV_MESSAGE]) result = false;
     /* we haven't received headers yet. */
-    else if (!stream_state->state_callback_received[OP_RECV_INITIAL_METADATA])
+    else if (!stream_state->state_callback_received[OP_RECV_INITIAL_METADATA] &&
+             !stream_state->state_op_done[OP_RECV_TRAILING_METADATA])
       result = false;
   } else if (op_id == OP_RECV_TRAILING_METADATA) {
     /* already executed */
@@ -778,7 +842,7 @@ static bool op_can_be_run(grpc_transport_stream_op *curr_op,
     else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA])
       result = false;
     /* we haven't sent message yet */
-    else if (stream_state->unprocessed_send_message &&
+    else if (stream_state->pending_send_message &&
              !stream_state->state_op_done[OP_SEND_MESSAGE])
       result = false;
     /* we haven't got on_write_completed for the send yet */
@@ -822,6 +886,10 @@ static bool op_can_be_run(grpc_transport_stream_op *curr_op,
                !stream_state->state_op_done[OP_RECV_MESSAGE]) {
       CRONET_LOG(GPR_DEBUG, "Because");
       result = false;
+    } else if (curr_op->cancel_stream &&
+               !stream_state->state_callback_received[OP_CANCELED]) {
+      CRONET_LOG(GPR_DEBUG, "Because");
+      result = false;
     } else if (curr_op->recv_trailing_metadata) {
       /* We aren't done with trailing metadata yet */
       if (!stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) {
@@ -856,7 +924,7 @@ static bool op_can_be_run(grpc_transport_stream_op *curr_op,
 */
 static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
                                           struct op_and_state *oas) {
-  grpc_transport_stream_op *stream_op = &oas->op;
+  grpc_transport_stream_op_batch *stream_op = &oas->op;
   struct stream_obj *s = oas->s;
   grpc_cronet_transport *t = (grpc_cronet_transport *)s->curr_ct;
   struct op_state *stream_state = &s->state;
@@ -878,9 +946,10 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
     char *url = NULL;
     const char *method = "POST";
     s->header_array.headers = NULL;
-    convert_metadata_to_cronet_headers(
-        stream_op->send_initial_metadata->list.head, t->host, &url,
-        &s->header_array.headers, &s->header_array.count, &method);
+    convert_metadata_to_cronet_headers(stream_op->payload->send_initial_metadata
+                                           .send_initial_metadata->list.head,
+                                       t->host, &url, &s->header_array.headers,
+                                       &s->header_array.count, &method);
     s->header_array.capacity = s->header_array.count;
     CRONET_LOG(GPR_DEBUG, "bidirectional_stream_start(%p, %s)", s->cbs, url);
     bidirectional_stream_start(s->cbs, url, 0, method, &s->header_array, false);
@@ -900,7 +969,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
   } else if (stream_op->send_message &&
              op_can_be_run(stream_op, s, &oas->state, OP_SEND_MESSAGE)) {
     CRONET_LOG(GPR_DEBUG, "running: %p  OP_SEND_MESSAGE", oas);
-    stream_state->unprocessed_send_message = false;
+    stream_state->pending_send_message = false;
     if (stream_state->state_callback_received[OP_FAILED]) {
       result = NO_ACTION_POSSIBLE;
       CRONET_LOG(GPR_DEBUG, "Stream is either cancelled or failed.");
@@ -908,13 +977,19 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
       grpc_slice_buffer write_slice_buffer;
       grpc_slice slice;
       grpc_slice_buffer_init(&write_slice_buffer);
-      grpc_byte_stream_next(NULL, stream_op->send_message, &slice,
-                            stream_op->send_message->length, NULL);
-      /* Check that compression flag is OFF. We don't support compression yet.
-       */
-      if (stream_op->send_message->flags != 0) {
-        gpr_log(GPR_ERROR, "Compression is not supported");
-        GPR_ASSERT(stream_op->send_message->flags == 0);
+      if (1 != grpc_byte_stream_next(
+                   exec_ctx, stream_op->payload->send_message.send_message,
+                   stream_op->payload->send_message.send_message->length,
+                   NULL)) {
+        /* Should never reach here */
+        GPR_ASSERT(false);
+      }
+      if (GRPC_ERROR_NONE !=
+          grpc_byte_stream_pull(exec_ctx,
+                                stream_op->payload->send_message.send_message,
+                                &slice)) {
+        /* Should never reach here */
+        GPR_ASSERT(false);
       }
       grpc_slice_buffer_add(&write_slice_buffer, slice);
       if (write_slice_buffer.count != 1) {
@@ -925,7 +1000,8 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
       if (write_slice_buffer.count > 0) {
         size_t write_buffer_size;
         create_grpc_frame(&write_slice_buffer, &stream_state->ws.write_buffer,
-                          &write_buffer_size);
+                          &write_buffer_size,
+                          stream_op->payload->send_message.send_message->flags);
         CRONET_LOG(GPR_DEBUG, "bidirectional_stream_write (%p, %p)", s->cbs,
                    stream_state->ws.write_buffer);
         stream_state->state_callback_received[OP_SEND_MESSAGE] = false;
@@ -972,17 +1048,28 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
                            OP_RECV_INITIAL_METADATA)) {
     CRONET_LOG(GPR_DEBUG, "running: %p  OP_RECV_INITIAL_METADATA", oas);
     if (stream_state->state_op_done[OP_CANCEL_ERROR]) {
-      grpc_closure_sched(exec_ctx, stream_op->recv_initial_metadata_ready,
-                         GRPC_ERROR_NONE);
+      grpc_closure_sched(
+          exec_ctx,
+          stream_op->payload->recv_initial_metadata.recv_initial_metadata_ready,
+          GRPC_ERROR_NONE);
     } else if (stream_state->state_callback_received[OP_FAILED]) {
-      grpc_closure_sched(exec_ctx, stream_op->recv_initial_metadata_ready,
-                         GRPC_ERROR_NONE);
+      grpc_closure_sched(
+          exec_ctx,
+          stream_op->payload->recv_initial_metadata.recv_initial_metadata_ready,
+          GRPC_ERROR_NONE);
+    } else if (stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) {
+      grpc_closure_sched(
+          exec_ctx,
+          stream_op->payload->recv_initial_metadata.recv_initial_metadata_ready,
+          GRPC_ERROR_NONE);
     } else {
       grpc_chttp2_incoming_metadata_buffer_publish(
           exec_ctx, &oas->s->state.rs.initial_metadata,
-          stream_op->recv_initial_metadata);
-      grpc_closure_sched(exec_ctx, stream_op->recv_initial_metadata_ready,
-                         GRPC_ERROR_NONE);
+          stream_op->payload->recv_initial_metadata.recv_initial_metadata);
+      grpc_closure_sched(
+          exec_ctx,
+          stream_op->payload->recv_initial_metadata.recv_initial_metadata_ready,
+          GRPC_ERROR_NONE);
     }
     stream_state->state_op_done[OP_RECV_INITIAL_METADATA] = true;
     result = ACTION_TAKEN_NO_CALLBACK;
@@ -991,20 +1078,31 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
     CRONET_LOG(GPR_DEBUG, "running: %p  OP_RECV_MESSAGE", oas);
     if (stream_state->state_op_done[OP_CANCEL_ERROR]) {
       CRONET_LOG(GPR_DEBUG, "Stream is cancelled.");
-      grpc_closure_sched(exec_ctx, stream_op->recv_message_ready,
+      grpc_closure_sched(exec_ctx,
+                         stream_op->payload->recv_message.recv_message_ready,
                          GRPC_ERROR_NONE);
       stream_state->state_op_done[OP_RECV_MESSAGE] = true;
       result = ACTION_TAKEN_NO_CALLBACK;
     } else if (stream_state->state_callback_received[OP_FAILED]) {
       CRONET_LOG(GPR_DEBUG, "Stream failed.");
-      grpc_closure_sched(exec_ctx, stream_op->recv_message_ready,
+      grpc_closure_sched(exec_ctx,
+                         stream_op->payload->recv_message.recv_message_ready,
                          GRPC_ERROR_NONE);
       stream_state->state_op_done[OP_RECV_MESSAGE] = true;
       result = ACTION_TAKEN_NO_CALLBACK;
     } else if (stream_state->rs.read_stream_closed == true) {
       /* No more data will be received */
       CRONET_LOG(GPR_DEBUG, "read stream closed");
-      grpc_closure_sched(exec_ctx, stream_op->recv_message_ready,
+      grpc_closure_sched(exec_ctx,
+                         stream_op->payload->recv_message.recv_message_ready,
+                         GRPC_ERROR_NONE);
+      stream_state->state_op_done[OP_RECV_MESSAGE] = true;
+      oas->state.state_op_done[OP_RECV_MESSAGE] = true;
+      result = ACTION_TAKEN_NO_CALLBACK;
+    } else if (stream_state->flush_read) {
+      CRONET_LOG(GPR_DEBUG, "flush read");
+      grpc_closure_sched(exec_ctx,
+                         stream_op->payload->recv_message.recv_message_ready,
                          GRPC_ERROR_NONE);
       stream_state->state_op_done[OP_RECV_MESSAGE] = true;
       oas->state.state_op_done[OP_RECV_MESSAGE] = true;
@@ -1014,8 +1112,9 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
           stream_state->rs.remaining_bytes == 0) {
         /* Start a read operation for data */
         stream_state->rs.length_field_received = true;
-        stream_state->rs.length_field = stream_state->rs.remaining_bytes =
-            parse_grpc_header((const uint8_t *)stream_state->rs.read_buffer);
+        parse_grpc_header((const uint8_t *)stream_state->rs.read_buffer,
+                          &stream_state->rs.length_field,
+                          &stream_state->rs.compressed);
         CRONET_LOG(GPR_DEBUG, "length field = %d",
                    stream_state->rs.length_field);
         if (stream_state->rs.length_field > 0) {
@@ -1029,6 +1128,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
               true; /* Indicates that at least one read request has been made */
           bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
                                     stream_state->rs.remaining_bytes);
+          stream_state->pending_read_from_cronet = true;
           result = ACTION_TAKEN_WITH_CALLBACK;
         } else {
           stream_state->rs.remaining_bytes = 0;
@@ -1036,10 +1136,15 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
           grpc_slice_buffer_init(&stream_state->rs.read_slice_buffer);
           grpc_slice_buffer_stream_init(&stream_state->rs.sbs,
                                         &stream_state->rs.read_slice_buffer, 0);
-          *((grpc_byte_buffer **)stream_op->recv_message) =
+          if (stream_state->rs.compressed) {
+            stream_state->rs.sbs.base.flags |= GRPC_WRITE_INTERNAL_COMPRESS;
+          }
+          *((grpc_byte_buffer **)
+                stream_op->payload->recv_message.recv_message) =
               (grpc_byte_buffer *)&stream_state->rs.sbs;
-          grpc_closure_sched(exec_ctx, stream_op->recv_message_ready,
-                             GRPC_ERROR_NONE);
+          grpc_closure_sched(
+              exec_ctx, stream_op->payload->recv_message.recv_message_ready,
+              GRPC_ERROR_NONE);
           stream_state->state_op_done[OP_RECV_MESSAGE] = true;
           oas->state.state_op_done[OP_RECV_MESSAGE] = true;
 
@@ -1047,11 +1152,14 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
           stream_state->rs.read_buffer = stream_state->rs.grpc_header_bytes;
           stream_state->rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES;
           stream_state->rs.received_bytes = 0;
+          stream_state->rs.compressed = false;
+          stream_state->rs.length_field_received = false;
           CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
           stream_state->state_op_done[OP_READ_REQ_MADE] =
               true; /* Indicates that at least one read request has been made */
           bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
                                     stream_state->rs.remaining_bytes);
+          stream_state->pending_read_from_cronet = true;
           result = ACTION_TAKEN_NO_CALLBACK;
         }
       } else if (stream_state->rs.remaining_bytes == 0) {
@@ -1059,11 +1167,13 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
         stream_state->rs.read_buffer = stream_state->rs.grpc_header_bytes;
         stream_state->rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES;
         stream_state->rs.received_bytes = 0;
+        stream_state->rs.compressed = false;
         CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
         stream_state->state_op_done[OP_READ_REQ_MADE] =
             true; /* Indicates that at least one read request has been made */
         bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
                                   stream_state->rs.remaining_bytes);
+        stream_state->pending_read_from_cronet = true;
         result = ACTION_TAKEN_WITH_CALLBACK;
       } else {
         result = NO_ACTION_POSSIBLE;
@@ -1071,31 +1181,37 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
     } else if (stream_state->rs.remaining_bytes == 0) {
       CRONET_LOG(GPR_DEBUG, "read operation complete");
       grpc_slice read_data_slice =
-          grpc_slice_malloc((uint32_t)stream_state->rs.length_field);
+          GRPC_SLICE_MALLOC((uint32_t)stream_state->rs.length_field);
       uint8_t *dst_p = GRPC_SLICE_START_PTR(read_data_slice);
       memcpy(dst_p, stream_state->rs.read_buffer,
              (size_t)stream_state->rs.length_field);
-      free_read_buffer(s);
+      null_and_maybe_free_read_buffer(s);
       grpc_slice_buffer_init(&stream_state->rs.read_slice_buffer);
       grpc_slice_buffer_add(&stream_state->rs.read_slice_buffer,
                             read_data_slice);
       grpc_slice_buffer_stream_init(&stream_state->rs.sbs,
                                     &stream_state->rs.read_slice_buffer, 0);
-      *((grpc_byte_buffer **)stream_op->recv_message) =
+      if (stream_state->rs.compressed) {
+        stream_state->rs.sbs.base.flags = GRPC_WRITE_INTERNAL_COMPRESS;
+      }
+      *((grpc_byte_buffer **)stream_op->payload->recv_message.recv_message) =
           (grpc_byte_buffer *)&stream_state->rs.sbs;
-      grpc_closure_sched(exec_ctx, stream_op->recv_message_ready,
+      grpc_closure_sched(exec_ctx,
+                         stream_op->payload->recv_message.recv_message_ready,
                          GRPC_ERROR_NONE);
       stream_state->state_op_done[OP_RECV_MESSAGE] = true;
       oas->state.state_op_done[OP_RECV_MESSAGE] = true;
       /* Do an extra read to trigger on_succeeded() callback in case connection
          is closed */
       stream_state->rs.read_buffer = stream_state->rs.grpc_header_bytes;
+      stream_state->rs.compressed = false;
       stream_state->rs.received_bytes = 0;
       stream_state->rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES;
       stream_state->rs.length_field_received = false;
       CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
       bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
                                 stream_state->rs.remaining_bytes);
+      stream_state->pending_read_from_cronet = true;
       result = ACTION_TAKEN_NO_CALLBACK;
     }
   } else if (stream_op->recv_trailing_metadata &&
@@ -1105,12 +1221,12 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
     if (oas->s->state.rs.trailing_metadata_valid) {
       grpc_chttp2_incoming_metadata_buffer_publish(
           exec_ctx, &oas->s->state.rs.trailing_metadata,
-          stream_op->recv_trailing_metadata);
+          stream_op->payload->recv_trailing_metadata.recv_trailing_metadata);
       stream_state->rs.trailing_metadata_valid = false;
     }
     stream_state->state_op_done[OP_RECV_TRAILING_METADATA] = true;
     result = ACTION_TAKEN_NO_CALLBACK;
-  } else if (stream_op->cancel_error &&
+  } else if (stream_op->cancel_stream &&
              op_can_be_run(stream_op, s, &oas->state, OP_CANCEL_ERROR)) {
     CRONET_LOG(GPR_DEBUG, "running: %p  OP_CANCEL_ERROR", oas);
     CRONET_LOG(GPR_DEBUG, "W: bidirectional_stream_cancel(%p)", s->cbs);
@@ -1122,7 +1238,8 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
     }
     stream_state->state_op_done[OP_CANCEL_ERROR] = true;
     if (!stream_state->cancel_error) {
-      stream_state->cancel_error = GRPC_ERROR_REF(stream_op->cancel_error);
+      stream_state->cancel_error =
+          GRPC_ERROR_REF(stream_op->payload->cancel_stream.cancel_error);
     }
   } else if (stream_op->on_complete &&
              op_can_be_run(stream_op, s, &oas->state, OP_ON_COMPLETE)) {
@@ -1153,15 +1270,6 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
       make a note */
     if (stream_op->recv_message)
       stream_state->state_op_done[OP_RECV_MESSAGE_AND_ON_COMPLETE] = true;
-  } else if (stream_state->fail_state && !stream_state->flush_read) {
-    CRONET_LOG(GPR_DEBUG, "running: %p  flush read", oas);
-    if (stream_state->rs.read_buffer &&
-        stream_state->rs.read_buffer != stream_state->rs.grpc_header_bytes) {
-      gpr_free(stream_state->rs.read_buffer);
-      stream_state->rs.read_buffer = NULL;
-    }
-    stream_state->rs.read_buffer = gpr_malloc(4096);
-    stream_state->flush_read = true;
   } else {
     result = NO_ACTION_POSSIBLE;
   }
@@ -1174,7 +1282,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
 
 static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
                        grpc_stream *gs, grpc_stream_refcount *refcount,
-                       const void *server_data) {
+                       const void *server_data, gpr_arena *arena) {
   stream_obj *s = (stream_obj *)gs;
   memset(&s->storage, 0, sizeof(s->storage));
   s->storage.head = NULL;
@@ -1190,10 +1298,13 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
   s->state.fail_state = s->state.flush_read = false;
   s->state.cancel_error = NULL;
   s->state.flush_cronet_when_ready = s->state.pending_write_for_trailer = false;
-  s->state.unprocessed_send_message = false;
+  s->state.pending_send_message = false;
+  s->state.pending_recv_trailing_metadata = false;
+  s->state.pending_read_from_cronet = false;
 
   s->curr_gs = gs;
   s->curr_ct = (grpc_cronet_transport *)gt;
+  s->arena = arena;
 
   gpr_mu_init(&s->mu);
   return 0;
@@ -1207,40 +1318,39 @@ static void set_pollset_set_do_nothing(grpc_exec_ctx *exec_ctx,
                                        grpc_pollset_set *pollset_set) {}
 
 static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
-                              grpc_stream *gs, grpc_transport_stream_op *op) {
+                              grpc_stream *gs,
+                              grpc_transport_stream_op_batch *op) {
   CRONET_LOG(GPR_DEBUG, "perform_stream_op");
-  stream_obj *s = (stream_obj *)gs;
-  add_to_storage(s, op);
   if (op->send_initial_metadata &&
-      header_has_authority(op->send_initial_metadata->list.head)) {
+      header_has_authority(op->payload->send_initial_metadata
+                               .send_initial_metadata->list.head)) {
     /* Cronet does not support :authority header field. We cancel the call when
-       this field is present in metadata */
-    bidirectional_stream_header_array header_array;
-    bidirectional_stream_header *header;
-    bidirectional_stream cbs;
-    CRONET_LOG(GPR_DEBUG,
-               ":authority header is provided but not supported;"
-               " cancel operations");
-    /* Notify application that operation is cancelled by forging trailers */
-    header_array.count = 1;
-    header_array.capacity = 1;
-    header_array.headers = gpr_malloc(sizeof(bidirectional_stream_header));
-    header = (bidirectional_stream_header *)header_array.headers;
-    header->key = "grpc-status";
-    header->value = "1"; /* Return status GRPC_STATUS_CANCELLED */
-    cbs.annotation = (void *)s;
-    s->state.state_op_done[OP_CANCEL_ERROR] = true;
-    on_response_trailers_received(&cbs, &header_array);
-    gpr_free(header_array.headers);
-  } else {
-    execute_from_storage(s);
+     this field is present in metadata */
+    if (op->recv_initial_metadata) {
+      grpc_closure_sched(
+          exec_ctx,
+          op->payload->recv_initial_metadata.recv_initial_metadata_ready,
+          GRPC_ERROR_CANCELLED);
+    }
+    if (op->recv_message) {
+      grpc_closure_sched(exec_ctx, op->payload->recv_message.recv_message_ready,
+                         GRPC_ERROR_CANCELLED);
+    }
+    grpc_closure_sched(exec_ctx, op->on_complete, GRPC_ERROR_CANCELLED);
+    return;
   }
+  stream_obj *s = (stream_obj *)gs;
+  add_to_storage(s, op);
+  execute_from_storage(s);
 }
 
 static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
-                           grpc_stream *gs, void *and_free_memory) {
+                           grpc_stream *gs,
+                           grpc_closure *then_schedule_closure) {
   stream_obj *s = (stream_obj *)gs;
+  null_and_maybe_free_read_buffer(s);
   GRPC_ERROR_UNREF(s->state.cancel_error);
+  grpc_closure_sched(exec_ctx, then_schedule_closure, GRPC_ERROR_NONE);
 }
 
 static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) {}
diff --git a/src/core/lib/channel/channel_args.c b/src/core/lib/channel/channel_args.c
index 1a099ac437a19abcc89dee19bf67309af9a8a2ea..238d176dfae724a968ace9c894d470c9333fc008 100644
--- a/src/core/lib/channel/channel_args.c
+++ b/src/core/lib/channel/channel_args.c
@@ -31,17 +31,18 @@
  *
  */
 
-#include "src/core/lib/channel/channel_args.h"
-#include <grpc/grpc.h>
-#include "src/core/lib/support/string.h"
+#include <limits.h>
+#include <string.h>
 
 #include <grpc/compression.h>
+#include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
 
-#include <string.h>
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/support/string.h"
 
 static grpc_arg copy_arg(const grpc_arg *src) {
   grpc_arg dst;
@@ -329,7 +330,9 @@ const grpc_arg *grpc_channel_args_find(const grpc_channel_args *args,
   return NULL;
 }
 
-int grpc_channel_arg_get_integer(grpc_arg *arg, grpc_integer_options options) {
+int grpc_channel_arg_get_integer(const grpc_arg *arg,
+                                 const grpc_integer_options options) {
+  if (arg == NULL) return options.default_value;
   if (arg->type != GRPC_ARG_INTEGER) {
     gpr_log(GPR_ERROR, "%s ignored: it must be an integer", arg->key);
     return options.default_value;
@@ -346,3 +349,26 @@ int grpc_channel_arg_get_integer(grpc_arg *arg, grpc_integer_options options) {
   }
   return arg->value.integer;
 }
+
+bool grpc_channel_arg_get_bool(const grpc_arg *arg, bool default_value) {
+  if (arg == NULL) return default_value;
+  if (arg->type != GRPC_ARG_INTEGER) {
+    gpr_log(GPR_ERROR, "%s ignored: it must be an integer", arg->key);
+    return default_value;
+  }
+  switch (arg->value.integer) {
+    case 0:
+      return false;
+    case 1:
+      return true;
+    default:
+      gpr_log(GPR_ERROR, "%s treated as bool but set to %d (assuming true)",
+              arg->key, arg->value.integer);
+      return true;
+  }
+}
+
+bool grpc_channel_args_want_minimal_stack(const grpc_channel_args *args) {
+  return grpc_channel_arg_get_bool(
+      grpc_channel_args_find(args, GRPC_ARG_MINIMAL_STACK), false);
+}
diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h
index 5c7d31f8bba0306ab841bc68ea7db81790ff0f3e..f0f603e25146f594c84c00dc415840de1a3fe9ef 100644
--- a/src/core/lib/channel/channel_args.h
+++ b/src/core/lib/channel/channel_args.h
@@ -113,12 +113,18 @@ grpc_channel_args *grpc_channel_args_set_socket_mutator(
 const grpc_arg *grpc_channel_args_find(const grpc_channel_args *args,
                                        const char *name);
 
+bool grpc_channel_args_want_minimal_stack(const grpc_channel_args *args);
+
 typedef struct grpc_integer_options {
   int default_value;  // Return this if value is outside of expected bounds.
   int min_value;
   int max_value;
 } grpc_integer_options;
+
 /** Returns the value of \a arg, subject to the contraints in \a options. */
-int grpc_channel_arg_get_integer(grpc_arg *arg, grpc_integer_options options);
+int grpc_channel_arg_get_integer(const grpc_arg *arg,
+                                 const grpc_integer_options options);
+
+bool grpc_channel_arg_get_bool(const grpc_arg *arg, bool default_value);
 
 #endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_ARGS_H */
diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c
index 3fb2a60ac719245c0b28db53277728e5d90b74f6..94382980eb3949c4a7942ad4946965ed978a9448 100644
--- a/src/core/lib/channel/channel_stack.c
+++ b/src/core/lib/channel/channel_stack.c
@@ -166,41 +166,32 @@ void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx,
   }
 }
 
-grpc_error *grpc_call_stack_init(
-    grpc_exec_ctx *exec_ctx, grpc_channel_stack *channel_stack,
-    int initial_refs, grpc_iomgr_cb_func destroy, void *destroy_arg,
-    grpc_call_context_element *context, const void *transport_server_data,
-    grpc_slice path, gpr_timespec start_time, gpr_timespec deadline,
-    grpc_call_stack *call_stack) {
+grpc_error *grpc_call_stack_init(grpc_exec_ctx *exec_ctx,
+                                 grpc_channel_stack *channel_stack,
+                                 int initial_refs, grpc_iomgr_cb_func destroy,
+                                 void *destroy_arg,
+                                 const grpc_call_element_args *elem_args) {
   grpc_channel_element *channel_elems = CHANNEL_ELEMS_FROM_STACK(channel_stack);
   size_t count = channel_stack->count;
   grpc_call_element *call_elems;
   char *user_data;
   size_t i;
 
-  call_stack->count = count;
-  GRPC_STREAM_REF_INIT(&call_stack->refcount, initial_refs, destroy,
+  elem_args->call_stack->count = count;
+  GRPC_STREAM_REF_INIT(&elem_args->call_stack->refcount, initial_refs, destroy,
                        destroy_arg, "CALL_STACK");
-  call_elems = CALL_ELEMS_FROM_STACK(call_stack);
+  call_elems = CALL_ELEMS_FROM_STACK(elem_args->call_stack);
   user_data = ((char *)call_elems) +
               ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element));
 
   /* init per-filter data */
   grpc_error *first_error = GRPC_ERROR_NONE;
-  const grpc_call_element_args args = {
-      .start_time = start_time,
-      .call_stack = call_stack,
-      .server_transport_data = transport_server_data,
-      .context = context,
-      .path = path,
-      .deadline = deadline,
-  };
   for (i = 0; i < count; i++) {
     call_elems[i].filter = channel_elems[i].filter;
     call_elems[i].channel_data = channel_elems[i].channel_data;
     call_elems[i].call_data = user_data;
-    grpc_error *error =
-        call_elems[i].filter->init_call_elem(exec_ctx, &call_elems[i], &args);
+    grpc_error *error = call_elems[i].filter->init_call_elem(
+        exec_ctx, &call_elems[i], elem_args);
     if (error != GRPC_ERROR_NONE) {
       if (first_error == GRPC_ERROR_NONE) {
         first_error = error;
@@ -241,22 +232,23 @@ void grpc_call_stack_ignore_set_pollset_or_pollset_set(
 
 void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack,
                              const grpc_call_final_info *final_info,
-                             void *and_free_memory) {
+                             grpc_closure *then_schedule_closure) {
   grpc_call_element *elems = CALL_ELEMS_FROM_STACK(stack);
   size_t count = stack->count;
   size_t i;
 
   /* destroy per-filter data */
   for (i = 0; i < count; i++) {
-    elems[i].filter->destroy_call_elem(exec_ctx, &elems[i], final_info,
-                                       i == count - 1 ? and_free_memory : NULL);
+    elems[i].filter->destroy_call_elem(
+        exec_ctx, &elems[i], final_info,
+        i == count - 1 ? then_schedule_closure : NULL);
   }
 }
 
 void grpc_call_next_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                       grpc_transport_stream_op *op) {
+                       grpc_transport_stream_op_batch *op) {
   grpc_call_element *next_elem = elem + 1;
-  next_elem->filter->start_transport_stream_op(exec_ctx, next_elem, op);
+  next_elem->filter->start_transport_stream_op_batch(exec_ctx, next_elem, op);
 }
 
 char *grpc_call_next_get_peer(grpc_exec_ctx *exec_ctx,
@@ -292,7 +284,8 @@ grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem) {
 void grpc_call_element_signal_error(grpc_exec_ctx *exec_ctx,
                                     grpc_call_element *elem,
                                     grpc_error *error) {
-  grpc_transport_stream_op *op = grpc_make_transport_stream_op(NULL);
-  op->cancel_error = error;
-  elem->filter->start_transport_stream_op(exec_ctx, elem, op);
+  grpc_transport_stream_op_batch *op = grpc_make_transport_stream_op(NULL);
+  op->cancel_stream = true;
+  op->payload->cancel_stream.cancel_error = error;
+  elem->filter->start_transport_stream_op_batch(exec_ctx, elem, op);
 }
diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h
index 6d3340bcbf8cf6e155267077260c642a0dfad977..fdbcbdb01850678dea891625d3e752f6de19992e 100644
--- a/src/core/lib/channel/channel_stack.h
+++ b/src/core/lib/channel/channel_stack.h
@@ -56,6 +56,7 @@
 
 #include "src/core/lib/debug/trace.h"
 #include "src/core/lib/iomgr/polling_entity.h"
+#include "src/core/lib/support/arena.h"
 #include "src/core/lib/transport/transport.h"
 
 #ifdef __cplusplus
@@ -84,6 +85,7 @@ typedef struct {
   grpc_slice path;
   gpr_timespec start_time;
   gpr_timespec deadline;
+  gpr_arena *arena;
 } grpc_call_element_args;
 
 typedef struct {
@@ -110,9 +112,9 @@ typedef struct {
 typedef struct {
   /* Called to eg. send/receive data on a call.
      See grpc_call_next_op on how to call the next element in the stack */
-  void (*start_transport_stream_op)(grpc_exec_ctx *exec_ctx,
-                                    grpc_call_element *elem,
-                                    grpc_transport_stream_op *op);
+  void (*start_transport_stream_op_batch)(grpc_exec_ctx *exec_ctx,
+                                          grpc_call_element *elem,
+                                          grpc_transport_stream_op_batch *op);
   /* Called to handle channel level operations - e.g. new calls, or transport
      closure.
      See grpc_channel_next_op on how to call the next element in the stack */
@@ -139,12 +141,12 @@ typedef struct {
   /* Destroy per call data.
      The filter does not need to do any chaining.
      The bottom filter of a stack will be passed a non-NULL pointer to
-     \a and_free_memory that should be passed to gpr_free when destruction
-     is complete. \a final_info contains data about the completed call, mainly
-     for reporting purposes. */
+     \a then_schedule_closure that should be passed to grpc_closure_sched when
+     destruction is complete. \a final_info contains data about the completed
+     call, mainly for reporting purposes. */
   void (*destroy_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                             const grpc_call_final_info *final_info,
-                            void *and_free_memory);
+                            grpc_closure *then_schedule_closure);
 
   /* sizeof(per channel data) */
   size_t sizeof_channel_data;
@@ -236,12 +238,11 @@ void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx,
 /* Initialize a call stack given a channel stack. transport_server_data is
    expected to be NULL on a client, or an opaque transport owned pointer on the
    server. */
-grpc_error *grpc_call_stack_init(
-    grpc_exec_ctx *exec_ctx, grpc_channel_stack *channel_stack,
-    int initial_refs, grpc_iomgr_cb_func destroy, void *destroy_arg,
-    grpc_call_context_element *context, const void *transport_server_data,
-    grpc_slice path, gpr_timespec start_time, gpr_timespec deadline,
-    grpc_call_stack *call_stack);
+grpc_error *grpc_call_stack_init(grpc_exec_ctx *exec_ctx,
+                                 grpc_channel_stack *channel_stack,
+                                 int initial_refs, grpc_iomgr_cb_func destroy,
+                                 void *destroy_arg,
+                                 const grpc_call_element_args *elem_args);
 /* Set a pollset or a pollset_set for a call stack: must occur before the first
  * op is started */
 void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
@@ -271,7 +272,7 @@ void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
 /* Destroy a call stack */
 void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack,
                              const grpc_call_final_info *final_info,
-                             void *and_free_memory);
+                             grpc_closure *then_schedule_closure);
 
 /* Ignore set pollset{_set} - used by filters if they don't care about pollsets
  * at all. Does nothing. */
@@ -280,7 +281,7 @@ void grpc_call_stack_ignore_set_pollset_or_pollset_set(
     grpc_polling_entity *pollent);
 /* Call the next operation in a call stack */
 void grpc_call_next_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                       grpc_transport_stream_op *op);
+                       grpc_transport_stream_op_batch *op);
 /* Call the next operation (depending on call directionality) in a channel
    stack */
 void grpc_channel_next_op(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem,
@@ -299,7 +300,8 @@ grpc_channel_stack *grpc_channel_stack_from_top_element(
 grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem);
 
 void grpc_call_log_op(char *file, int line, gpr_log_severity severity,
-                      grpc_call_element *elem, grpc_transport_stream_op *op);
+                      grpc_call_element *elem,
+                      grpc_transport_stream_op_batch *op);
 
 void grpc_call_element_signal_error(grpc_exec_ctx *exec_ctx,
                                     grpc_call_element *cur_elem,
diff --git a/src/core/lib/channel/channel_stack_builder.c b/src/core/lib/channel/channel_stack_builder.c
index b515b7321a70d56e1d29bdeb37046ab2244202e8..88c02edb70e423499899a93ac9a1172b6bae06c5 100644
--- a/src/core/lib/channel/channel_stack_builder.c
+++ b/src/core/lib/channel/channel_stack_builder.c
@@ -113,6 +113,17 @@ grpc_channel_stack_builder_create_iterator_at_last(
   return create_iterator_at_filter_node(builder, &builder->end);
 }
 
+bool grpc_channel_stack_builder_iterator_is_end(
+    grpc_channel_stack_builder_iterator *iterator) {
+  return iterator->node == &iterator->builder->end;
+}
+
+const char *grpc_channel_stack_builder_iterator_filter_name(
+    grpc_channel_stack_builder_iterator *iterator) {
+  if (iterator->node->filter == NULL) return NULL;
+  return iterator->node->filter->name;
+}
+
 bool grpc_channel_stack_builder_move_next(
     grpc_channel_stack_builder_iterator *iterator) {
   if (iterator->node == &iterator->builder->end) return false;
diff --git a/src/core/lib/channel/channel_stack_builder.h b/src/core/lib/channel/channel_stack_builder.h
index 8adf38e27bff0a4a232cc7678b9b3908591e85fd..c78111b00d01e744e659b4b7078c0a27dc5aae6f 100644
--- a/src/core/lib/channel/channel_stack_builder.h
+++ b/src/core/lib/channel/channel_stack_builder.h
@@ -98,6 +98,10 @@ bool grpc_channel_stack_builder_iterator_is_first(
 bool grpc_channel_stack_builder_iterator_is_end(
     grpc_channel_stack_builder_iterator *iterator);
 
+/// What is the name of the filter at this iterator position?
+const char *grpc_channel_stack_builder_iterator_filter_name(
+    grpc_channel_stack_builder_iterator *iterator);
+
 /// Move an iterator to the next item
 bool grpc_channel_stack_builder_move_next(
     grpc_channel_stack_builder_iterator *iterator);
diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c
index 29796f7ca7e96546c770cafb2d1d4360198eac01..d8985268ebae2b190593a5a14682aafa8d5fc49d 100644
--- a/src/core/lib/channel/connected_channel.c
+++ b/src/core/lib/channel/connected_channel.c
@@ -62,9 +62,9 @@ typedef struct connected_channel_call_data { void *unused; } call_data;
 
 /* Intercept a call operation and either push it directly up or translate it
    into transport stream operations */
-static void con_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
-                                          grpc_call_element *elem,
-                                          grpc_transport_stream_op *op) {
+static void con_start_transport_stream_op_batch(
+    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+    grpc_transport_stream_op_batch *op) {
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
   GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
@@ -88,9 +88,10 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
   channel_data *chand = elem->channel_data;
   int r = grpc_transport_init_stream(
       exec_ctx, chand->transport, TRANSPORT_STREAM_FROM_CALL_DATA(calld),
-      &args->call_stack->refcount, args->server_transport_data);
+      &args->call_stack->refcount, args->server_transport_data, args->arena);
   return r == 0 ? GRPC_ERROR_NONE
-                : GRPC_ERROR_CREATE("transport stream initialization failed");
+                : GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                      "transport stream initialization failed");
 }
 
 static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
@@ -105,12 +106,12 @@ static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
 /* Destructor for call_data */
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
-                              void *and_free_memory) {
+                              grpc_closure *then_schedule_closure) {
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
   grpc_transport_destroy_stream(exec_ctx, chand->transport,
                                 TRANSPORT_STREAM_FROM_CALL_DATA(calld),
-                                and_free_memory);
+                                then_schedule_closure);
 }
 
 /* Constructor for channel_data */
@@ -127,7 +128,9 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
                                  grpc_channel_element *elem) {
   channel_data *cd = (channel_data *)elem->channel_data;
-  grpc_transport_destroy(exec_ctx, cd->transport);
+  if (cd->transport) {
+    grpc_transport_destroy(exec_ctx, cd->transport);
+  }
 }
 
 static char *con_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
@@ -141,7 +144,7 @@ static void con_get_channel_info(grpc_exec_ctx *exec_ctx,
                                  const grpc_channel_info *channel_info) {}
 
 const grpc_channel_filter grpc_connected_filter = {
-    con_start_transport_stream_op,
+    con_start_transport_stream_op_batch,
     con_start_transport_op,
     sizeof(call_data),
     init_call_elem,
diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h
index 2c1174ce7a15cfba376175c515d321137e36c18f..f0a21113c5310d2c26aea8da36356da4b5ae98cb 100644
--- a/src/core/lib/channel/context.h
+++ b/src/core/lib/channel/context.h
@@ -50,8 +50,8 @@ typedef enum {
   /// Reserved for traffic_class_context.
   GRPC_CONTEXT_TRAFFIC,
 
-  /// Costs for Load Reporting.
-  GRPC_CONTEXT_LR_COST,
+  /// Value is a \a grpc_grpclb_client_stats.
+  GRPC_GRPCLB_CLIENT_STATS,
 
   GRPC_CONTEXT_COUNT
 } grpc_context_index;
diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c
index 1b4240bb10f423ad9a5d269707ac46c5ab4b3020..5861fa6f54cc9d754eed94f31a6e4a0c18770af8 100644
--- a/src/core/lib/channel/handshaker.c
+++ b/src/core/lib/channel/handshaker.c
@@ -236,8 +236,9 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, void* arg,
 static void on_timeout(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
   grpc_handshake_manager* mgr = arg;
   if (error == GRPC_ERROR_NONE) {  // Timer fired, rather than being cancelled.
-    grpc_handshake_manager_shutdown(exec_ctx, mgr,
-                                    GRPC_ERROR_CREATE("Handshake timed out"));
+    grpc_handshake_manager_shutdown(
+        exec_ctx, mgr,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake timed out"));
   }
   grpc_handshake_manager_unref(exec_ctx, mgr);
 }
diff --git a/src/core/lib/compression/message_compress.c b/src/core/lib/compression/message_compress.c
index 49beb953b00cb6ecf3cd0dc4e3df7ae5a0920190..fd3d1e6fcc055884270e2c7b5c9bea75f13fb5ff 100644
--- a/src/core/lib/compression/message_compress.c
+++ b/src/core/lib/compression/message_compress.c
@@ -50,7 +50,7 @@ static int zlib_body(grpc_exec_ctx* exec_ctx, z_stream* zs,
   int r;
   int flush;
   size_t i;
-  grpc_slice outbuf = grpc_slice_malloc(OUTPUT_BLOCK_SIZE);
+  grpc_slice outbuf = GRPC_SLICE_MALLOC(OUTPUT_BLOCK_SIZE);
   const uInt uint_max = ~(uInt)0;
 
   GPR_ASSERT(GRPC_SLICE_LENGTH(outbuf) <= uint_max);
@@ -65,7 +65,7 @@ static int zlib_body(grpc_exec_ctx* exec_ctx, z_stream* zs,
     do {
       if (zs->avail_out == 0) {
         grpc_slice_buffer_add_indexed(output, outbuf);
-        outbuf = grpc_slice_malloc(OUTPUT_BLOCK_SIZE);
+        outbuf = GRPC_SLICE_MALLOC(OUTPUT_BLOCK_SIZE);
         GPR_ASSERT(GRPC_SLICE_LENGTH(outbuf) <= uint_max);
         zs->avail_out = (uInt)GRPC_SLICE_LENGTH(outbuf);
         zs->next_out = GRPC_SLICE_START_PTR(outbuf);
diff --git a/src/core/lib/http/httpcli.c b/src/core/lib/http/httpcli.c
index 6d7aa43b815fc1b45748261b9c204e39794b8132..0ac2c2ad52af4a27ebde03d9c731f21f5fbb7c3a 100644
--- a/src/core/lib/http/httpcli.c
+++ b/src/core/lib/http/httpcli.c
@@ -105,7 +105,7 @@ static void finish(grpc_exec_ctx *exec_ctx, internal_request *req,
                    grpc_error *error) {
   grpc_polling_entity_del_from_pollset_set(exec_ctx, req->pollent,
                                            req->context->pollset_set);
-  grpc_closure_sched(exec_ctx, req->on_done, error);
+  grpc_closure_sched(exec_ctx, req->on_done, GRPC_ERROR_REF(error));
   grpc_http_parser_destroy(&req->parser);
   if (req->addresses != NULL) {
     grpc_resolved_addresses_destroy(req->addresses);
@@ -126,13 +126,15 @@ static void finish(grpc_exec_ctx *exec_ctx, internal_request *req,
 
 static void append_error(internal_request *req, grpc_error *error) {
   if (req->overall_error == GRPC_ERROR_NONE) {
-    req->overall_error = GRPC_ERROR_CREATE("Failed HTTP/1 client request");
+    req->overall_error =
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed HTTP/1 client request");
   }
   grpc_resolved_address *addr = &req->addresses->addrs[req->next_address - 1];
   char *addr_text = grpc_sockaddr_to_uri(addr);
   req->overall_error = grpc_error_add_child(
       req->overall_error,
-      grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, addr_text));
+      grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS,
+                         grpc_slice_from_copied_string(addr_text)));
   gpr_free(addr_text);
 }
 
@@ -190,8 +192,8 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
   internal_request *req = arg;
 
   if (!ep) {
-    next_address(exec_ctx, req,
-                 GRPC_ERROR_CREATE("Unexplained handshake failure"));
+    next_address(exec_ctx, req, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                    "Unexplained handshake failure"));
     return;
   }
 
@@ -221,8 +223,8 @@ static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req,
   }
   if (req->next_address == req->addresses->naddrs) {
     finish(exec_ctx, req,
-           GRPC_ERROR_CREATE_REFERENCING("Failed HTTP requests to all targets",
-                                         &req->overall_error, 1));
+           GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+               "Failed HTTP requests to all targets", &req->overall_error, 1));
     return;
   }
   addr = &req->addresses->addrs[req->next_address++];
diff --git a/src/core/lib/http/httpcli_security_connector.c b/src/core/lib/http/httpcli_security_connector.c
index 354d2f4a0953ac7dbb9726ae8329a31c338f82ca..76946434f0698159547ca3f8bb437ebcb3fb2046 100644
--- a/src/core/lib/http/httpcli_security_connector.c
+++ b/src/core/lib/http/httpcli_security_connector.c
@@ -43,11 +43,11 @@
 #include "src/core/lib/security/transport/security_handshaker.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
-#include "src/core/lib/tsi/ssl_transport_security.h"
+#include "src/core/tsi/ssl_transport_security.h"
 
 typedef struct {
   grpc_channel_security_connector base;
-  tsi_ssl_handshaker_factory *handshaker_factory;
+  tsi_ssl_client_handshaker_factory *handshaker_factory;
   char *secure_peer_name;
 } grpc_httpcli_ssl_channel_security_connector;
 
@@ -56,7 +56,7 @@ static void httpcli_ssl_destroy(grpc_exec_ctx *exec_ctx,
   grpc_httpcli_ssl_channel_security_connector *c =
       (grpc_httpcli_ssl_channel_security_connector *)sc;
   if (c->handshaker_factory != NULL) {
-    tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
+    tsi_ssl_client_handshaker_factory_destroy(c->handshaker_factory);
   }
   if (c->secure_peer_name != NULL) gpr_free(c->secure_peer_name);
   gpr_free(sc);
@@ -69,7 +69,7 @@ static void httpcli_ssl_add_handshakers(grpc_exec_ctx *exec_ctx,
       (grpc_httpcli_ssl_channel_security_connector *)sc;
   tsi_handshaker *handshaker = NULL;
   if (c->handshaker_factory != NULL) {
-    tsi_result result = tsi_ssl_handshaker_factory_create_handshaker(
+    tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
         c->handshaker_factory, c->secure_peer_name, &handshaker);
     if (result != TSI_OK) {
       gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
@@ -95,7 +95,7 @@ static void httpcli_ssl_check_peer(grpc_exec_ctx *exec_ctx,
     char *msg;
     gpr_asprintf(&msg, "Peer name %s is not in peer certificate",
                  c->secure_peer_name);
-    error = GRPC_ERROR_CREATE(msg);
+    error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
   }
   grpc_closure_sched(exec_ctx, on_peer_checked, error);
@@ -106,9 +106,8 @@ static grpc_security_connector_vtable httpcli_ssl_vtable = {
     httpcli_ssl_destroy, httpcli_ssl_check_peer};
 
 static grpc_security_status httpcli_ssl_channel_security_connector_create(
-    grpc_exec_ctx *exec_ctx, const unsigned char *pem_root_certs,
-    size_t pem_root_certs_size, const char *secure_peer_name,
-    grpc_channel_security_connector **sc) {
+    grpc_exec_ctx *exec_ctx, const char *pem_root_certs,
+    const char *secure_peer_name, grpc_channel_security_connector **sc) {
   tsi_result result = TSI_OK;
   grpc_httpcli_ssl_channel_security_connector *c;
 
@@ -126,8 +125,7 @@ static grpc_security_status httpcli_ssl_channel_security_connector_create(
     c->secure_peer_name = gpr_strdup(secure_peer_name);
   }
   result = tsi_create_ssl_client_handshaker_factory(
-      NULL, 0, NULL, 0, pem_root_certs, pem_root_certs_size, NULL, NULL, NULL,
-      0, &c->handshaker_factory);
+      NULL, pem_root_certs, NULL, NULL, 0, &c->handshaker_factory);
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
             tsi_result_to_string(result));
@@ -173,10 +171,9 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg,
                           void (*on_done)(grpc_exec_ctx *exec_ctx, void *arg,
                                           grpc_endpoint *endpoint)) {
   grpc_channel_security_connector *sc = NULL;
-  const unsigned char *pem_root_certs = NULL;
   on_done_closure *c = gpr_malloc(sizeof(*c));
-  size_t pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs);
-  if (pem_root_certs == NULL || pem_root_certs_size == 0) {
+  const char *pem_root_certs = grpc_get_default_ssl_roots();
+  if (pem_root_certs == NULL) {
     gpr_log(GPR_ERROR, "Could not get default pem root certs.");
     on_done(exec_ctx, arg, NULL);
     gpr_free(c);
@@ -186,8 +183,7 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg,
   c->arg = arg;
   c->handshake_mgr = grpc_handshake_manager_create();
   GPR_ASSERT(httpcli_ssl_channel_security_connector_create(
-                 exec_ctx, pem_root_certs, pem_root_certs_size, host, &sc) ==
-             GRPC_SECURITY_OK);
+                 exec_ctx, pem_root_certs, host, &sc) == GRPC_SECURITY_OK);
   grpc_channel_security_connector_add_handshakers(exec_ctx, sc,
                                                   c->handshake_mgr);
   grpc_handshake_manager_do_handshake(
diff --git a/src/core/lib/http/parser.c b/src/core/lib/http/parser.c
index b9c56c103c75bafa290fa46979c23d0a410dce11..aac506b800da3fe12e99ee1859ae6aa4bfa14149 100644
--- a/src/core/lib/http/parser.c
+++ b/src/core/lib/http/parser.c
@@ -54,26 +54,36 @@ static grpc_error *handle_response_line(grpc_http_parser *parser) {
   uint8_t *cur = beg;
   uint8_t *end = beg + parser->cur_line_length;
 
-  if (cur == end || *cur++ != 'H') return GRPC_ERROR_CREATE("Expected 'H'");
-  if (cur == end || *cur++ != 'T') return GRPC_ERROR_CREATE("Expected 'T'");
-  if (cur == end || *cur++ != 'T') return GRPC_ERROR_CREATE("Expected 'T'");
-  if (cur == end || *cur++ != 'P') return GRPC_ERROR_CREATE("Expected 'P'");
-  if (cur == end || *cur++ != '/') return GRPC_ERROR_CREATE("Expected '/'");
-  if (cur == end || *cur++ != '1') return GRPC_ERROR_CREATE("Expected '1'");
-  if (cur == end || *cur++ != '.') return GRPC_ERROR_CREATE("Expected '.'");
+  if (cur == end || *cur++ != 'H')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'H'");
+  if (cur == end || *cur++ != 'T')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'T'");
+  if (cur == end || *cur++ != 'T')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'T'");
+  if (cur == end || *cur++ != 'P')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'P'");
+  if (cur == end || *cur++ != '/')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected '/'");
+  if (cur == end || *cur++ != '1')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected '1'");
+  if (cur == end || *cur++ != '.')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected '.'");
   if (cur == end || *cur < '0' || *cur++ > '1') {
-    return GRPC_ERROR_CREATE("Expected HTTP/1.0 or HTTP/1.1");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Expected HTTP/1.0 or HTTP/1.1");
   }
-  if (cur == end || *cur++ != ' ') return GRPC_ERROR_CREATE("Expected ' '");
+  if (cur == end || *cur++ != ' ')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected ' '");
   if (cur == end || *cur < '1' || *cur++ > '9')
-    return GRPC_ERROR_CREATE("Expected status code");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected status code");
   if (cur == end || *cur < '0' || *cur++ > '9')
-    return GRPC_ERROR_CREATE("Expected status code");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected status code");
   if (cur == end || *cur < '0' || *cur++ > '9')
-    return GRPC_ERROR_CREATE("Expected status code");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected status code");
   parser->http.response->status =
       (cur[-3] - '0') * 100 + (cur[-2] - '0') * 10 + (cur[-1] - '0');
-  if (cur == end || *cur++ != ' ') return GRPC_ERROR_CREATE("Expected ' '");
+  if (cur == end || *cur++ != ' ')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected ' '");
 
   /* we don't really care about the status code message */
 
@@ -89,24 +99,33 @@ static grpc_error *handle_request_line(grpc_http_parser *parser) {
 
   while (cur != end && *cur++ != ' ')
     ;
-  if (cur == end) return GRPC_ERROR_CREATE("No method on HTTP request line");
+  if (cur == end)
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "No method on HTTP request line");
   parser->http.request->method = buf2str(beg, (size_t)(cur - beg - 1));
 
   beg = cur;
   while (cur != end && *cur++ != ' ')
     ;
-  if (cur == end) return GRPC_ERROR_CREATE("No path on HTTP request line");
+  if (cur == end)
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("No path on HTTP request line");
   parser->http.request->path = buf2str(beg, (size_t)(cur - beg - 1));
 
-  if (cur == end || *cur++ != 'H') return GRPC_ERROR_CREATE("Expected 'H'");
-  if (cur == end || *cur++ != 'T') return GRPC_ERROR_CREATE("Expected 'T'");
-  if (cur == end || *cur++ != 'T') return GRPC_ERROR_CREATE("Expected 'T'");
-  if (cur == end || *cur++ != 'P') return GRPC_ERROR_CREATE("Expected 'P'");
-  if (cur == end || *cur++ != '/') return GRPC_ERROR_CREATE("Expected '/'");
+  if (cur == end || *cur++ != 'H')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'H'");
+  if (cur == end || *cur++ != 'T')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'T'");
+  if (cur == end || *cur++ != 'T')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'T'");
+  if (cur == end || *cur++ != 'P')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'P'");
+  if (cur == end || *cur++ != '/')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected '/'");
   vers_major = (uint8_t)(*cur++ - '1' + 1);
   ++cur;
   if (cur == end)
-    return GRPC_ERROR_CREATE("End of line in HTTP version string");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "End of line in HTTP version string");
   vers_minor = (uint8_t)(*cur++ - '1' + 1);
 
   if (vers_major == 1) {
@@ -115,18 +134,19 @@ static grpc_error *handle_request_line(grpc_http_parser *parser) {
     } else if (vers_minor == 1) {
       parser->http.request->version = GRPC_HTTP_HTTP11;
     } else {
-      return GRPC_ERROR_CREATE(
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
           "Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
     }
   } else if (vers_major == 2) {
     if (vers_minor == 0) {
       parser->http.request->version = GRPC_HTTP_HTTP20;
     } else {
-      return GRPC_ERROR_CREATE(
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
           "Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
     }
   } else {
-    return GRPC_ERROR_CREATE("Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
   }
 
   return GRPC_ERROR_NONE;
@@ -139,7 +159,8 @@ static grpc_error *handle_first_line(grpc_http_parser *parser) {
     case GRPC_HTTP_RESPONSE:
       return handle_response_line(parser);
   }
-  GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here"));
+  GPR_UNREACHABLE_CODE(
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here"));
 }
 
 static grpc_error *add_header(grpc_http_parser *parser) {
@@ -154,7 +175,8 @@ static grpc_error *add_header(grpc_http_parser *parser) {
   GPR_ASSERT(cur != end);
 
   if (*cur == ' ' || *cur == '\t') {
-    error = GRPC_ERROR_CREATE("Continued header lines not supported yet");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Continued header lines not supported yet");
     goto done;
   }
 
@@ -162,7 +184,8 @@ static grpc_error *add_header(grpc_http_parser *parser) {
     cur++;
   }
   if (cur == end) {
-    error = GRPC_ERROR_CREATE("Didn't find ':' in header string");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Didn't find ':' in header string");
     goto done;
   }
   GPR_ASSERT(cur >= beg);
@@ -222,7 +245,8 @@ static grpc_error *finish_line(grpc_http_parser *parser,
       }
       break;
     case GRPC_HTTP_BODY:
-      GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here"));
+      GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "Should never reach here"));
   }
 
   parser->cur_line_length = 0;
@@ -240,7 +264,8 @@ static grpc_error *addbyte_body(grpc_http_parser *parser, uint8_t byte) {
     body_length = &parser->http.request->body_length;
     body = &parser->http.request->body;
   } else {
-    GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here"));
+    GPR_UNREACHABLE_CODE(
+        return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here"));
   }
 
   if (*body_length == parser->body_capacity) {
@@ -286,7 +311,8 @@ static grpc_error *addbyte(grpc_http_parser *parser, uint8_t byte,
         if (grpc_http1_trace)
           gpr_log(GPR_ERROR, "HTTP header max line length (%d) exceeded",
                   GRPC_HTTP_PARSER_MAX_HEADER_LENGTH);
-        return GRPC_ERROR_CREATE("HTTP header max line length exceeded");
+        return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+            "HTTP header max line length exceeded");
       }
       parser->cur_line[parser->cur_line_length] = byte;
       parser->cur_line_length++;
@@ -347,7 +373,7 @@ grpc_error *grpc_http_parser_parse(grpc_http_parser *parser, grpc_slice slice,
 
 grpc_error *grpc_http_parser_eof(grpc_http_parser *parser) {
   if (parser->state != GRPC_HTTP_BODY) {
-    return GRPC_ERROR_CREATE("Did not finish headers");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Did not finish headers");
   }
   return GRPC_ERROR_NONE;
 }
diff --git a/src/core/lib/iomgr/closure.c b/src/core/lib/iomgr/closure.c
index 509c1ff95dd2304fe90b1f4e51cbba172d4f69fb..8ef0b210ad213fef162eb4742612920170265bc1 100644
--- a/src/core/lib/iomgr/closure.c
+++ b/src/core/lib/iomgr/closure.c
@@ -33,6 +33,7 @@
 
 #include "src/core/lib/iomgr/closure.h"
 
+#include <assert.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
@@ -44,6 +45,9 @@ grpc_closure *grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
   closure->cb = cb;
   closure->cb_arg = cb_arg;
   closure->scheduler = scheduler;
+#ifndef NDEBUG
+  closure->scheduled = false;
+#endif
   return closure;
 }
 
@@ -124,6 +128,7 @@ void grpc_closure_run(grpc_exec_ctx *exec_ctx, grpc_closure *c,
                       grpc_error *error) {
   GPR_TIMER_BEGIN("grpc_closure_run", 0);
   if (c != NULL) {
+    assert(c->cb);
     c->scheduler->vtable->run(exec_ctx, c, error);
   } else {
     GRPC_ERROR_UNREF(error);
@@ -135,6 +140,11 @@ void grpc_closure_sched(grpc_exec_ctx *exec_ctx, grpc_closure *c,
                         grpc_error *error) {
   GPR_TIMER_BEGIN("grpc_closure_sched", 0);
   if (c != NULL) {
+#ifndef NDEBUG
+    GPR_ASSERT(!c->scheduled);
+    c->scheduled = true;
+#endif
+    assert(c->cb);
     c->scheduler->vtable->sched(exec_ctx, c, error);
   } else {
     GRPC_ERROR_UNREF(error);
@@ -146,6 +156,11 @@ void grpc_closure_list_sched(grpc_exec_ctx *exec_ctx, grpc_closure_list *list) {
   grpc_closure *c = list->head;
   while (c != NULL) {
     grpc_closure *next = c->next_data.next;
+#ifndef NDEBUG
+    GPR_ASSERT(!c->scheduled);
+    c->scheduled = true;
+#endif
+    assert(c->cb);
     c->scheduler->vtable->sched(exec_ctx, c, c->error_data.error);
     c = next;
   }
diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h
index 2510d50b428f37b697f7ed51bd416347e1aea2b2..2bedbf00d63c99ab871904f9a40619e21e0d3a93 100644
--- a/src/core/lib/iomgr/closure.h
+++ b/src/core/lib/iomgr/closure.h
@@ -99,6 +99,10 @@ struct grpc_closure {
     grpc_error *error;
     uintptr_t scratch;
   } error_data;
+
+#ifndef NDEBUG
+  bool scheduled;
+#endif
 };
 
 /** Initializes \a closure with \a cb and \a cb_arg. Returns \a closure. */
diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c
index fa9966c3a6957b38d7fa47d983bc7783198cf8a5..05cdbdad2b78e2bcc5ae9d4e3eab66dbae12767b 100644
--- a/src/core/lib/iomgr/combiner.c
+++ b/src/core/lib/iomgr/combiner.c
@@ -33,6 +33,7 @@
 
 #include "src/core/lib/iomgr/combiner.h"
 
+#include <assert.h>
 #include <string.h>
 
 #include <grpc/support/alloc.h>
@@ -216,6 +217,7 @@ static void combiner_exec(grpc_exec_ctx *exec_ctx, grpc_combiner *lock,
       GPR_DEBUG, "C:%p grpc_combiner_execute c=%p cov=%d last=%" PRIdPTR, lock,
       cl, covered_by_poller, last));
   GPR_ASSERT(last & STATE_UNORPHANED);  // ensure lock has not been destroyed
+  assert(cl->cb);
   cl->error_data.scratch =
       pack_error_data((error_data){error, covered_by_poller});
   if (covered_by_poller) {
@@ -317,6 +319,9 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) {
     GPR_TIMER_BEGIN("combiner.exec1", 0);
     grpc_closure *cl = (grpc_closure *)n;
     error_data err = unpack_error_data(cl->error_data.scratch);
+#ifndef NDEBUG
+    cl->scheduled = false;
+#endif
     cl->cb(exec_ctx, cl->cb_arg, err.error);
     if (err.covered_by_poller) {
       gpr_atm_no_barrier_fetch_add(&lock->elements_covered_by_poller, -1);
@@ -335,6 +340,9 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) {
           gpr_log(GPR_DEBUG, "C:%p execute_final[%d] c=%p", lock, loops, c));
       grpc_closure *next = c->next_data.next;
       grpc_error *error = c->error_data.error;
+#ifndef NDEBUG
+      c->scheduled = false;
+#endif
       c->cb(exec_ctx, c->cb_arg, error);
       GRPC_ERROR_UNREF(error);
       c = next;
diff --git a/src/core/lib/iomgr/endpoint_pair.h b/src/core/lib/iomgr/endpoint_pair.h
index f9de0c715ecc0f6a6ce67add9a32c2089fc2966c..6407a6ad3f32ca225385a6aab76ae4a0d4d1488e 100644
--- a/src/core/lib/iomgr/endpoint_pair.h
+++ b/src/core/lib/iomgr/endpoint_pair.h
@@ -41,8 +41,7 @@ typedef struct {
   grpc_endpoint *server;
 } grpc_endpoint_pair;
 
-grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(
-    const char *name, grpc_resource_quota *resource_quota,
-    size_t read_slice_size);
+grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name,
+                                                   grpc_channel_args *args);
 
 #endif /* GRPC_CORE_LIB_IOMGR_ENDPOINT_PAIR_H */
diff --git a/src/core/lib/iomgr/endpoint_pair_posix.c b/src/core/lib/iomgr/endpoint_pair_posix.c
index b9ff969e8100c858616db042e2c0742a8113f442..5542a372d8bfdf007fe6fef511ed9d229b02ee04 100644
--- a/src/core/lib/iomgr/endpoint_pair_posix.c
+++ b/src/core/lib/iomgr/endpoint_pair_posix.c
@@ -62,22 +62,25 @@ static void create_sockets(int sv[2]) {
   GPR_ASSERT(grpc_set_socket_no_sigpipe_if_possible(sv[1]) == GRPC_ERROR_NONE);
 }
 
-grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(
-    const char *name, grpc_resource_quota *resource_quota,
-    size_t read_slice_size) {
+grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name,
+                                                   grpc_channel_args *args) {
   int sv[2];
   grpc_endpoint_pair p;
   char *final_name;
   create_sockets(sv);
 
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
   gpr_asprintf(&final_name, "%s:client", name);
-  p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name), resource_quota,
-                             read_slice_size, "socketpair-server");
+  p.client = grpc_tcp_create(&exec_ctx, grpc_fd_create(sv[1], final_name), args,
+                             "socketpair-server");
   gpr_free(final_name);
   gpr_asprintf(&final_name, "%s:server", name);
-  p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name), resource_quota,
-                             read_slice_size, "socketpair-client");
+  p.server = grpc_tcp_create(&exec_ctx, grpc_fd_create(sv[0], final_name), args,
+                             "socketpair-client");
   gpr_free(final_name);
+
+  grpc_exec_ctx_finish(&exec_ctx);
   return p;
 }
 
diff --git a/src/core/lib/iomgr/endpoint_pair_uv.c b/src/core/lib/iomgr/endpoint_pair_uv.c
index ff24894c6db8d3ff9977dc86ceb6e96b1fa4b2d3..9718eb0523727a133dcddb9cb2b96cd2f6b1d68b 100644
--- a/src/core/lib/iomgr/endpoint_pair_uv.c
+++ b/src/core/lib/iomgr/endpoint_pair_uv.c
@@ -41,9 +41,8 @@
 
 #include "src/core/lib/iomgr/endpoint_pair.h"
 
-grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(
-    const char *name, grpc_resource_quota *resource_quota,
-    size_t read_slice_size) {
+grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name,
+                                                   grpc_channel_args *args) {
   grpc_endpoint_pair endpoint_pair;
   // TODO(mlumish): implement this properly under libuv
   GPR_ASSERT(false &&
diff --git a/src/core/lib/iomgr/endpoint_pair_windows.c b/src/core/lib/iomgr/endpoint_pair_windows.c
index 93f71b745c6c0489e2c35474a34a8f639c8f5c81..25d6264dfb690cc2674cd849f7666be0268265e0 100644
--- a/src/core/lib/iomgr/endpoint_pair_windows.c
+++ b/src/core/lib/iomgr/endpoint_pair_windows.c
@@ -83,15 +83,18 @@ static void create_sockets(SOCKET sv[2]) {
 }
 
 grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(
-    const char *name, grpc_resource_quota *resource_quota,
-    size_t read_slice_size) {
+    const char *name, grpc_channel_args *channel_args) {
   SOCKET sv[2];
   grpc_endpoint_pair p;
   create_sockets(sv);
-  p.client = grpc_tcp_create(grpc_winsocket_create(sv[1], "endpoint:client"),
-                             resource_quota, "endpoint:server");
-  p.server = grpc_tcp_create(grpc_winsocket_create(sv[0], "endpoint:server"),
-                             resource_quota, "endpoint:client");
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  p.client = grpc_tcp_create(&exec_ctx,
+                             grpc_winsocket_create(sv[1], "endpoint:client"),
+                             channel_args, "endpoint:server");
+  p.server = grpc_tcp_create(&exec_ctx,
+                             grpc_winsocket_create(sv[0], "endpoint:server"),
+                             channel_args, "endpoint:client");
+  grpc_exec_ctx_finish(&exec_ctx);
   return p;
 }
 
diff --git a/src/core/lib/iomgr/error.c b/src/core/lib/iomgr/error.c
index dbe5b139f91dfbd11ddf042b7541a8069c1909e9..5f2c989aad00119792ab6b0974a962a7b7629b3e 100644
--- a/src/core/lib/iomgr/error.c
+++ b/src/core/lib/iomgr/error.c
@@ -47,46 +47,7 @@
 
 #include "src/core/lib/iomgr/error_internal.h"
 #include "src/core/lib/profiling/timers.h"
-
-static void destroy_integer(void *key) {}
-
-static void *copy_integer(void *key) { return key; }
-
-static long compare_integers(void *key1, void *key2) {
-  return GPR_ICMP((uintptr_t)key1, (uintptr_t)key2);
-}
-
-static void destroy_string(void *str) { gpr_free(str); }
-
-static void *copy_string(void *str) { return gpr_strdup(str); }
-
-static void destroy_err(void *err) { GRPC_ERROR_UNREF(err); }
-
-static void *copy_err(void *err) { return GRPC_ERROR_REF(err); }
-
-static void destroy_time(void *tm) { gpr_free(tm); }
-
-static gpr_timespec *box_time(gpr_timespec tm) {
-  gpr_timespec *out = gpr_malloc(sizeof(*out));
-  *out = tm;
-  return out;
-}
-
-static void *copy_time(void *tm) { return box_time(*(gpr_timespec *)tm); }
-
-static const gpr_avl_vtable avl_vtable_ints = {destroy_integer, copy_integer,
-                                               compare_integers,
-                                               destroy_integer, copy_integer};
-
-static const gpr_avl_vtable avl_vtable_strs = {destroy_integer, copy_integer,
-                                               compare_integers, destroy_string,
-                                               copy_string};
-
-static const gpr_avl_vtable avl_vtable_times = {
-    destroy_integer, copy_integer, compare_integers, destroy_time, copy_time};
-
-static const gpr_avl_vtable avl_vtable_errs = {
-    destroy_integer, copy_integer, compare_integers, destroy_err, copy_err};
+#include "src/core/lib/slice/slice_internal.h"
 
 static const char *error_int_name(grpc_error_ints key) {
   switch (key) {
@@ -120,6 +81,8 @@ static const char *error_int_name(grpc_error_ints key) {
       return "limit";
     case GRPC_ERROR_INT_OCCURRED_DURING_WRITE:
       return "occurred_during_write";
+    case GRPC_ERROR_INT_MAX:
+      GPR_UNREACHABLE_CODE(return "unknown");
   }
   GPR_UNREACHABLE_CODE(return "unknown");
 }
@@ -150,6 +113,8 @@ static const char *error_str_name(grpc_error_strs key) {
       return "filename";
     case GRPC_ERROR_STR_QUEUED_BUFFERS:
       return "queued_buffers";
+    case GRPC_ERROR_STR_MAX:
+      GPR_UNREACHABLE_CODE(return "unknown");
   }
   GPR_UNREACHABLE_CODE(return "unknown");
 }
@@ -158,6 +123,8 @@ static const char *error_time_name(grpc_error_times key) {
   switch (key) {
     case GRPC_ERROR_TIME_CREATED:
       return "created";
+    case GRPC_ERROR_TIME_MAX:
+      GPR_UNREACHABLE_CODE(return "unknown");
   }
   GPR_UNREACHABLE_CODE(return "unknown");
 }
@@ -172,25 +139,51 @@ grpc_error *grpc_error_ref(grpc_error *err, const char *file, int line,
                            const char *func) {
   if (grpc_error_is_special(err)) return err;
   gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err,
-          err->refs.count, err->refs.count + 1, file, line, func);
-  gpr_ref(&err->refs);
+          gpr_atm_no_barrier_load(&err->atomics.refs.count),
+          gpr_atm_no_barrier_load(&err->atomics.refs.count) + 1, file, line,
+          func);
+  gpr_ref(&err->atomics.refs);
   return err;
 }
 #else
 grpc_error *grpc_error_ref(grpc_error *err) {
   if (grpc_error_is_special(err)) return err;
-  gpr_ref(&err->refs);
+  gpr_ref(&err->atomics.refs);
   return err;
 }
 #endif
 
+static void unref_errs(grpc_error *err) {
+  uint8_t slot = err->first_err;
+  while (slot != UINT8_MAX) {
+    grpc_linked_error *lerr = (grpc_linked_error *)(err->arena + slot);
+    GRPC_ERROR_UNREF(lerr->err);
+    GPR_ASSERT(err->last_err == slot ? lerr->next == UINT8_MAX
+                                     : lerr->next != UINT8_MAX);
+    slot = lerr->next;
+  }
+}
+
+static void unref_slice(grpc_slice slice) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_slice_unref_internal(&exec_ctx, slice);
+  grpc_exec_ctx_finish(&exec_ctx);
+}
+
+static void unref_strs(grpc_error *err) {
+  for (size_t which = 0; which < GRPC_ERROR_STR_MAX; ++which) {
+    uint8_t slot = err->strs[which];
+    if (slot != UINT8_MAX) {
+      unref_slice(*(grpc_slice *)(err->arena + slot));
+    }
+  }
+}
+
 static void error_destroy(grpc_error *err) {
   GPR_ASSERT(!grpc_error_is_special(err));
-  gpr_avl_unref(err->ints);
-  gpr_avl_unref(err->strs);
-  gpr_avl_unref(err->errs);
-  gpr_avl_unref(err->times);
-  gpr_free((void *)gpr_atm_acq_load(&err->error_string));
+  unref_errs(err);
+  unref_strs(err);
+  gpr_free((void *)gpr_atm_acq_load(&err->atomics.error_string));
   gpr_free(err);
 }
 
@@ -199,81 +192,237 @@ void grpc_error_unref(grpc_error *err, const char *file, int line,
                       const char *func) {
   if (grpc_error_is_special(err)) return;
   gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err,
-          err->refs.count, err->refs.count - 1, file, line, func);
-  if (gpr_unref(&err->refs)) {
+          gpr_atm_no_barrier_load(&err->atomics.refs.count),
+          gpr_atm_no_barrier_load(&err->atomics.refs.count) - 1, file, line,
+          func);
+  if (gpr_unref(&err->atomics.refs)) {
     error_destroy(err);
   }
 }
 #else
 void grpc_error_unref(grpc_error *err) {
   if (grpc_error_is_special(err)) return;
-  if (gpr_unref(&err->refs)) {
+  if (gpr_unref(&err->atomics.refs)) {
     error_destroy(err);
   }
 }
 #endif
 
-grpc_error *grpc_error_create(const char *file, int line, const char *desc,
+static uint8_t get_placement(grpc_error **err, size_t size) {
+  GPR_ASSERT(*err);
+  uint8_t slots = (uint8_t)(size / sizeof(intptr_t));
+  if ((*err)->arena_size + slots > (*err)->arena_capacity) {
+    (*err)->arena_capacity =
+        (uint8_t)GPR_MIN(UINT8_MAX - 1, (3 * (*err)->arena_capacity / 2));
+    if ((*err)->arena_size + slots > (*err)->arena_capacity) {
+      return UINT8_MAX;
+    }
+#ifdef GRPC_ERROR_REFCOUNT_DEBUG
+    grpc_error *orig = *err;
+#endif
+    *err = gpr_realloc(
+        *err, sizeof(grpc_error) + (*err)->arena_capacity * sizeof(intptr_t));
+#ifdef GRPC_ERROR_REFCOUNT_DEBUG
+    if (*err != orig) gpr_log(GPR_DEBUG, "realloc %p -> %p", orig, *err);
+#endif
+  }
+  uint8_t placement = (*err)->arena_size;
+  (*err)->arena_size = (uint8_t)((*err)->arena_size + slots);
+  return placement;
+}
+
+static void internal_set_int(grpc_error **err, grpc_error_ints which,
+                             intptr_t value) {
+  uint8_t slot = (*err)->ints[which];
+  if (slot == UINT8_MAX) {
+    slot = get_placement(err, sizeof(value));
+    if (slot == UINT8_MAX) {
+      gpr_log(GPR_ERROR, "Error %p is full, dropping int {\"%s\":%" PRIiPTR "}",
+              *err, error_int_name(which), value);
+      return;
+    }
+  }
+  (*err)->ints[which] = slot;
+  (*err)->arena[slot] = value;
+}
+
+static void internal_set_str(grpc_error **err, grpc_error_strs which,
+                             grpc_slice value) {
+  uint8_t slot = (*err)->strs[which];
+  if (slot == UINT8_MAX) {
+    slot = get_placement(err, sizeof(value));
+    if (slot == UINT8_MAX) {
+      const char *str = grpc_slice_to_c_string(value);
+      gpr_log(GPR_ERROR, "Error %p is full, dropping string {\"%s\":\"%s\"}",
+              *err, error_str_name(which), str);
+      gpr_free((void *)str);
+      return;
+    }
+  } else {
+    unref_slice(*(grpc_slice *)((*err)->arena + slot));
+  }
+  (*err)->strs[which] = slot;
+  memcpy((*err)->arena + slot, &value, sizeof(value));
+}
+
+static char *fmt_time(gpr_timespec tm);
+static void internal_set_time(grpc_error **err, grpc_error_times which,
+                              gpr_timespec value) {
+  uint8_t slot = (*err)->times[which];
+  if (slot == UINT8_MAX) {
+    slot = get_placement(err, sizeof(value));
+    if (slot == UINT8_MAX) {
+      const char *time_str = fmt_time(value);
+      gpr_log(GPR_ERROR, "Error %p is full, dropping \"%s\":\"%s\"}", *err,
+              error_time_name(which), time_str);
+      gpr_free((void *)time_str);
+      return;
+    }
+  }
+  (*err)->times[which] = slot;
+  memcpy((*err)->arena + slot, &value, sizeof(value));
+}
+
+static void internal_add_error(grpc_error **err, grpc_error *new) {
+  grpc_linked_error new_last = {new, UINT8_MAX};
+  uint8_t slot = get_placement(err, sizeof(grpc_linked_error));
+  if (slot == UINT8_MAX) {
+    gpr_log(GPR_ERROR, "Error %p is full, dropping error %p = %s", *err, new,
+            grpc_error_string(new));
+    GRPC_ERROR_UNREF(new);
+    return;
+  }
+  if ((*err)->first_err == UINT8_MAX) {
+    GPR_ASSERT((*err)->last_err == UINT8_MAX);
+    (*err)->last_err = slot;
+    (*err)->first_err = slot;
+  } else {
+    GPR_ASSERT((*err)->last_err != UINT8_MAX);
+    grpc_linked_error *old_last =
+        (grpc_linked_error *)((*err)->arena + (*err)->last_err);
+    old_last->next = slot;
+    (*err)->last_err = slot;
+  }
+  memcpy((*err)->arena + slot, &new_last, sizeof(grpc_linked_error));
+}
+
+#define SLOTS_PER_INT (sizeof(intptr_t) / sizeof(intptr_t))
+#define SLOTS_PER_STR (sizeof(grpc_slice) / sizeof(intptr_t))
+#define SLOTS_PER_TIME (sizeof(gpr_timespec) / sizeof(intptr_t))
+#define SLOTS_PER_LINKED_ERROR (sizeof(grpc_linked_error) / sizeof(intptr_t))
+
+// size of storing one int and two slices and a timespec. For line, desc, file,
+// and time created
+#define DEFAULT_ERROR_CAPACITY \
+  (SLOTS_PER_INT + (SLOTS_PER_STR * 2) + SLOTS_PER_TIME)
+
+// It is very common to include and extra int and string in an error
+#define SURPLUS_CAPACITY (2 * SLOTS_PER_INT + SLOTS_PER_TIME)
+
+grpc_error *grpc_error_create(const char *file, int line, grpc_slice desc,
                               grpc_error **referencing,
                               size_t num_referencing) {
   GPR_TIMER_BEGIN("grpc_error_create", 0);
-  grpc_error *err = gpr_malloc(sizeof(*err));
+  uint8_t initial_arena_capacity = (uint8_t)(
+      DEFAULT_ERROR_CAPACITY +
+      (uint8_t)(num_referencing * SLOTS_PER_LINKED_ERROR) + SURPLUS_CAPACITY);
+  grpc_error *err =
+      gpr_malloc(sizeof(*err) + initial_arena_capacity * sizeof(intptr_t));
   if (err == NULL) {  // TODO(ctiller): make gpr_malloc return NULL
     return GRPC_ERROR_OOM;
   }
 #ifdef GRPC_ERROR_REFCOUNT_DEBUG
   gpr_log(GPR_DEBUG, "%p create [%s:%d]", err, file, line);
 #endif
-  err->ints = gpr_avl_add(gpr_avl_create(&avl_vtable_ints),
-                          (void *)(uintptr_t)GRPC_ERROR_INT_FILE_LINE,
-                          (void *)(uintptr_t)line);
-  err->strs = gpr_avl_add(
-      gpr_avl_add(gpr_avl_create(&avl_vtable_strs),
-                  (void *)(uintptr_t)GRPC_ERROR_STR_FILE, gpr_strdup(file)),
-      (void *)(uintptr_t)GRPC_ERROR_STR_DESCRIPTION, gpr_strdup(desc));
-  err->errs = gpr_avl_create(&avl_vtable_errs);
-  err->next_err = 0;
-  for (size_t i = 0; i < num_referencing; i++) {
+
+  err->arena_size = 0;
+  err->arena_capacity = initial_arena_capacity;
+  err->first_err = UINT8_MAX;
+  err->last_err = UINT8_MAX;
+
+  memset(err->ints, UINT8_MAX, GRPC_ERROR_INT_MAX);
+  memset(err->strs, UINT8_MAX, GRPC_ERROR_STR_MAX);
+  memset(err->times, UINT8_MAX, GRPC_ERROR_TIME_MAX);
+
+  internal_set_int(&err, GRPC_ERROR_INT_FILE_LINE, line);
+  internal_set_str(&err, GRPC_ERROR_STR_FILE,
+                   grpc_slice_from_static_string(file));
+  internal_set_str(&err, GRPC_ERROR_STR_DESCRIPTION, desc);
+
+  for (size_t i = 0; i < num_referencing; ++i) {
     if (referencing[i] == GRPC_ERROR_NONE) continue;
-    err->errs = gpr_avl_add(err->errs, (void *)(err->next_err++),
-                            GRPC_ERROR_REF(referencing[i]));
-  }
-  err->times = gpr_avl_add(gpr_avl_create(&avl_vtable_times),
-                           (void *)(uintptr_t)GRPC_ERROR_TIME_CREATED,
-                           box_time(gpr_now(GPR_CLOCK_REALTIME)));
-  gpr_atm_no_barrier_store(&err->error_string, 0);
-  gpr_ref_init(&err->refs, 1);
+    internal_add_error(
+        &err,
+        GRPC_ERROR_REF(
+            referencing[i]));  // TODO(ncteisen), change ownership semantics
+  }
+
+  internal_set_time(&err, GRPC_ERROR_TIME_CREATED, gpr_now(GPR_CLOCK_REALTIME));
+
+  gpr_atm_no_barrier_store(&err->atomics.error_string, 0);
+  gpr_ref_init(&err->atomics.refs, 1);
   GPR_TIMER_END("grpc_error_create", 0);
   return err;
 }
 
+static void ref_strs(grpc_error *err) {
+  for (size_t i = 0; i < GRPC_ERROR_STR_MAX; ++i) {
+    uint8_t slot = err->strs[i];
+    if (slot != UINT8_MAX) {
+      grpc_slice_ref_internal(*(grpc_slice *)(err->arena + slot));
+    }
+  }
+}
+
+static void ref_errs(grpc_error *err) {
+  uint8_t slot = err->first_err;
+  while (slot != UINT8_MAX) {
+    grpc_linked_error *lerr = (grpc_linked_error *)(err->arena + slot);
+    GRPC_ERROR_REF(lerr->err);
+    slot = lerr->next;
+  }
+}
+
 static grpc_error *copy_error_and_unref(grpc_error *in) {
   GPR_TIMER_BEGIN("copy_error_and_unref", 0);
   grpc_error *out;
   if (grpc_error_is_special(in)) {
-    if (in == GRPC_ERROR_NONE)
-      out = grpc_error_set_int(GRPC_ERROR_CREATE("no error"),
-                               GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_OK);
-    else if (in == GRPC_ERROR_OOM)
-      out = GRPC_ERROR_CREATE("oom");
-    else if (in == GRPC_ERROR_CANCELLED)
-      out =
-          grpc_error_set_int(GRPC_ERROR_CREATE("cancelled"),
-                             GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_CANCELLED);
-    else
-      out = GRPC_ERROR_CREATE("unknown");
+    out = GRPC_ERROR_CREATE_FROM_STATIC_STRING("unknown");
+    if (in == GRPC_ERROR_NONE) {
+      internal_set_str(&out, GRPC_ERROR_STR_DESCRIPTION,
+                       grpc_slice_from_static_string("no error"));
+      internal_set_int(&out, GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_OK);
+    } else if (in == GRPC_ERROR_OOM) {
+      internal_set_str(&out, GRPC_ERROR_STR_DESCRIPTION,
+                       grpc_slice_from_static_string("oom"));
+    } else if (in == GRPC_ERROR_CANCELLED) {
+      internal_set_str(&out, GRPC_ERROR_STR_DESCRIPTION,
+                       grpc_slice_from_static_string("cancelled"));
+      internal_set_int(&out, GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_CANCELLED);
+    }
+  } else if (gpr_ref_is_unique(&in->atomics.refs)) {
+    out = in;
   } else {
-    out = gpr_malloc(sizeof(*out));
+    uint8_t new_arena_capacity = in->arena_capacity;
+    // the returned err will be added to, so we ensure this is room to avoid
+    // unneeded allocations.
+    if (in->arena_capacity - in->arena_size < (uint8_t)SLOTS_PER_STR) {
+      new_arena_capacity = (uint8_t)(3 * new_arena_capacity / 2);
+    }
+    out = gpr_malloc(sizeof(*in) + new_arena_capacity * sizeof(intptr_t));
 #ifdef GRPC_ERROR_REFCOUNT_DEBUG
     gpr_log(GPR_DEBUG, "%p create copying %p", out, in);
 #endif
-    out->ints = gpr_avl_ref(in->ints);
-    out->strs = gpr_avl_ref(in->strs);
-    out->errs = gpr_avl_ref(in->errs);
-    out->times = gpr_avl_ref(in->times);
-    gpr_atm_no_barrier_store(&out->error_string, 0);
-    out->next_err = in->next_err;
-    gpr_ref_init(&out->refs, 1);
+    // bulk memcpy of the rest of the struct.
+    size_t skip = sizeof(&out->atomics);
+    memcpy((void *)((uintptr_t)out + skip), (void *)((uintptr_t)in + skip),
+           sizeof(*in) + (in->arena_size * sizeof(intptr_t)) - skip);
+    // manually set the atomics and the new capacity
+    gpr_atm_no_barrier_store(&out->atomics.error_string, 0);
+    gpr_ref_init(&out->atomics.refs, 1);
+    out->arena_capacity = new_arena_capacity;
+    ref_strs(out);
+    ref_errs(out);
     GRPC_ERROR_UNREF(in);
   }
   GPR_TIMER_END("copy_error_and_unref", 0);
@@ -284,7 +433,7 @@ grpc_error *grpc_error_set_int(grpc_error *src, grpc_error_ints which,
                                intptr_t value) {
   GPR_TIMER_BEGIN("grpc_error_set_int", 0);
   grpc_error *new = copy_error_and_unref(src);
-  new->ints = gpr_avl_add(new->ints, (void *)(uintptr_t)which, (void *)value);
+  internal_set_int(&new, which, value);
   GPR_TIMER_END("grpc_error_set_int", 0);
   return new;
 }
@@ -295,14 +444,13 @@ typedef struct {
   const char *msg;
 } special_error_status_map;
 static special_error_status_map error_status_map[] = {
-    {GRPC_ERROR_NONE, GRPC_STATUS_OK, NULL},
+    {GRPC_ERROR_NONE, GRPC_STATUS_OK, ""},
     {GRPC_ERROR_CANCELLED, GRPC_STATUS_CANCELLED, "Cancelled"},
     {GRPC_ERROR_OOM, GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory"},
 };
 
 bool grpc_error_get_int(grpc_error *err, grpc_error_ints which, intptr_t *p) {
   GPR_TIMER_BEGIN("grpc_error_get_int", 0);
-  void *pp;
   if (grpc_error_is_special(err)) {
     if (which == GRPC_ERROR_INT_GRPC_STATUS) {
       for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) {
@@ -316,8 +464,9 @@ bool grpc_error_get_int(grpc_error *err, grpc_error_ints which, intptr_t *p) {
     GPR_TIMER_END("grpc_error_get_int", 0);
     return false;
   }
-  if (gpr_avl_maybe_get(err->ints, (void *)(uintptr_t)which, &pp)) {
-    if (p != NULL) *p = (intptr_t)pp;
+  uint8_t slot = err->ints[which];
+  if (slot != UINT8_MAX) {
+    if (p != NULL) *p = err->arena[slot];
     GPR_TIMER_END("grpc_error_get_int", 0);
     return true;
   }
@@ -326,33 +475,40 @@ bool grpc_error_get_int(grpc_error *err, grpc_error_ints which, intptr_t *p) {
 }
 
 grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which,
-                               const char *value) {
+                               grpc_slice str) {
   GPR_TIMER_BEGIN("grpc_error_set_str", 0);
   grpc_error *new = copy_error_and_unref(src);
-  new->strs =
-      gpr_avl_add(new->strs, (void *)(uintptr_t)which, gpr_strdup(value));
+  internal_set_str(&new, which, str);
   GPR_TIMER_END("grpc_error_set_str", 0);
   return new;
 }
 
-const char *grpc_error_get_str(grpc_error *err, grpc_error_strs which) {
+bool grpc_error_get_str(grpc_error *err, grpc_error_strs which,
+                        grpc_slice *str) {
   if (grpc_error_is_special(err)) {
     if (which == GRPC_ERROR_STR_GRPC_MESSAGE) {
       for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) {
         if (error_status_map[i].error == err) {
-          return error_status_map[i].msg;
+          *str = grpc_slice_from_static_string(error_status_map[i].msg);
+          return true;
         }
       }
     }
-    return NULL;
+    return false;
+  }
+  uint8_t slot = err->strs[which];
+  if (slot != UINT8_MAX) {
+    *str = *(grpc_slice *)(err->arena + slot);
+    return true;
+  } else {
+    return false;
   }
-  return gpr_avl_get(err->strs, (void *)(uintptr_t)which);
 }
 
 grpc_error *grpc_error_add_child(grpc_error *src, grpc_error *child) {
   GPR_TIMER_BEGIN("grpc_error_add_child", 0);
   grpc_error *new = copy_error_and_unref(src);
-  new->errs = gpr_avl_add(new->errs, (void *)(new->next_err++), child);
+  internal_add_error(&new, child);
   GPR_TIMER_END("grpc_error_add_child", 0);
   return new;
 }
@@ -372,42 +528,6 @@ typedef struct {
   size_t cap_kvs;
 } kv_pairs;
 
-static void append_kv(kv_pairs *kvs, char *key, char *value) {
-  if (kvs->num_kvs == kvs->cap_kvs) {
-    kvs->cap_kvs = GPR_MAX(3 * kvs->cap_kvs / 2, 4);
-    kvs->kvs = gpr_realloc(kvs->kvs, sizeof(*kvs->kvs) * kvs->cap_kvs);
-  }
-  kvs->kvs[kvs->num_kvs].key = key;
-  kvs->kvs[kvs->num_kvs].value = value;
-  kvs->num_kvs++;
-}
-
-static void collect_kvs(gpr_avl_node *node, char *key(void *k),
-                        char *fmt(void *v), kv_pairs *kvs) {
-  if (node == NULL) return;
-  append_kv(kvs, key(node->key), fmt(node->value));
-  collect_kvs(node->left, key, fmt, kvs);
-  collect_kvs(node->right, key, fmt, kvs);
-}
-
-static char *key_int(void *p) {
-  return gpr_strdup(error_int_name((grpc_error_ints)(uintptr_t)p));
-}
-
-static char *key_str(void *p) {
-  return gpr_strdup(error_str_name((grpc_error_strs)(uintptr_t)p));
-}
-
-static char *key_time(void *p) {
-  return gpr_strdup(error_time_name((grpc_error_times)(uintptr_t)p));
-}
-
-static char *fmt_int(void *p) {
-  char *s;
-  gpr_asprintf(&s, "%" PRIdPTR, (intptr_t)p);
-  return s;
-}
-
 static void append_chr(char c, char **s, size_t *sz, size_t *cap) {
   if (*sz == *cap) {
     *cap = GPR_MAX(8, 3 * *cap / 2);
@@ -422,13 +542,14 @@ static void append_str(const char *str, char **s, size_t *sz, size_t *cap) {
   }
 }
 
-static void append_esc_str(const char *str, char **s, size_t *sz, size_t *cap) {
+static void append_esc_str(const uint8_t *str, size_t len, char **s, size_t *sz,
+                           size_t *cap) {
   static const char *hex = "0123456789abcdef";
   append_chr('"', s, sz, cap);
-  for (const uint8_t *c = (const uint8_t *)str; *c; c++) {
-    if (*c < 32 || *c >= 127) {
+  for (size_t i = 0; i < len; i++, str++) {
+    if (*str < 32 || *str >= 127) {
       append_chr('\\', s, sz, cap);
-      switch (*c) {
+      switch (*str) {
         case '\b':
           append_chr('b', s, sz, cap);
           break;
@@ -448,28 +569,76 @@ static void append_esc_str(const char *str, char **s, size_t *sz, size_t *cap) {
           append_chr('u', s, sz, cap);
           append_chr('0', s, sz, cap);
           append_chr('0', s, sz, cap);
-          append_chr(hex[*c >> 4], s, sz, cap);
-          append_chr(hex[*c & 0x0f], s, sz, cap);
+          append_chr(hex[*str >> 4], s, sz, cap);
+          append_chr(hex[*str & 0x0f], s, sz, cap);
           break;
       }
     } else {
-      append_chr((char)*c, s, sz, cap);
+      append_chr((char)*str, s, sz, cap);
     }
   }
   append_chr('"', s, sz, cap);
 }
 
-static char *fmt_str(void *p) {
+static void append_kv(kv_pairs *kvs, char *key, char *value) {
+  if (kvs->num_kvs == kvs->cap_kvs) {
+    kvs->cap_kvs = GPR_MAX(3 * kvs->cap_kvs / 2, 4);
+    kvs->kvs = gpr_realloc(kvs->kvs, sizeof(*kvs->kvs) * kvs->cap_kvs);
+  }
+  kvs->kvs[kvs->num_kvs].key = key;
+  kvs->kvs[kvs->num_kvs].value = value;
+  kvs->num_kvs++;
+}
+
+static char *key_int(grpc_error_ints which) {
+  return gpr_strdup(error_int_name(which));
+}
+
+static char *fmt_int(intptr_t p) {
+  char *s;
+  gpr_asprintf(&s, "%" PRIdPTR, p);
+  return s;
+}
+
+static void collect_ints_kvs(grpc_error *err, kv_pairs *kvs) {
+  for (size_t which = 0; which < GRPC_ERROR_INT_MAX; ++which) {
+    uint8_t slot = err->ints[which];
+    if (slot != UINT8_MAX) {
+      append_kv(kvs, key_int((grpc_error_ints)which),
+                fmt_int(err->arena[slot]));
+    }
+  }
+}
+
+static char *key_str(grpc_error_strs which) {
+  return gpr_strdup(error_str_name(which));
+}
+
+static char *fmt_str(grpc_slice slice) {
   char *s = NULL;
   size_t sz = 0;
   size_t cap = 0;
-  append_esc_str(p, &s, &sz, &cap);
+  append_esc_str((const uint8_t *)GRPC_SLICE_START_PTR(slice),
+                 GRPC_SLICE_LENGTH(slice), &s, &sz, &cap);
   append_chr(0, &s, &sz, &cap);
   return s;
 }
 
-static char *fmt_time(void *p) {
-  gpr_timespec tm = *(gpr_timespec *)p;
+static void collect_strs_kvs(grpc_error *err, kv_pairs *kvs) {
+  for (size_t which = 0; which < GRPC_ERROR_STR_MAX; ++which) {
+    uint8_t slot = err->strs[which];
+    if (slot != UINT8_MAX) {
+      append_kv(kvs, key_str((grpc_error_strs)which),
+                fmt_str(*(grpc_slice *)(err->arena + slot)));
+    }
+  }
+}
+
+static char *key_time(grpc_error_times which) {
+  return gpr_strdup(error_time_name(which));
+}
+
+static char *fmt_time(gpr_timespec tm) {
   char *out;
   char *pfx = "!!";
   switch (tm.clock_type) {
@@ -490,24 +659,37 @@ static char *fmt_time(void *p) {
   return out;
 }
 
-static void add_errs(gpr_avl_node *n, char **s, size_t *sz, size_t *cap,
-                     bool *first) {
-  if (n == NULL) return;
-  add_errs(n->left, s, sz, cap, first);
-  if (!*first) append_chr(',', s, sz, cap);
-  *first = false;
-  const char *e = grpc_error_string(n->value);
-  append_str(e, s, sz, cap);
-  add_errs(n->right, s, sz, cap, first);
+static void collect_times_kvs(grpc_error *err, kv_pairs *kvs) {
+  for (size_t which = 0; which < GRPC_ERROR_TIME_MAX; ++which) {
+    uint8_t slot = err->times[which];
+    if (slot != UINT8_MAX) {
+      append_kv(kvs, key_time((grpc_error_times)which),
+                fmt_time(*(gpr_timespec *)(err->arena + slot)));
+    }
+  }
+}
+
+static void add_errs(grpc_error *err, char **s, size_t *sz, size_t *cap) {
+  uint8_t slot = err->first_err;
+  bool first = true;
+  while (slot != UINT8_MAX) {
+    grpc_linked_error *lerr = (grpc_linked_error *)(err->arena + slot);
+    if (!first) append_chr(',', s, sz, cap);
+    first = false;
+    const char *e = grpc_error_string(lerr->err);
+    append_str(e, s, sz, cap);
+    GPR_ASSERT(err->last_err == slot ? lerr->next == UINT8_MAX
+                                     : lerr->next != UINT8_MAX);
+    slot = lerr->next;
+  }
 }
 
 static char *errs_string(grpc_error *err) {
   char *s = NULL;
   size_t sz = 0;
   size_t cap = 0;
-  bool first = true;
   append_chr('[', &s, &sz, &cap);
-  add_errs(err->errs.root, &s, &sz, &cap, &first);
+  add_errs(err, &s, &sz, &cap);
   append_chr(']', &s, &sz, &cap);
   append_chr(0, &s, &sz, &cap);
   return s;
@@ -527,7 +709,8 @@ static char *finish_kvs(kv_pairs *kvs) {
   append_chr('{', &s, &sz, &cap);
   for (size_t i = 0; i < kvs->num_kvs; i++) {
     if (i != 0) append_chr(',', &s, &sz, &cap);
-    append_esc_str(kvs->kvs[i].key, &s, &sz, &cap);
+    append_esc_str((const uint8_t *)kvs->kvs[i].key, strlen(kvs->kvs[i].key),
+                   &s, &sz, &cap);
     gpr_free(kvs->kvs[i].key);
     append_chr(':', &s, &sz, &cap);
     append_str(kvs->kvs[i].value, &s, &sz, &cap);
@@ -546,7 +729,7 @@ const char *grpc_error_string(grpc_error *err) {
   if (err == GRPC_ERROR_OOM) return oom_error_string;
   if (err == GRPC_ERROR_CANCELLED) return cancelled_error_string;
 
-  void *p = (void *)gpr_atm_acq_load(&err->error_string);
+  void *p = (void *)gpr_atm_acq_load(&err->atomics.error_string);
   if (p != NULL) {
     GPR_TIMER_END("grpc_error_string", 0);
     return p;
@@ -555,10 +738,10 @@ const char *grpc_error_string(grpc_error *err) {
   kv_pairs kvs;
   memset(&kvs, 0, sizeof(kvs));
 
-  collect_kvs(err->ints.root, key_int, fmt_int, &kvs);
-  collect_kvs(err->strs.root, key_str, fmt_str, &kvs);
-  collect_kvs(err->times.root, key_time, fmt_time, &kvs);
-  if (!gpr_avl_is_empty(err->errs)) {
+  collect_ints_kvs(err, &kvs);
+  collect_strs_kvs(err, &kvs);
+  collect_times_kvs(err, &kvs);
+  if (err->first_err != UINT8_MAX) {
     append_kv(&kvs, gpr_strdup("referenced_errors"), errs_string(err));
   }
 
@@ -566,9 +749,9 @@ const char *grpc_error_string(grpc_error *err) {
 
   char *out = finish_kvs(&kvs);
 
-  if (!gpr_atm_rel_cas(&err->error_string, 0, (gpr_atm)out)) {
+  if (!gpr_atm_rel_cas(&err->atomics.error_string, 0, (gpr_atm)out)) {
     gpr_free(out);
-    out = (char *)gpr_atm_no_barrier_load(&err->error_string);
+    out = (char *)gpr_atm_no_barrier_load(&err->atomics.error_string);
   }
 
   GPR_TIMER_END("grpc_error_string", 0);
@@ -579,10 +762,14 @@ grpc_error *grpc_os_error(const char *file, int line, int err,
                           const char *call_name) {
   return grpc_error_set_str(
       grpc_error_set_str(
-          grpc_error_set_int(grpc_error_create(file, line, "OS Error", NULL, 0),
-                             GRPC_ERROR_INT_ERRNO, err),
-          GRPC_ERROR_STR_OS_ERROR, strerror(err)),
-      GRPC_ERROR_STR_SYSCALL, call_name);
+          grpc_error_set_int(
+              grpc_error_create(file, line,
+                                grpc_slice_from_static_string("OS Error"), NULL,
+                                0),
+              GRPC_ERROR_INT_ERRNO, err),
+          GRPC_ERROR_STR_OS_ERROR,
+          grpc_slice_from_static_string(strerror(err))),
+      GRPC_ERROR_STR_SYSCALL, grpc_slice_from_static_string(call_name));
 }
 
 #ifdef GPR_WINDOWS
@@ -591,10 +778,13 @@ grpc_error *grpc_wsa_error(const char *file, int line, int err,
   char *utf8_message = gpr_format_message(err);
   grpc_error *error = grpc_error_set_str(
       grpc_error_set_str(
-          grpc_error_set_int(grpc_error_create(file, line, "OS Error", NULL, 0),
-                             GRPC_ERROR_INT_WSA_ERROR, err),
-          GRPC_ERROR_STR_OS_ERROR, utf8_message),
-      GRPC_ERROR_STR_SYSCALL, call_name);
+          grpc_error_set_int(
+              grpc_error_create(file, line,
+                                grpc_slice_from_static_string("OS Error"), NULL,
+                                0),
+              GRPC_ERROR_INT_WSA_ERROR, err),
+          GRPC_ERROR_STR_OS_ERROR, grpc_slice_from_copied_string(utf8_message)),
+      GRPC_ERROR_STR_SYSCALL, grpc_slice_from_static_string(call_name));
   gpr_free(utf8_message);
   return error;
 }
diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h
index 2613512acbeedd5970d64bb10a07e4cf1bb56c45..34b24d926388efe811ebd47e89464579593f2520 100644
--- a/src/core/lib/iomgr/error.h
+++ b/src/core/lib/iomgr/error.h
@@ -37,6 +37,7 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#include <grpc/slice.h>
 #include <grpc/status.h>
 #include <grpc/support/time.h>
 
@@ -45,28 +46,9 @@ extern "C" {
 #endif
 
 /// Opaque representation of an error.
-/// Errors are refcounted objects that represent the result of an operation.
-/// Ownership laws:
-///  if a grpc_error is returned by a function, the caller owns a ref to that
-///    instance
-///  if a grpc_error is passed to a grpc_closure callback function (functions
-///    with the signature:
-///      void (*f)(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error))
-///    then those functions do not own a ref to error (but are free to manually
-///    take a reference).
-///  if a grpc_error is passed to *ANY OTHER FUNCTION* then that function takes
-///    ownership of the error
-/// Errors have:
-///  a set of ints, strings, and timestamps that describe the error
-///  always present are:
-///    GRPC_ERROR_STR_FILE, GRPC_ERROR_INT_FILE_LINE - source location the error
-///      was generated
-///    GRPC_ERROR_STR_DESCRIPTION - a human readable description of the error
-///    GRPC_ERROR_TIME_CREATED - a timestamp indicating when the error happened
-///  an error can also have children; these are other errors that are believed
-///    to have contributed to this one. By accumulating children, we can begin
-///    to root cause high level failures from low level failures, without having
-///    to derive execution paths from log lines
+/// See https://github.com/grpc/grpc/blob/master/doc/core/grpc-error.md for a
+/// full write up of this object.
+
 typedef struct grpc_error grpc_error;
 
 typedef enum {
@@ -102,6 +84,9 @@ typedef enum {
   GRPC_ERROR_INT_LIMIT,
   /// chttp2: did the error occur while a write was in progress
   GRPC_ERROR_INT_OCCURRED_DURING_WRITE,
+
+  /// Must always be last
+  GRPC_ERROR_INT_MAX,
 } grpc_error_ints;
 
 typedef enum {
@@ -129,11 +114,17 @@ typedef enum {
   GRPC_ERROR_STR_KEY,
   /// value associated with the error
   GRPC_ERROR_STR_VALUE,
+
+  /// Must always be last
+  GRPC_ERROR_STR_MAX,
 } grpc_error_strs;
 
 typedef enum {
   /// timestamp of error creation
   GRPC_ERROR_TIME_CREATED,
+
+  /// Must always be last
+  GRPC_ERROR_TIME_MAX,
 } grpc_error_times;
 
 /// The following "special" errors can be propagated without allocating memory.
@@ -147,7 +138,7 @@ typedef enum {
 const char *grpc_error_string(grpc_error *error);
 
 /// Create an error - but use GRPC_ERROR_CREATE instead
-grpc_error *grpc_error_create(const char *file, int line, const char *desc,
+grpc_error *grpc_error_create(const char *file, int line, grpc_slice desc,
                               grpc_error **referencing, size_t num_referencing);
 /// Create an error (this is the preferred way of generating an error that is
 ///   not due to a system call - for system calls, use GRPC_OS_ERROR or
@@ -157,13 +148,21 @@ grpc_error *grpc_error_create(const char *file, int line, const char *desc,
 /// err = grpc_error_create(x, y, z, r, nr) is equivalent to:
 ///   err = grpc_error_create(x, y, z, NULL, 0);
 ///   for (i=0; i<nr; i++) err = grpc_error_add_child(err, r[i]);
-#define GRPC_ERROR_CREATE(desc) \
-  grpc_error_create(__FILE__, __LINE__, desc, NULL, 0)
+#define GRPC_ERROR_CREATE_FROM_STATIC_STRING(desc)                           \
+  grpc_error_create(__FILE__, __LINE__, grpc_slice_from_static_string(desc), \
+                    NULL, 0)
+#define GRPC_ERROR_CREATE_FROM_COPIED_STRING(desc)                           \
+  grpc_error_create(__FILE__, __LINE__, grpc_slice_from_copied_string(desc), \
+                    NULL, 0)
 
 // Create an error that references some other errors. This function adds a
 // reference to each error in errs - it does not consume an existing reference
-#define GRPC_ERROR_CREATE_REFERENCING(desc, errs, count) \
-  grpc_error_create(__FILE__, __LINE__, desc, errs, count)
+#define GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(desc, errs, count)  \
+  grpc_error_create(__FILE__, __LINE__, grpc_slice_from_static_string(desc), \
+                    errs, count)
+#define GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(desc, errs, count)  \
+  grpc_error_create(__FILE__, __LINE__, grpc_slice_from_copied_string(desc), \
+                    errs, count)
 
 //#define GRPC_ERROR_REFCOUNT_DEBUG
 #ifdef GRPC_ERROR_REFCOUNT_DEBUG
@@ -184,13 +183,12 @@ void grpc_error_unref(grpc_error *err);
 grpc_error *grpc_error_set_int(grpc_error *src, grpc_error_ints which,
                                intptr_t value) GRPC_MUST_USE_RESULT;
 bool grpc_error_get_int(grpc_error *error, grpc_error_ints which, intptr_t *p);
-grpc_error *grpc_error_set_time(grpc_error *src, grpc_error_times which,
-                                gpr_timespec value) GRPC_MUST_USE_RESULT;
 grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which,
-                               const char *value) GRPC_MUST_USE_RESULT;
-/// Returns NULL if the specified string is not set.
-/// Caller does NOT own return value.
-const char *grpc_error_get_str(grpc_error *error, grpc_error_strs which);
+                               grpc_slice str) GRPC_MUST_USE_RESULT;
+/// Returns false if the specified string is not set.
+/// Caller does NOT own the slice.
+bool grpc_error_get_str(grpc_error *error, grpc_error_strs which,
+                        grpc_slice *s);
 
 /// Add a child error: an error that is believed to have contributed to this
 /// error occurring. Allows root causing high level errors from lower level
diff --git a/src/core/lib/iomgr/error_internal.h b/src/core/lib/iomgr/error_internal.h
index 1c89ead4ed66d53b36d81195bcccba2ba98ac5e7..7f204df1b2db613e273567d783dbdb1234207c21 100644
--- a/src/core/lib/iomgr/error_internal.h
+++ b/src/core/lib/iomgr/error_internal.h
@@ -35,18 +35,39 @@
 #define GRPC_CORE_LIB_IOMGR_ERROR_INTERNAL_H
 
 #include <inttypes.h>
-#include <stdbool.h>
+#include <stdbool.h>  // TODO, do we need this?
 
-#include <grpc/support/avl.h>
+#include <grpc/support/sync.h>
 
+typedef struct grpc_linked_error grpc_linked_error;
+
+struct grpc_linked_error {
+  grpc_error *err;
+  uint8_t next;
+};
+
+// c core representation of an error. See error.h for high level description of
+// this object.
 struct grpc_error {
-  gpr_refcount refs;
-  gpr_avl ints;
-  gpr_avl strs;
-  gpr_avl times;
-  gpr_avl errs;
-  uintptr_t next_err;
-  gpr_atm error_string;
+  // All atomics in grpc_error must be stored in this nested struct. The rest of
+  // the object is memcpy-ed in bulk in copy_and_unref.
+  struct atomics {
+    gpr_refcount refs;
+    gpr_atm error_string;
+  } atomics;
+  // These arrays index into dynamic arena at the bottom of the struct.
+  // UINT8_MAX is used as a sentinel value.
+  uint8_t ints[GRPC_ERROR_INT_MAX];
+  uint8_t strs[GRPC_ERROR_STR_MAX];
+  uint8_t times[GRPC_ERROR_TIME_MAX];
+  // The child errors are stored in the arena, but are effectively a linked list
+  // structure, since they are contained withing grpc_linked_error objects.
+  uint8_t first_err;
+  uint8_t last_err;
+  // The arena is dynamically reallocated with a grow factor of 1.5.
+  uint8_t arena_size;
+  uint8_t arena_capacity;
+  intptr_t arena[0];
 };
 
 bool grpc_error_is_special(grpc_error *err);
diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c
index 11208b9ad13d5033355ac9902a306ecaf9f2c5a2..e603a755937286e80ab1d8d14cd51be6c3a9287e 100644
--- a/src/core/lib/iomgr/ev_epoll_linux.c
+++ b/src/core/lib/iomgr/ev_epoll_linux.c
@@ -56,6 +56,8 @@
 
 #include "src/core/lib/iomgr/ev_posix.h"
 #include "src/core/lib/iomgr/iomgr_internal.h"
+#include "src/core/lib/iomgr/lockfree_event.h"
+#include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/iomgr/wakeup_fd_posix.h"
 #include "src/core/lib/iomgr/workqueue.h"
 #include "src/core/lib/profiling/timers.h"
@@ -140,52 +142,11 @@ struct grpc_fd {
      Ref/Unref by two to avoid altering the orphaned bit */
   gpr_atm refst;
 
-  /* Internally stores data of type (grpc_error *). If the FD is shutdown, this
-     contains reason for shutdown (i.e a pointer to grpc_error) ORed with
-     FD_SHUTDOWN_BIT. Since address allocations are word-aligned, the lower bit
-     of (grpc_error *) addresses is guaranteed to be zero. Even if the
-     (grpc_error *), is of special types like GRPC_ERROR_NONE, GRPC_ERROR_OOM
-     etc, the lower bit is guaranteed to be zero.
-
-     Once an fd is shutdown, any pending or future read/write closures on the
-     fd should fail */
-  gpr_atm shutdown_error;
-
   /* The fd is either closed or we relinquished control of it. In either
      cases, this indicates that the 'fd' on this structure is no longer
      valid */
   bool orphaned;
 
-  /* Closures to call when the fd is readable or writable respectively. These
-     fields contain one of the following values:
-       CLOSURE_READY     : The fd has an I/O event of interest but there is no
-                           closure yet to execute
-
-       CLOSURE_NOT_READY : The fd has no I/O event of interest
-
-       closure ptr       : The closure to be executed when the fd has an I/O
-                           event of interest
-
-       shutdown_error | FD_SHUTDOWN_BIT :
-                          'shutdown_error' field ORed with FD_SHUTDOWN_BIT.
-                           This indicates that the fd is shutdown. Since all
-                           memory allocations are word-aligned, the lower two
-                           bits of the shutdown_error pointer are always 0. So
-                           it is safe to OR these with FD_SHUTDOWN_BIT
-
-     Valid state transitions:
-
-       <closure ptr> <-----3------ CLOSURE_NOT_READY ----1---->  CLOSURE_READY
-         |  |                         ^   |    ^                         |  |
-         |  |                         |   |    |                         |  |
-         |  +--------------4----------+   6    +---------2---------------+  |
-         |                                |                                 |
-         |                                v                                 |
-         +-----5------->  [shutdown_error | FD_SHUTDOWN_BIT] <----7---------+
-
-      For 1, 4 : See set_ready() function
-      For 2, 3 : See notify_on() function
-      For 5,6,7: See set_shutdown() function */
   gpr_atm read_closure;
   gpr_atm write_closure;
 
@@ -217,11 +178,6 @@ static void fd_unref(grpc_fd *fd);
 static void fd_global_init(void);
 static void fd_global_shutdown(void);
 
-#define CLOSURE_NOT_READY ((gpr_atm)0)
-#define CLOSURE_READY ((gpr_atm)2)
-
-#define FD_SHUTDOWN_BIT 1
-
 /*******************************************************************************
  * Polling island Declarations
  */
@@ -321,7 +277,7 @@ static bool append_error(grpc_error **composite, grpc_error *error,
                          const char *desc) {
   if (error == GRPC_ERROR_NONE) return true;
   if (*composite == GRPC_ERROR_NONE) {
-    *composite = GRPC_ERROR_CREATE(desc);
+    *composite = GRPC_ERROR_CREATE_FROM_COPIED_STRING(desc);
   }
   *composite = grpc_error_add_child(*composite, error);
   return false;
@@ -948,10 +904,8 @@ static void unref_by(grpc_fd *fd, int n) {
     fd_freelist = fd;
     grpc_iomgr_unregister_object(&fd->iomgr_object);
 
-    grpc_error *err = (grpc_error *)gpr_atm_acq_load(&fd->shutdown_error);
-    /* Clear the least significant bit if it set (in case fd was shutdown) */
-    err = (grpc_error *)((intptr_t)err & ~FD_SHUTDOWN_BIT);
-    GRPC_ERROR_UNREF(err);
+    grpc_lfev_destroy(&fd->read_closure);
+    grpc_lfev_destroy(&fd->write_closure);
 
     gpr_mu_unlock(&fd_freelist_mu);
   } else {
@@ -1015,10 +969,9 @@ static grpc_fd *fd_create(int fd, const char *name) {
 
   gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1);
   new_fd->fd = fd;
-  gpr_atm_no_barrier_store(&new_fd->shutdown_error, (gpr_atm)GRPC_ERROR_NONE);
   new_fd->orphaned = false;
-  gpr_atm_no_barrier_store(&new_fd->read_closure, CLOSURE_NOT_READY);
-  gpr_atm_no_barrier_store(&new_fd->write_closure, CLOSURE_NOT_READY);
+  grpc_lfev_init(&new_fd->read_closure);
+  grpc_lfev_init(&new_fd->write_closure);
   gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
 
   new_fd->freelist_next = NULL;
@@ -1104,172 +1057,6 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
   GRPC_ERROR_UNREF(error);
 }
 
-static void notify_on(grpc_exec_ctx *exec_ctx, grpc_fd *fd, gpr_atm *state,
-                      grpc_closure *closure) {
-  while (true) {
-    /* Fast-path: CLOSURE_NOT_READY -> <closure>.
-       The 'release' cas here matches the 'acquire' load in set_ready and
-       set_shutdown ensuring that the closure (scheduled by set_ready or
-       set_shutdown) happens-after the I/O event on the fd */
-    if (gpr_atm_rel_cas(state, CLOSURE_NOT_READY, (gpr_atm)closure)) {
-      return; /* Fast-path successful. Return */
-    }
-
-    /* Slowpath. The 'acquire' load matches the 'release' cas in set_ready and
-       set_shutdown */
-    gpr_atm curr = gpr_atm_acq_load(state);
-    switch (curr) {
-      case CLOSURE_NOT_READY: {
-        break; /* retry */
-      }
-
-      case CLOSURE_READY: {
-        /* Change the state to CLOSURE_NOT_READY. Schedule the closure if
-           successful. If not, the state most likely transitioned to shutdown.
-           We should retry.
-
-           This can be a no-barrier cas since the state is being transitioned to
-           CLOSURE_NOT_READY; set_ready and set_shutdown do not schedule any
-           closure when transitioning out of CLOSURE_NO_READY state (i.e there
-           is no other code that needs to 'happen-after' this) */
-        if (gpr_atm_no_barrier_cas(state, CLOSURE_READY, CLOSURE_NOT_READY)) {
-          grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE);
-          return; /* Slow-path successful. Return */
-        }
-
-        break; /* retry */
-      }
-
-      default: {
-        /* 'curr' is either a closure or the fd is shutdown(in which case 'curr'
-           contains a pointer to the shutdown-error). If the fd is shutdown,
-           schedule the closure with the shutdown error */
-        if ((curr & FD_SHUTDOWN_BIT) > 0) {
-          grpc_error *shutdown_err = (grpc_error *)(curr & ~FD_SHUTDOWN_BIT);
-          grpc_closure_sched(
-              exec_ctx, closure,
-              GRPC_ERROR_CREATE_REFERENCING("FD Shutdown", &shutdown_err, 1));
-          return;
-        }
-
-        /* There is already a closure!. This indicates a bug in the code */
-        gpr_log(GPR_ERROR,
-                "notify_on called with a previous callback still pending");
-        abort();
-      }
-    }
-  }
-
-  GPR_UNREACHABLE_CODE(return );
-}
-
-static void set_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd, gpr_atm *state,
-                         grpc_error *shutdown_err) {
-  /* Try the fast-path first (i.e expect the current value to be
-     CLOSURE_NOT_READY */
-  gpr_atm curr = CLOSURE_NOT_READY;
-  gpr_atm new_state = (gpr_atm)shutdown_err | FD_SHUTDOWN_BIT;
-
-  while (true) {
-    /* The 'release' cas here matches the 'acquire' load in notify_on to ensure
-       that the closure it schedules 'happens-after' the set_shutdown is called
-       on the fd */
-    if (gpr_atm_rel_cas(state, curr, new_state)) {
-      return; /* Fast-path successful. Return */
-    }
-
-    /* Fallback to slowpath. This 'acquire' load matches the 'release' cas in
-       notify_on and set_ready */
-    curr = gpr_atm_acq_load(state);
-    switch (curr) {
-      case CLOSURE_READY: {
-        break; /* retry */
-      }
-
-      case CLOSURE_NOT_READY: {
-        break; /* retry */
-      }
-
-      default: {
-        /* 'curr' is either a closure or the fd is already shutdown */
-
-        /* If fd is already shutdown, we are done */
-        if ((curr & FD_SHUTDOWN_BIT) > 0) {
-          return;
-        }
-
-        /* Fd is not shutdown. Schedule the closure and move the state to
-           shutdown state. The 'release' cas here matches the 'acquire' load in
-           notify_on to ensure that the closure it schedules 'happens-after'
-           the set_shutdown is called on the fd */
-        if (gpr_atm_rel_cas(state, curr, new_state)) {
-          grpc_closure_sched(
-              exec_ctx, (grpc_closure *)curr,
-              GRPC_ERROR_CREATE_REFERENCING("FD Shutdown", &shutdown_err, 1));
-          return;
-        }
-
-        /* 'curr' was a closure but now changed to a different state. We will
-          have to retry */
-        break;
-      }
-    }
-  }
-
-  GPR_UNREACHABLE_CODE(return );
-}
-
-static void set_ready(grpc_exec_ctx *exec_ctx, grpc_fd *fd, gpr_atm *state) {
-  /* Try an optimistic case first (i.e assume current state is
-     CLOSURE_NOT_READY).
-
-     This 'release' cas matches the 'acquire' load in notify_on ensuring that
-     any closure (scheduled by notify_on) 'happens-after' the return from
-     epoll_pwait */
-  if (gpr_atm_rel_cas(state, CLOSURE_NOT_READY, CLOSURE_READY)) {
-    return; /* early out */
-  }
-
-  /* The 'acquire' load here matches the 'release' cas in notify_on and
-     set_shutdown */
-  gpr_atm curr = gpr_atm_acq_load(state);
-  switch (curr) {
-    case CLOSURE_READY: {
-      /* Already ready. We are done here */
-      break;
-    }
-
-    case CLOSURE_NOT_READY: {
-      /* The state was not CLOSURE_NOT_READY when we checked initially at the
-         beginning of this function but now it is CLOSURE_NOT_READY again.
-         This is only possible if the state transitioned out of
-         CLOSURE_NOT_READY to either CLOSURE_READY or <some closure> and then
-         back to CLOSURE_NOT_READY again (i.e after we entered this function,
-         the fd became "ready" and the necessary actions were already done).
-         So there is no need to make the state CLOSURE_READY now */
-      break;
-    }
-
-    default: {
-      /* 'curr' is either a closure or the fd is shutdown */
-      if ((curr & FD_SHUTDOWN_BIT) > 0) {
-        /* The fd is shutdown. Do nothing */
-      } else if (gpr_atm_no_barrier_cas(state, curr, CLOSURE_NOT_READY)) {
-        /* The cas above was no-barrier since the state is being transitioned to
-           CLOSURE_NOT_READY; notify_on and set_shutdown do not schedule any
-           closures when transitioning out of CLOSURE_NO_READY state (i.e there
-           is no other code that needs to 'happen-after' this) */
-
-        grpc_closure_sched(exec_ctx, (grpc_closure *)curr, GRPC_ERROR_NONE);
-      }
-      /* else the state changed again (only possible by either a racing
-         set_ready or set_shutdown functions. In both these cases, the closure
-         would have been scheduled for execution. So we are done here */
-      break;
-    }
-  }
-}
-
 static grpc_pollset *fd_get_read_notifier_pollset(grpc_exec_ctx *exec_ctx,
                                                   grpc_fd *fd) {
   gpr_atm notifier = gpr_atm_acq_load(&fd->read_notifier_pollset);
@@ -1277,33 +1064,27 @@ static grpc_pollset *fd_get_read_notifier_pollset(grpc_exec_ctx *exec_ctx,
 }
 
 static bool fd_is_shutdown(grpc_fd *fd) {
-  grpc_error *err = (grpc_error *)gpr_atm_acq_load(&fd->shutdown_error);
-  return (((intptr_t)err & FD_SHUTDOWN_BIT) > 0);
+  return grpc_lfev_is_shutdown(&fd->read_closure);
 }
 
 /* Might be called multiple times */
 static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_error *why) {
-  /* Store the shutdown error ORed with FD_SHUTDOWN_BIT in fd->shutdown_error */
-  if (gpr_atm_rel_cas(&fd->shutdown_error, (gpr_atm)GRPC_ERROR_NONE,
-                      (gpr_atm)why | FD_SHUTDOWN_BIT)) {
+  if (grpc_lfev_set_shutdown(exec_ctx, &fd->read_closure,
+                             GRPC_ERROR_REF(why))) {
     shutdown(fd->fd, SHUT_RDWR);
-
-    set_shutdown(exec_ctx, fd, &fd->read_closure, why);
-    set_shutdown(exec_ctx, fd, &fd->write_closure, why);
-  } else {
-    /* Shutdown already called */
-    GRPC_ERROR_UNREF(why);
+    grpc_lfev_set_shutdown(exec_ctx, &fd->write_closure, GRPC_ERROR_REF(why));
   }
+  GRPC_ERROR_UNREF(why);
 }
 
 static void fd_notify_on_read(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
                               grpc_closure *closure) {
-  notify_on(exec_ctx, fd, &fd->read_closure, closure);
+  grpc_lfev_notify_on(exec_ctx, &fd->read_closure, closure);
 }
 
 static void fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
                                grpc_closure *closure) {
-  notify_on(exec_ctx, fd, &fd->write_closure, closure);
+  grpc_lfev_notify_on(exec_ctx, &fd->write_closure, closure);
 }
 
 static grpc_workqueue *fd_get_workqueue(grpc_fd *fd) {
@@ -1351,7 +1132,7 @@ static grpc_error *pollset_worker_kick(grpc_pollset_worker *worker) {
   if (gpr_atm_no_barrier_cas(&worker->is_kicked, (gpr_atm)0, (gpr_atm)1)) {
     GRPC_POLLING_TRACE(
         "pollset_worker_kick: Kicking worker: %p (thread id: %ld)",
-        (void *)worker, worker->pt_id);
+        (void *)worker, (long int)worker->pt_id);
     int err_num = pthread_kill(worker->pt_id, grpc_wakeup_signal);
     if (err_num != 0) {
       err = GRPC_OS_ERROR(err_num, "pthread_kill");
@@ -1486,13 +1267,14 @@ static int poll_deadline_to_millis_timeout(gpr_timespec deadline,
     return 0;
   }
   timeout = gpr_time_sub(deadline, now);
-  return gpr_time_to_millis(gpr_time_add(
+  int millis = gpr_time_to_millis(gpr_time_add(
       timeout, gpr_time_from_nanos(GPR_NS_PER_MS - 1, GPR_TIMESPAN)));
+  return millis >= 1 ? millis : 1;
 }
 
 static void fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
                                grpc_pollset *notifier) {
-  set_ready(exec_ctx, fd, &fd->read_closure);
+  grpc_lfev_set_ready(exec_ctx, &fd->read_closure);
 
   /* Note, it is possible that fd_become_readable might be called twice with
      different 'notifier's when an fd becomes readable and it is in two epoll
@@ -1504,7 +1286,7 @@ static void fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
 }
 
 static void fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
-  set_ready(exec_ctx, fd, &fd->write_closure);
+  grpc_lfev_set_ready(exec_ctx, &fd->write_closure);
 }
 
 static void pollset_release_polling_island(grpc_exec_ctx *exec_ctx,
@@ -1566,6 +1348,9 @@ static bool maybe_do_workqueue_work(grpc_exec_ctx *exec_ctx,
       }
       grpc_closure *c = (grpc_closure *)n;
       grpc_error *error = c->error_data.error;
+#ifndef NDEBUG
+      c->scheduled = false;
+#endif
       c->cb(exec_ctx, c->cb_arg, error);
       GRPC_ERROR_UNREF(error);
       return true;
@@ -1669,6 +1454,7 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx,
     for (int i = 0; i < ep_rv; ++i) {
       void *data_ptr = ep_ev[i].data.ptr;
       if (data_ptr == &global_wakeup_fd) {
+        grpc_timer_consume_kick();
         append_error(error, grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd),
                      err_desc);
       } else if (data_ptr == &pi->workqueue_wakeup_fd) {
@@ -1733,7 +1519,7 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
   worker.pt_id = pthread_self();
   gpr_atm_no_barrier_store(&worker.is_kicked, (gpr_atm)0);
 
-  *worker_hdl = &worker;
+  if (worker_hdl) *worker_hdl = &worker;
 
   gpr_tls_set(&g_current_thread_pollset, (intptr_t)pollset);
   gpr_tls_set(&g_current_thread_worker, (intptr_t)&worker);
@@ -1811,7 +1597,7 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
     gpr_mu_lock(&pollset->po.mu);
   }
 
-  *worker_hdl = NULL;
+  if (worker_hdl) *worker_hdl = NULL;
 
   gpr_tls_set(&g_current_thread_pollset, (intptr_t)0);
   gpr_tls_set(&g_current_thread_worker, (intptr_t)0);
diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c
index 5ddd5313e2b0e4ce7db05a688c32b2bf3ce5248d..9834cdd197963df9a92f1176297842f0bc700957 100644
--- a/src/core/lib/iomgr/ev_poll_posix.c
+++ b/src/core/lib/iomgr/ev_poll_posix.c
@@ -52,6 +52,7 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/iomgr/iomgr_internal.h"
+#include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/iomgr/wakeup_fd_cv.h"
 #include "src/core/lib/iomgr/wakeup_fd_posix.h"
 #include "src/core/lib/profiling/timers.h"
@@ -451,14 +452,16 @@ static grpc_error *fd_shutdown_error(grpc_fd *fd) {
   if (!fd->shutdown) {
     return GRPC_ERROR_NONE;
   } else {
-    return GRPC_ERROR_CREATE_REFERENCING("FD shutdown", &fd->shutdown_error, 1);
+    return GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+        "FD shutdown", &fd->shutdown_error, 1);
   }
 }
 
 static void notify_on_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
                              grpc_closure **st, grpc_closure *closure) {
   if (fd->shutdown) {
-    grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_CREATE("FD shutdown"));
+    grpc_closure_sched(exec_ctx, closure,
+                       GRPC_ERROR_CREATE_FROM_STATIC_STRING("FD shutdown"));
   } else if (*st == CLOSURE_NOT_READY) {
     /* not ready ==> switch to a waiting state by setting the closure */
     *st = closure;
@@ -696,7 +699,7 @@ static void push_front_worker(grpc_pollset *p, grpc_pollset_worker *worker) {
 static void kick_append_error(grpc_error **composite, grpc_error *error) {
   if (error == GRPC_ERROR_NONE) return;
   if (*composite == GRPC_ERROR_NONE) {
-    *composite = GRPC_ERROR_CREATE("Kick Failure");
+    *composite = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Kick Failure");
   }
   *composite = grpc_error_add_child(*composite, error);
 }
@@ -859,7 +862,7 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset) {
 static void work_combine_error(grpc_error **composite, grpc_error *error) {
   if (error == GRPC_ERROR_NONE) return;
   if (*composite == GRPC_ERROR_NONE) {
-    *composite = GRPC_ERROR_CREATE("pollset_work");
+    *composite = GRPC_ERROR_CREATE_FROM_STATIC_STRING("pollset_work");
   }
   *composite = grpc_error_add_child(*composite, error);
 }
@@ -868,7 +871,7 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
                                 grpc_pollset_worker **worker_hdl,
                                 gpr_timespec now, gpr_timespec deadline) {
   grpc_pollset_worker worker;
-  *worker_hdl = &worker;
+  if (worker_hdl) *worker_hdl = &worker;
   grpc_error *error = GRPC_ERROR_NONE;
 
   /* Avoid malloc for small number of elements. */
@@ -1004,6 +1007,7 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
         }
       } else {
         if (pfds[0].revents & POLLIN_CHECK) {
+          grpc_timer_consume_kick();
           work_combine_error(&error,
                              grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd));
         }
@@ -1088,7 +1092,7 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
       gpr_mu_lock(&pollset->mu);
     }
   }
-  *worker_hdl = NULL;
+  if (worker_hdl) *worker_hdl = NULL;
   GPR_TIMER_END("pollset_work", 0);
   GRPC_LOG_IF_ERROR("pollset_work", GRPC_ERROR_REF(error));
   return error;
@@ -1421,7 +1425,7 @@ static int cvfd_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
     g_cvfds.pollcount++;
     opt = gpr_thd_options_default();
     gpr_thd_options_set_detached(&opt);
-    gpr_thd_new(&t_id, &run_poll, pargs, &opt);
+    GPR_ASSERT(gpr_thd_new(&t_id, &run_poll, pargs, &opt));
     // We want the poll() thread to trigger the deadline, so wait forever here
     gpr_cv_wait(pollcv, &g_cvfds.mu, gpr_inf_future(GPR_CLOCK_MONOTONIC));
     if (gpr_atm_no_barrier_load(&pargs->status) == COMPLETED) {
diff --git a/src/core/lib/iomgr/ev_posix.c b/src/core/lib/iomgr/ev_posix.c
index b5be5504b9d044462e6fff3b3999a56dae36fa8f..13409a4de83edd1d6efcd28c7d9bf6db6e09cc10 100644
--- a/src/core/lib/iomgr/ev_posix.c
+++ b/src/core/lib/iomgr/ev_posix.c
@@ -111,6 +111,12 @@ static void try_engine(const char *engine) {
   }
 }
 
+/* This should be used for testing purposes ONLY */
+void grpc_set_event_engine_test_only(
+    const grpc_event_engine_vtable *ev_engine) {
+  g_event_engine = ev_engine;
+}
+
 /* Call this only after calling grpc_event_engine_init() */
 const char *grpc_get_poll_strategy_name() { return g_poll_strategy_name; }
 
diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h
index 1a9e5c115aec82206ec680cadc4ab2820adb70f4..becc4d359e52ad67479ac83791b7170e1d069eef 100644
--- a/src/core/lib/iomgr/ev_posix.h
+++ b/src/core/lib/iomgr/ev_posix.h
@@ -183,4 +183,7 @@ void grpc_pollset_set_del_fd(grpc_exec_ctx *exec_ctx,
 typedef int (*grpc_poll_function_type)(struct pollfd *, nfds_t, int);
 extern grpc_poll_function_type grpc_poll_function;
 
+/* This should be used for testing purposes ONLY */
+void grpc_set_event_engine_test_only(const grpc_event_engine_vtable *);
+
 #endif /* GRPC_CORE_LIB_IOMGR_EV_POSIX_H */
diff --git a/src/core/lib/iomgr/exec_ctx.c b/src/core/lib/iomgr/exec_ctx.c
index 83bb436bd0ad426c6f4f7fdfd964c0ad39fd301f..2532a708e7b0ba9aa0f6caec3ddf90c18c3d3d12 100644
--- a/src/core/lib/iomgr/exec_ctx.c
+++ b/src/core/lib/iomgr/exec_ctx.c
@@ -73,6 +73,9 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) {
         grpc_closure *next = c->next_data.next;
         grpc_error *error = c->error_data.error;
         did_something = true;
+#ifndef NDEBUG
+        c->scheduled = false;
+#endif
         c->cb(exec_ctx, c->cb_arg, error);
         GRPC_ERROR_UNREF(error);
         c = next;
@@ -93,6 +96,9 @@ void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx) {
 
 static void exec_ctx_run(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
                          grpc_error *error) {
+#ifndef NDEBUG
+  closure->scheduled = false;
+#endif
   closure->cb(exec_ctx, closure->cb_arg, error);
   GRPC_ERROR_UNREF(error);
 }
diff --git a/src/core/lib/iomgr/executor.c b/src/core/lib/iomgr/executor.c
index a5b62aa88885ccce3c0f89bb8fc0a945f80e63c4..75fd5b1c50c547575f6ade9fec301d61cfcb6bfd 100644
--- a/src/core/lib/iomgr/executor.c
+++ b/src/core/lib/iomgr/executor.c
@@ -83,6 +83,9 @@ static void closure_exec_thread_func(void *ignored) {
       while (c != NULL) {
         grpc_closure *next = c->next_data.next;
         grpc_error *error = c->error_data.error;
+#ifndef NDEBUG
+        c->scheduled = false;
+#endif
         c->cb(&exec_ctx, c->cb_arg, error);
         GRPC_ERROR_UNREF(error);
         c = next;
@@ -115,8 +118,8 @@ static void maybe_spawn_locked() {
   /* All previous instances of the thread should have been joined at this point.
    * Spawn time! */
   g_executor.busy = 1;
-  gpr_thd_new(&g_executor.tid, closure_exec_thread_func, NULL,
-              &g_executor.options);
+  GPR_ASSERT(gpr_thd_new(&g_executor.tid, closure_exec_thread_func, NULL,
+                         &g_executor.options));
   g_executor.pending_join = 1;
 }
 
@@ -146,6 +149,9 @@ void grpc_executor_shutdown(grpc_exec_ctx *exec_ctx) {
   while (c != NULL) {
     grpc_closure *next = c->next_data.next;
     grpc_error *error = c->error_data.error;
+#ifndef NDEBUG
+    c->scheduled = false;
+#endif
     c->cb(exec_ctx, c->cb_arg, error);
     GRPC_ERROR_UNREF(error);
     c = next;
diff --git a/src/core/lib/iomgr/load_file.c b/src/core/lib/iomgr/load_file.c
index f40c8b28ccd9910cf7b1e4d8709121539cad0ba8..208f74e20cf7203aad6c88bf056f34776ac9dfa7 100644
--- a/src/core/lib/iomgr/load_file.c
+++ b/src/core/lib/iomgr/load_file.c
@@ -78,9 +78,12 @@ end:
   *output = result;
   if (file != NULL) fclose(file);
   if (error != GRPC_ERROR_NONE) {
-    grpc_error *error_out = grpc_error_set_str(
-        GRPC_ERROR_CREATE_REFERENCING("Failed to load file", &error, 1),
-        GRPC_ERROR_STR_FILENAME, filename);
+    grpc_error *error_out =
+        grpc_error_set_str(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                               "Failed to load file", &error, 1),
+                           GRPC_ERROR_STR_FILENAME,
+                           grpc_slice_from_copied_string(
+                               filename));  // TODO(ncteisen), always static?
     GRPC_ERROR_UNREF(error);
     error = error_out;
   }
diff --git a/src/core/lib/iomgr/lockfree_event.c b/src/core/lib/iomgr/lockfree_event.c
new file mode 100644
index 0000000000000000000000000000000000000000..17e3bbf7278ee6065d27674efb858dd040e5b065
--- /dev/null
+++ b/src/core/lib/iomgr/lockfree_event.c
@@ -0,0 +1,238 @@
+/*
+ *
+ * Copyright 2017, 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/lib/iomgr/lockfree_event.h"
+
+#include <grpc/support/log.h>
+
+/* 'state' holds the to call when the fd is readable or writable respectively.
+   It can contain one of the following values:
+     CLOSURE_READY     : The fd has an I/O event of interest but there is no
+                         closure yet to execute
+
+     CLOSURE_NOT_READY : The fd has no I/O event of interest
+
+     closure ptr       : The closure to be executed when the fd has an I/O
+                         event of interest
+
+     shutdown_error | FD_SHUTDOWN_BIT :
+                        'shutdown_error' field ORed with FD_SHUTDOWN_BIT.
+                         This indicates that the fd is shutdown. Since all
+                         memory allocations are word-aligned, the lower two
+                         bits of the shutdown_error pointer are always 0. So
+                         it is safe to OR these with FD_SHUTDOWN_BIT
+
+   Valid state transitions:
+
+     <closure ptr> <-----3------ CLOSURE_NOT_READY ----1---->  CLOSURE_READY
+       |  |                         ^   |    ^                         |  |
+       |  |                         |   |    |                         |  |
+       |  +--------------4----------+   6    +---------2---------------+  |
+       |                                |                                 |
+       |                                v                                 |
+       +-----5------->  [shutdown_error | FD_SHUTDOWN_BIT] <----7---------+
+
+    For 1, 4 : See grpc_lfev_set_ready() function
+    For 2, 3 : See grpc_lfev_notify_on() function
+    For 5,6,7: See grpc_lfev_set_shutdown() function */
+
+#define CLOSURE_NOT_READY ((gpr_atm)0)
+#define CLOSURE_READY ((gpr_atm)2)
+
+#define FD_SHUTDOWN_BIT ((gpr_atm)1)
+
+void grpc_lfev_init(gpr_atm *state) {
+  gpr_atm_no_barrier_store(state, CLOSURE_NOT_READY);
+}
+
+void grpc_lfev_destroy(gpr_atm *state) {
+  gpr_atm curr = gpr_atm_no_barrier_load(state);
+  if (curr & FD_SHUTDOWN_BIT) {
+    GRPC_ERROR_UNREF((grpc_error *)(curr & ~FD_SHUTDOWN_BIT));
+  } else {
+    GPR_ASSERT(curr == CLOSURE_NOT_READY || curr == CLOSURE_READY);
+  }
+}
+
+bool grpc_lfev_is_shutdown(gpr_atm *state) {
+  gpr_atm curr = gpr_atm_no_barrier_load(state);
+  return (curr & FD_SHUTDOWN_BIT) != 0;
+}
+
+void grpc_lfev_notify_on(grpc_exec_ctx *exec_ctx, gpr_atm *state,
+                         grpc_closure *closure) {
+  while (true) {
+    gpr_atm curr = gpr_atm_no_barrier_load(state);
+    switch (curr) {
+      case CLOSURE_NOT_READY: {
+        /* CLOSURE_NOT_READY -> <closure>.
+
+           We're guaranteed by API that there's an acquire barrier before here,
+           so there's no need to double-dip and this can be a release-only.
+
+           The release itself pairs with the acquire half of a set_ready full
+           barrier. */
+        if (gpr_atm_rel_cas(state, CLOSURE_NOT_READY, (gpr_atm)closure)) {
+          return; /* Successful. Return */
+        }
+
+        break; /* retry */
+      }
+
+      case CLOSURE_READY: {
+        /* Change the state to CLOSURE_NOT_READY. Schedule the closure if
+           successful. If not, the state most likely transitioned to shutdown.
+           We should retry.
+
+           This can be a no-barrier cas since the state is being transitioned to
+           CLOSURE_NOT_READY; set_ready and set_shutdown do not schedule any
+           closure when transitioning out of CLOSURE_NO_READY state (i.e there
+           is no other code that needs to 'happen-after' this) */
+        if (gpr_atm_no_barrier_cas(state, CLOSURE_READY, CLOSURE_NOT_READY)) {
+          grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE);
+          return; /* Successful. Return */
+        }
+
+        break; /* retry */
+      }
+
+      default: {
+        /* 'curr' is either a closure or the fd is shutdown(in which case 'curr'
+           contains a pointer to the shutdown-error). If the fd is shutdown,
+           schedule the closure with the shutdown error */
+        if ((curr & FD_SHUTDOWN_BIT) > 0) {
+          grpc_error *shutdown_err = (grpc_error *)(curr & ~FD_SHUTDOWN_BIT);
+          grpc_closure_sched(exec_ctx, closure,
+                             GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                                 "FD Shutdown", &shutdown_err, 1));
+          return;
+        }
+
+        /* There is already a closure!. This indicates a bug in the code */
+        gpr_log(GPR_ERROR,
+                "notify_on called with a previous callback still pending");
+        abort();
+      }
+    }
+  }
+
+  GPR_UNREACHABLE_CODE(return );
+}
+
+bool grpc_lfev_set_shutdown(grpc_exec_ctx *exec_ctx, gpr_atm *state,
+                            grpc_error *shutdown_err) {
+  gpr_atm new_state = (gpr_atm)shutdown_err | FD_SHUTDOWN_BIT;
+
+  while (true) {
+    gpr_atm curr = gpr_atm_no_barrier_load(state);
+    switch (curr) {
+      case CLOSURE_READY:
+      case CLOSURE_NOT_READY:
+        /* Need a full barrier here so that the initial load in notify_on
+           doesn't need a barrier */
+        if (gpr_atm_full_cas(state, curr, new_state)) {
+          return true; /* early out */
+        }
+        break; /* retry */
+
+      default: {
+        /* 'curr' is either a closure or the fd is already shutdown */
+
+        /* If fd is already shutdown, we are done */
+        if ((curr & FD_SHUTDOWN_BIT) > 0) {
+          GRPC_ERROR_UNREF(shutdown_err);
+          return false;
+        }
+
+        /* Fd is not shutdown. Schedule the closure and move the state to
+           shutdown state.
+           Needs an acquire to pair with setting the closure (and get a
+           happens-after on that edge), and a release to pair with anything
+           loading the shutdown state. */
+        if (gpr_atm_full_cas(state, curr, new_state)) {
+          grpc_closure_sched(exec_ctx, (grpc_closure *)curr,
+                             GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                                 "FD Shutdown", &shutdown_err, 1));
+          return true;
+        }
+
+        /* 'curr' was a closure but now changed to a different state. We will
+          have to retry */
+        break;
+      }
+    }
+  }
+
+  GPR_UNREACHABLE_CODE(return false);
+}
+
+void grpc_lfev_set_ready(grpc_exec_ctx *exec_ctx, gpr_atm *state) {
+  while (true) {
+    gpr_atm curr = gpr_atm_no_barrier_load(state);
+
+    switch (curr) {
+      case CLOSURE_READY: {
+        /* Already ready. We are done here */
+        return;
+      }
+
+      case CLOSURE_NOT_READY: {
+        /* No barrier required as we're transitioning to a state that does not
+           involve a closure */
+        if (gpr_atm_no_barrier_cas(state, CLOSURE_NOT_READY, CLOSURE_READY)) {
+          return; /* early out */
+        }
+        break; /* retry */
+      }
+
+      default: {
+        /* 'curr' is either a closure or the fd is shutdown */
+        if ((curr & FD_SHUTDOWN_BIT) > 0) {
+          /* The fd is shutdown. Do nothing */
+          return;
+        }
+        /* Full cas: acquire pairs with this cas' release in the event of a
+           spurious set_ready; release pairs with this or the acquire in
+           notify_on (or set_shutdown) */
+        else if (gpr_atm_full_cas(state, curr, CLOSURE_NOT_READY)) {
+          grpc_closure_sched(exec_ctx, (grpc_closure *)curr, GRPC_ERROR_NONE);
+          return;
+        }
+        /* else the state changed again (only possible by either a racing
+           set_ready or set_shutdown functions. In both these cases, the closure
+           would have been scheduled for execution. So we are done here */
+        return;
+      }
+    }
+  }
+}
diff --git a/src/core/lib/iomgr/lockfree_event.h b/src/core/lib/iomgr/lockfree_event.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d9119204cab9da541795dd1d44590aa6aab6ea3
--- /dev/null
+++ b/src/core/lib/iomgr/lockfree_event.h
@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright 2017, 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_CORE_LIB_IOMGR_LOCKFREE_EVENT_H
+#define GRPC_CORE_LIB_IOMGR_LOCKFREE_EVENT_H
+
+/* Lock free event notification for file descriptors */
+
+#include <grpc/support/atm.h>
+
+#include "src/core/lib/iomgr/exec_ctx.h"
+
+void grpc_lfev_init(gpr_atm *state);
+void grpc_lfev_destroy(gpr_atm *state);
+bool grpc_lfev_is_shutdown(gpr_atm *state);
+
+void grpc_lfev_notify_on(grpc_exec_ctx *exec_ctx, gpr_atm *state,
+                         grpc_closure *closure);
+/* Returns true on first successful shutdown */
+bool grpc_lfev_set_shutdown(grpc_exec_ctx *exec_ctx, gpr_atm *state,
+                            grpc_error *shutdown_err);
+void grpc_lfev_set_ready(grpc_exec_ctx *exec_ctx, gpr_atm *state);
+
+#endif /* GRPC_CORE_LIB_IOMGR_LOCKFREE_EVENT_H */
diff --git a/src/core/lib/iomgr/pollset.h b/src/core/lib/iomgr/pollset.h
index e19ce697b8d3edba687fe404195dff68c9ee5692..9bf3cdac89e2a4152964a904886f5aabdebdb514 100644
--- a/src/core/lib/iomgr/pollset.h
+++ b/src/core/lib/iomgr/pollset.h
@@ -75,6 +75,10 @@ void grpc_pollset_destroy(grpc_pollset *pollset);
    and it is guaranteed that it will not be released by grpc_pollset_work
    AFTER worker has been destroyed.
 
+   It's legal for worker to be NULL: in that case, this specific thread can not
+   be directly woken with a kick, but maybe be indirectly (with a kick against
+   the pollset as a whole).
+
    Tries not to block past deadline.
    May call grpc_closure_list_run on grpc_closure_list, without holding the
    pollset
diff --git a/src/core/lib/iomgr/pollset_uv.c b/src/core/lib/iomgr/pollset_uv.c
index af33949c698bd33af5104b79ba3e88444716c816..a2f81bcd78d6354c754088972c095187f9f2bce6 100644
--- a/src/core/lib/iomgr/pollset_uv.c
+++ b/src/core/lib/iomgr/pollset_uv.c
@@ -39,6 +39,7 @@
 
 #include <string.h>
 
+#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 
@@ -61,25 +62,30 @@ gpr_mu grpc_polling_mu;
    immediately in the next loop iteration.
    Note: In the future, if there is a bug that involves missing wakeups in the
    future, try adding a uv_async_t to kick the loop differently */
-uv_timer_t dummy_uv_handle;
+uv_timer_t *dummy_uv_handle;
 
 size_t grpc_pollset_size() { return sizeof(grpc_pollset); }
 
 void dummy_timer_cb(uv_timer_t *handle) {}
 
+void dummy_handle_close_cb(uv_handle_t *handle) { gpr_free(handle); }
+
 void grpc_pollset_global_init(void) {
   gpr_mu_init(&grpc_polling_mu);
-  uv_timer_init(uv_default_loop(), &dummy_uv_handle);
+  dummy_uv_handle = gpr_malloc(sizeof(uv_timer_t));
+  uv_timer_init(uv_default_loop(), dummy_uv_handle);
   grpc_pollset_work_run_loop = 1;
 }
 
-static void timer_close_cb(uv_handle_t *handle) { handle->data = (void *)1; }
-
 void grpc_pollset_global_shutdown(void) {
   gpr_mu_destroy(&grpc_polling_mu);
-  uv_close((uv_handle_t *)&dummy_uv_handle, timer_close_cb);
+  uv_close((uv_handle_t *)dummy_uv_handle, dummy_handle_close_cb);
 }
 
+static void timer_run_cb(uv_timer_t *timer) {}
+
+static void timer_close_cb(uv_handle_t *handle) { handle->data = (void *)1; }
+
 void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
   *mu = &grpc_polling_mu;
   uv_timer_init(uv_default_loop(), &pollset->timer);
@@ -95,7 +101,7 @@ void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
     uv_run(uv_default_loop(), UV_RUN_NOWAIT);
   } else {
     // kick the loop once
-    uv_timer_start(&dummy_uv_handle, dummy_timer_cb, 0, 0);
+    uv_timer_start(dummy_uv_handle, dummy_timer_cb, 0, 0);
   }
   grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE);
 }
@@ -111,8 +117,6 @@ void grpc_pollset_destroy(grpc_pollset *pollset) {
   }
 }
 
-static void timer_run_cb(uv_timer_t *timer) {}
-
 grpc_error *grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
                               grpc_pollset_worker **worker_hdl,
                               gpr_timespec now, gpr_timespec deadline) {
@@ -145,7 +149,7 @@ grpc_error *grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
 
 grpc_error *grpc_pollset_kick(grpc_pollset *pollset,
                               grpc_pollset_worker *specific_worker) {
-  uv_timer_start(&dummy_uv_handle, dummy_timer_cb, 0, 0);
+  uv_timer_start(dummy_uv_handle, dummy_timer_cb, 0, 0);
   return GRPC_ERROR_NONE;
 }
 
diff --git a/src/core/lib/iomgr/pollset_windows.c b/src/core/lib/iomgr/pollset_windows.c
index 17043c1ea1ada25f21946d249f1721bd26a1cb41..04c6b7174759d10821a4ed510c185a8b80259a84 100644
--- a/src/core/lib/iomgr/pollset_windows.c
+++ b/src/core/lib/iomgr/pollset_windows.c
@@ -120,7 +120,7 @@ grpc_error *grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
                               grpc_pollset_worker **worker_hdl,
                               gpr_timespec now, gpr_timespec deadline) {
   grpc_pollset_worker worker;
-  *worker_hdl = &worker;
+  if (worker_hdl) *worker_hdl = &worker;
 
   int added_worker = 0;
   worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].next =
@@ -185,7 +185,7 @@ done:
     remove_worker(&worker, GRPC_POLLSET_WORKER_LINK_POLLSET);
   }
   gpr_cv_destroy(&worker.cv);
-  *worker_hdl = NULL;
+  if (worker_hdl) *worker_hdl = NULL;
   return GRPC_ERROR_NONE;
 }
 
diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h
index f1897bb91f2fd8ad1efb29eef2d976e04a3e42ca..2a553f41149088e644db7b0da7478db97d5111de 100644
--- a/src/core/lib/iomgr/port.h
+++ b/src/core/lib/iomgr/port.h
@@ -39,6 +39,7 @@
 #if defined(GRPC_UV)
 // Do nothing
 #elif defined(GPR_MANYLINUX1)
+#define GRPC_HAVE_IFADDRS 1
 #define GRPC_HAVE_IPV6_RECVPKTINFO 1
 #define GRPC_HAVE_IP_PKTINFO 1
 #define GRPC_HAVE_MSG_NOSIGNAL 1
@@ -65,6 +66,7 @@
 #define GRPC_POSIX_WAKEUP_FD 1
 #define GRPC_TIMER_USE_GENERIC 1
 #elif defined(GPR_LINUX)
+#define GRPC_HAVE_IFADDRS 1
 #define GRPC_HAVE_IPV6_RECVPKTINFO 1
 #define GRPC_HAVE_IP_PKTINFO 1
 #define GRPC_HAVE_MSG_NOSIGNAL 1
@@ -83,6 +85,11 @@
 #define GRPC_LINUX_SOCKETUTILS 1
 #endif
 #endif
+#ifndef __GLIBC__
+#define GRPC_LINUX_EPOLL 1
+#define GRPC_LINUX_EVENTFD 1
+#define GRPC_MSG_IOVLEN_TYPE int
+#endif
 #ifndef GRPC_LINUX_EVENTFD
 #define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1
 #endif
@@ -90,6 +97,7 @@
 #define GRPC_POSIX_SOCKETUTILS
 #endif
 #elif defined(GPR_APPLE)
+#define GRPC_HAVE_IFADDRS 1
 #define GRPC_HAVE_SO_NOSIGPIPE 1
 #define GRPC_HAVE_UNIX_SOCKET 1
 #define GRPC_MSG_IOVLEN_TYPE int
@@ -100,6 +108,7 @@
 #define GRPC_POSIX_WAKEUP_FD 1
 #define GRPC_TIMER_USE_GENERIC 1
 #elif defined(GPR_FREEBSD)
+#define GRPC_HAVE_IFADDRS 1
 #define GRPC_HAVE_IPV6_RECVPKTINFO 1
 #define GRPC_HAVE_SO_NOSIGPIPE 1
 #define GRPC_HAVE_UNIX_SOCKET 1
diff --git a/src/core/lib/iomgr/resolve_address_posix.c b/src/core/lib/iomgr/resolve_address_posix.c
index 50e470d14916a23d5e2b5ac2f7c16d8b74c78a4b..d0ede0f2d5e80d04d84aeaf7b6436c62dd3020ce 100644
--- a/src/core/lib/iomgr/resolve_address_posix.c
+++ b/src/core/lib/iomgr/resolve_address_posix.c
@@ -73,14 +73,16 @@ static grpc_error *blocking_resolve_address_impl(
   /* parse name, splitting it into host and port parts */
   gpr_split_host_port(name, &host, &port);
   if (host == NULL) {
-    err = grpc_error_set_str(GRPC_ERROR_CREATE("unparseable host:port"),
-                             GRPC_ERROR_STR_TARGET_ADDRESS, name);
+    err = grpc_error_set_str(
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("unparseable host:port"),
+        GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
     goto done;
   }
   if (port == NULL) {
     if (default_port == NULL) {
-      err = grpc_error_set_str(GRPC_ERROR_CREATE("no port in name"),
-                               GRPC_ERROR_STR_TARGET_ADDRESS, name);
+      err = grpc_error_set_str(
+          GRPC_ERROR_CREATE_FROM_STATIC_STRING("no port in name"),
+          GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
       goto done;
     }
     port = gpr_strdup(default_port);
@@ -112,11 +114,15 @@ static grpc_error *blocking_resolve_address_impl(
   if (s != 0) {
     err = grpc_error_set_str(
         grpc_error_set_str(
-            grpc_error_set_str(grpc_error_set_int(GRPC_ERROR_CREATE("OS Error"),
-                                                  GRPC_ERROR_INT_ERRNO, s),
-                               GRPC_ERROR_STR_OS_ERROR, gai_strerror(s)),
-            GRPC_ERROR_STR_SYSCALL, "getaddrinfo"),
-        GRPC_ERROR_STR_TARGET_ADDRESS, name);
+            grpc_error_set_str(
+                grpc_error_set_int(
+                    GRPC_ERROR_CREATE_FROM_STATIC_STRING("OS Error"),
+                    GRPC_ERROR_INT_ERRNO, s),
+                GRPC_ERROR_STR_OS_ERROR,
+                grpc_slice_from_static_string(gai_strerror(s))),
+            GRPC_ERROR_STR_SYSCALL,
+            grpc_slice_from_static_string("getaddrinfo")),
+        GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
     goto done;
   }
 
diff --git a/src/core/lib/iomgr/resolve_address_uv.c b/src/core/lib/iomgr/resolve_address_uv.c
index 79ff91073899e47b6c47afb50fb322780c5f636c..6b468764fcc9813c74ff9c364afe2f0f949acab5 100644
--- a/src/core/lib/iomgr/resolve_address_uv.c
+++ b/src/core/lib/iomgr/resolve_address_uv.c
@@ -40,6 +40,7 @@
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
+#include <grpc/support/useful.h>
 
 #include "src/core/lib/iomgr/closure.h"
 #include "src/core/lib/iomgr/error.h"
@@ -54,8 +55,37 @@ typedef struct request {
   grpc_closure *on_done;
   grpc_resolved_addresses **addresses;
   struct addrinfo *hints;
+  char *host;
+  char *port;
 } request;
 
+static int retry_named_port_failure(int status, request *r,
+                                    uv_getaddrinfo_cb getaddrinfo_cb) {
+  if (status != 0) {
+    // This loop is copied from resolve_address_posix.c
+    char *svc[][2] = {{"http", "80"}, {"https", "443"}};
+    for (size_t i = 0; i < GPR_ARRAY_SIZE(svc); i++) {
+      if (strcmp(r->port, svc[i][0]) == 0) {
+        int retry_status;
+        uv_getaddrinfo_t *req = gpr_malloc(sizeof(uv_getaddrinfo_t));
+        req->data = r;
+        r->port = svc[i][1];
+        retry_status = uv_getaddrinfo(uv_default_loop(), req, getaddrinfo_cb,
+                                      r->host, r->port, r->hints);
+        if (retry_status < 0 || getaddrinfo_cb == NULL) {
+          // The callback will not be called
+          gpr_free(req);
+        }
+        return retry_status;
+      }
+    }
+  }
+  /* If this function calls uv_getaddrinfo, it will return that function's
+     return value. That function only returns numbers <=0, so we can safely
+     return 1 to indicate that we never retried */
+  return 1;
+}
+
 static grpc_error *handle_addrinfo_result(int status, struct addrinfo *result,
                                           grpc_resolved_addresses **addresses) {
   struct addrinfo *resp;
@@ -63,9 +93,10 @@ static grpc_error *handle_addrinfo_result(int status, struct addrinfo *result,
   if (status != 0) {
     grpc_error *error;
     *addresses = NULL;
-    error = GRPC_ERROR_CREATE("getaddrinfo failed");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("getaddrinfo failed");
     error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, uv_strerror(status));
+        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                           grpc_slice_from_static_string(uv_strerror(status)));
     return error;
   }
   (*addresses) = gpr_malloc(sizeof(grpc_resolved_addresses));
@@ -97,13 +128,21 @@ static void getaddrinfo_callback(uv_getaddrinfo_t *req, int status,
   request *r = (request *)req->data;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_error *error;
+  int retry_status;
+
+  gpr_free(req);
+  retry_status = retry_named_port_failure(status, r, getaddrinfo_callback);
+  if (retry_status == 0) {
+    // The request is being retried. Nothing should be done here
+    return;
+  }
+  /* Either no retry was attempted, or the retry failed. Either way, the
+     original error probably has more interesting information */
   error = handle_addrinfo_result(status, res, r->addresses);
   grpc_closure_sched(&exec_ctx, r->on_done, error);
   grpc_exec_ctx_finish(&exec_ctx);
-
   gpr_free(r->hints);
   gpr_free(r);
-  gpr_free(req);
   uv_freeaddrinfo(res);
 }
 
@@ -116,7 +155,7 @@ static grpc_error *try_split_host_port(const char *name,
   if (*host == NULL) {
     char *msg;
     gpr_asprintf(&msg, "unparseable host:port: '%s'", name);
-    error = GRPC_ERROR_CREATE(msg);
+    error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return error;
   }
@@ -125,7 +164,7 @@ static grpc_error *try_split_host_port(const char *name,
     if (default_port == NULL) {
       char *msg;
       gpr_asprintf(&msg, "no port in name '%s'", name);
-      error = GRPC_ERROR_CREATE(msg);
+      error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
       gpr_free(msg);
       return error;
     }
@@ -143,6 +182,7 @@ static grpc_error *blocking_resolve_address_impl(
   uv_getaddrinfo_t req;
   int s;
   grpc_error *err;
+  int retry_status;
 
   req.addrinfo = NULL;
 
@@ -158,6 +198,12 @@ static grpc_error *blocking_resolve_address_impl(
   hints.ai_flags = AI_PASSIVE;     /* for wildcard IP address */
 
   s = uv_getaddrinfo(uv_default_loop(), &req, NULL, host, port, &hints);
+  request r = {
+      .addresses = addresses, .hints = &hints, .host = host, .port = port};
+  retry_status = retry_named_port_failure(s, &r, NULL);
+  if (retry_status <= 0) {
+    s = retry_status;
+  }
   err = handle_addrinfo_result(s, req.addrinfo, addresses);
 
 done:
@@ -200,6 +246,8 @@ static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
   r = gpr_malloc(sizeof(request));
   r->on_done = on_done;
   r->addresses = addrs;
+  r->host = host;
+  r->port = port;
   req = gpr_malloc(sizeof(uv_getaddrinfo_t));
   req->data = r;
 
@@ -216,12 +264,15 @@ static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
 
   if (s != 0) {
     *addrs = NULL;
-    err = GRPC_ERROR_CREATE("getaddrinfo failed");
-    err = grpc_error_set_str(err, GRPC_ERROR_STR_OS_ERROR, uv_strerror(s));
+    err = GRPC_ERROR_CREATE_FROM_STATIC_STRING("getaddrinfo failed");
+    err = grpc_error_set_str(err, GRPC_ERROR_STR_OS_ERROR,
+                             grpc_slice_from_static_string(uv_strerror(s)));
     grpc_closure_sched(exec_ctx, on_done, err);
     gpr_free(r);
     gpr_free(req);
     gpr_free(hints);
+    gpr_free(host);
+    gpr_free(port);
   }
 }
 
diff --git a/src/core/lib/iomgr/resolve_address_windows.c b/src/core/lib/iomgr/resolve_address_windows.c
index 2439ce3cb79964eeee7ecf8667f7abeff7894814..22eca1fd3b8e10b019cbdac5a383e0efdb23f3c0 100644
--- a/src/core/lib/iomgr/resolve_address_windows.c
+++ b/src/core/lib/iomgr/resolve_address_windows.c
@@ -78,7 +78,7 @@ static grpc_error *blocking_resolve_address_impl(
   if (host == NULL) {
     char *msg;
     gpr_asprintf(&msg, "unparseable host:port: '%s'", name);
-    error = GRPC_ERROR_CREATE(msg);
+    error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     goto done;
   }
@@ -86,7 +86,7 @@ static grpc_error *blocking_resolve_address_impl(
     if (default_port == NULL) {
       char *msg;
       gpr_asprintf(&msg, "no port in name '%s'", name);
-      error = GRPC_ERROR_CREATE(msg);
+      error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
       gpr_free(msg);
       goto done;
     }
diff --git a/src/core/lib/iomgr/resource_quota.c b/src/core/lib/iomgr/resource_quota.c
index 511ffdcdf13bc5c7736c53a3dd30aeb338c90a59..c3ee8786517218549abc4a0b907a30a1c8ac6912 100644
--- a/src/core/lib/iomgr/resource_quota.c
+++ b/src/core/lib/iomgr/resource_quota.c
@@ -142,6 +142,8 @@ struct grpc_resource_quota {
   /* Amount of free memory in the resource quota */
   int64_t free_pool;
 
+  gpr_atm last_size;
+
   /* Has rq_step been scheduled to occur? */
   bool step_scheduled;
   /* Are we currently reclaiming memory */
@@ -279,11 +281,17 @@ static void rq_step_sched(grpc_exec_ctx *exec_ctx,
 /* update the atomically available resource estimate - use no barriers since
    timeliness of delivery really doesn't matter much */
 static void rq_update_estimate(grpc_resource_quota *resource_quota) {
+  gpr_atm memory_usage_estimation = MEMORY_USAGE_ESTIMATION_MAX;
+  if (resource_quota->size != 0) {
+    memory_usage_estimation =
+        GPR_CLAMP((gpr_atm)((1.0 -
+                             ((double)resource_quota->free_pool) /
+                                 ((double)resource_quota->size)) *
+                            MEMORY_USAGE_ESTIMATION_MAX),
+                  0, MEMORY_USAGE_ESTIMATION_MAX);
+  }
   gpr_atm_no_barrier_store(&resource_quota->memory_usage_estimation,
-                           (gpr_atm)((1.0 -
-                                      ((double)resource_quota->free_pool) /
-                                          ((double)resource_quota->size)) *
-                                     MEMORY_USAGE_ESTIMATION_MAX));
+                           memory_usage_estimation);
 }
 
 /* returns true if all allocations are completed */
@@ -575,6 +583,7 @@ grpc_resource_quota *grpc_resource_quota_create(const char *name) {
   resource_quota->combiner = grpc_combiner_create(NULL);
   resource_quota->free_pool = INT64_MAX;
   resource_quota->size = INT64_MAX;
+  gpr_atm_no_barrier_store(&resource_quota->last_size, GPR_ATM_MAX);
   resource_quota->step_scheduled = false;
   resource_quota->reclaiming = false;
   gpr_atm_no_barrier_store(&resource_quota->memory_usage_estimation, 0);
@@ -637,11 +646,17 @@ void grpc_resource_quota_resize(grpc_resource_quota *resource_quota,
   rq_resize_args *a = gpr_malloc(sizeof(*a));
   a->resource_quota = grpc_resource_quota_ref_internal(resource_quota);
   a->size = (int64_t)size;
+  gpr_atm_no_barrier_store(&resource_quota->last_size,
+                           (gpr_atm)GPR_MIN((size_t)GPR_ATM_MAX, size));
   grpc_closure_init(&a->closure, rq_resize, a, grpc_schedule_on_exec_ctx);
   grpc_closure_sched(&exec_ctx, &a->closure, GRPC_ERROR_NONE);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
+size_t grpc_resource_quota_peek_size(grpc_resource_quota *resource_quota) {
+  return (size_t)gpr_atm_no_barrier_load(&resource_quota->last_size);
+}
+
 /*******************************************************************************
  * grpc_resource_user channel args api
  */
diff --git a/src/core/lib/iomgr/resource_quota.h b/src/core/lib/iomgr/resource_quota.h
index b9f62cbf83f011d03801ba9416260f65f9a05108..6f99be0d512e48cdcbdbe5244bba221f79db30cd 100644
--- a/src/core/lib/iomgr/resource_quota.h
+++ b/src/core/lib/iomgr/resource_quota.h
@@ -90,6 +90,8 @@ grpc_resource_quota *grpc_resource_quota_from_channel_args(
 double grpc_resource_quota_get_memory_pressure(
     grpc_resource_quota *resource_quota);
 
+size_t grpc_resource_quota_peek_size(grpc_resource_quota *resource_quota);
+
 typedef struct grpc_resource_user grpc_resource_user;
 
 grpc_resource_user *grpc_resource_user_create(
diff --git a/src/core/lib/iomgr/sockaddr_utils.c b/src/core/lib/iomgr/sockaddr_utils.c
index ffa62cb53c096fc26169ad8fb425825639d776e7..a6a4cac3e29ffa54a7613ca184e3840595843fcc 100644
--- a/src/core/lib/iomgr/sockaddr_utils.c
+++ b/src/core/lib/iomgr/sockaddr_utils.c
@@ -55,7 +55,9 @@ int grpc_sockaddr_is_v4mapped(const grpc_resolved_address *resolved_addr,
   GPR_ASSERT(resolved_addr != resolved_addr4_out);
   const struct sockaddr *addr = (const struct sockaddr *)resolved_addr->addr;
   struct sockaddr_in *addr4_out =
-      (struct sockaddr_in *)resolved_addr4_out->addr;
+      resolved_addr4_out == NULL
+          ? NULL
+          : (struct sockaddr_in *)resolved_addr4_out->addr;
   if (addr->sa_family == AF_INET6) {
     const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
     if (memcmp(addr6->sin6_addr.s6_addr, kV4MappedPrefix,
@@ -162,6 +164,7 @@ int grpc_sockaddr_to_string(char **out,
   char ntop_buf[INET6_ADDRSTRLEN];
   const void *ip = NULL;
   int port;
+  uint32_t sin6_scope_id = 0;
   int ret;
 
   *out = NULL;
@@ -177,10 +180,19 @@ int grpc_sockaddr_to_string(char **out,
     const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
     ip = &addr6->sin6_addr;
     port = ntohs(addr6->sin6_port);
+    sin6_scope_id = addr6->sin6_scope_id;
   }
   if (ip != NULL &&
       grpc_inet_ntop(addr->sa_family, ip, ntop_buf, sizeof(ntop_buf)) != NULL) {
-    ret = gpr_join_host_port(out, ntop_buf, port);
+    if (sin6_scope_id != 0) {
+      char *host_with_scope;
+      /* Enclose sin6_scope_id with the format defined in RFC 6784 section 2. */
+      gpr_asprintf(&host_with_scope, "%s%%25%" PRIu32, ntop_buf, sin6_scope_id);
+      ret = gpr_join_host_port(out, host_with_scope, port);
+      gpr_free(host_with_scope);
+    } else {
+      ret = gpr_join_host_port(out, ntop_buf, port);
+    }
   } else {
     ret = gpr_asprintf(out, "(sockaddr family=%d)", addr->sa_family);
   }
diff --git a/src/core/lib/iomgr/sockaddr_utils.h b/src/core/lib/iomgr/sockaddr_utils.h
index 2b22f11b49dcf9c9fd6e063063307835ff1314d0..be3ea2038f140610d79e028914149bb95ea6a310 100644
--- a/src/core/lib/iomgr/sockaddr_utils.h
+++ b/src/core/lib/iomgr/sockaddr_utils.h
@@ -50,7 +50,7 @@ int grpc_sockaddr_to_v4mapped(const grpc_resolved_address *addr,
                               grpc_resolved_address *addr6_out);
 
 /* If addr is ::, 0.0.0.0, or ::ffff:0.0.0.0, writes the port number to
-   *port_out (if not NULL) and returns true, otherwise returns false. */
+ *port_out (if not NULL) and returns true, otherwise returns false. */
 int grpc_sockaddr_is_wildcard(const grpc_resolved_address *addr, int *port_out);
 
 /* Writes 0.0.0.0:port and [::]:port to separate sockaddrs. */
diff --git a/src/core/lib/iomgr/socket_factory_posix.c b/src/core/lib/iomgr/socket_factory_posix.c
new file mode 100644
index 0000000000000000000000000000000000000000..1050a14c4698b7f4650d70e0c51a568f6c50b479
--- /dev/null
+++ b/src/core/lib/iomgr/socket_factory_posix.c
@@ -0,0 +1,110 @@
+/*
+ *
+ * Copyright 2017, 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/lib/iomgr/port.h"
+
+#ifdef GRPC_POSIX_SOCKET
+
+#include "src/core/lib/iomgr/socket_factory_posix.h"
+
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/useful.h>
+
+void grpc_socket_factory_init(grpc_socket_factory *factory,
+                              const grpc_socket_factory_vtable *vtable) {
+  factory->vtable = vtable;
+  gpr_ref_init(&factory->refcount, 1);
+}
+
+int grpc_socket_factory_socket(grpc_socket_factory *factory, int domain,
+                               int type, int protocol) {
+  return factory->vtable->socket(factory, domain, type, protocol);
+}
+
+int grpc_socket_factory_bind(grpc_socket_factory *factory, int sockfd,
+                             const grpc_resolved_address *addr) {
+  return factory->vtable->bind(factory, sockfd, addr);
+}
+
+int grpc_socket_factory_compare(grpc_socket_factory *a,
+                                grpc_socket_factory *b) {
+  int c = GPR_ICMP(a, b);
+  if (c != 0) {
+    grpc_socket_factory *sma = a;
+    grpc_socket_factory *smb = b;
+    c = GPR_ICMP(sma->vtable, smb->vtable);
+    if (c == 0) {
+      c = sma->vtable->compare(sma, smb);
+    }
+  }
+  return c;
+}
+
+grpc_socket_factory *grpc_socket_factory_ref(grpc_socket_factory *factory) {
+  gpr_ref(&factory->refcount);
+  return factory;
+}
+
+void grpc_socket_factory_unref(grpc_socket_factory *factory) {
+  if (gpr_unref(&factory->refcount)) {
+    factory->vtable->destroy(factory);
+  }
+}
+
+static void *socket_factory_arg_copy(void *p) {
+  return grpc_socket_factory_ref(p);
+}
+
+static void socket_factory_arg_destroy(grpc_exec_ctx *exec_ctx, void *p) {
+  grpc_socket_factory_unref(p);
+}
+
+static int socket_factory_cmp(void *a, void *b) {
+  return grpc_socket_factory_compare((grpc_socket_factory *)a,
+                                     (grpc_socket_factory *)b);
+}
+
+static const grpc_arg_pointer_vtable socket_factory_arg_vtable = {
+    socket_factory_arg_copy, socket_factory_arg_destroy, socket_factory_cmp};
+
+grpc_arg grpc_socket_factory_to_arg(grpc_socket_factory *factory) {
+  grpc_arg arg;
+  arg.type = GRPC_ARG_POINTER;
+  arg.key = GRPC_ARG_SOCKET_FACTORY;
+  arg.value.pointer.vtable = &socket_factory_arg_vtable;
+  arg.value.pointer.p = factory;
+  return arg;
+}
+
+#endif
diff --git a/src/core/lib/iomgr/socket_factory_posix.h b/src/core/lib/iomgr/socket_factory_posix.h
new file mode 100644
index 0000000000000000000000000000000000000000..2c63299030caf36ab5821374fcc9573ae9d3d242
--- /dev/null
+++ b/src/core/lib/iomgr/socket_factory_posix.h
@@ -0,0 +1,90 @@
+/*
+ *
+ * Copyright 2017, 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_CORE_LIB_IOMGR_SOCKET_FACTORY_POSIX_H
+#define GRPC_CORE_LIB_IOMGR_SOCKET_FACTORY_POSIX_H
+
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/support/sync.h>
+#include "src/core/lib/iomgr/resolve_address.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** The virtual table of grpc_socket_factory */
+typedef struct {
+  /** Replacement for socket(2) */
+  int (*socket)(grpc_socket_factory *factory, int domain, int type,
+                int protocol);
+  /** Replacement for bind(2) */
+  int (*bind)(grpc_socket_factory *factory, int sockfd,
+              const grpc_resolved_address *addr);
+  /** Compare socket factory \a a and \a b */
+  int (*compare)(grpc_socket_factory *a, grpc_socket_factory *b);
+  /** Destroys the socket factory instance */
+  void (*destroy)(grpc_socket_factory *factory);
+} grpc_socket_factory_vtable;
+
+/** The Socket Factory interface allows changes on socket options */
+struct grpc_socket_factory {
+  const grpc_socket_factory_vtable *vtable;
+  gpr_refcount refcount;
+};
+
+/** called by concrete implementations to initialize the base struct */
+void grpc_socket_factory_init(grpc_socket_factory *factory,
+                              const grpc_socket_factory_vtable *vtable);
+
+/** Wrap \a factory as a grpc_arg */
+grpc_arg grpc_socket_factory_to_arg(grpc_socket_factory *factory);
+
+/** Perform the equivalent of a socket(2) operation using \a factory */
+int grpc_socket_factory_socket(grpc_socket_factory *factory, int domain,
+                               int type, int protocol);
+
+/** Perform the equivalent of a bind(2) operation using \a factory */
+int grpc_socket_factory_bind(grpc_socket_factory *factory, int sockfd,
+                             const grpc_resolved_address *addr);
+
+/** Compare if \a a and \a b are the same factory or have same settings */
+int grpc_socket_factory_compare(grpc_socket_factory *a, grpc_socket_factory *b);
+
+grpc_socket_factory *grpc_socket_factory_ref(grpc_socket_factory *factory);
+void grpc_socket_factory_unref(grpc_socket_factory *factory);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_CORE_LIB_IOMGR_SOCKET_FACTORY_POSIX_H */
diff --git a/src/core/lib/iomgr/socket_mutator.h b/src/core/lib/iomgr/socket_mutator.h
index 2f5b6c248e9db3ccc12d43029c80bf8012c1e371..28b1710ec4093e50654c8d7458cbded132959152 100644
--- a/src/core/lib/iomgr/socket_mutator.h
+++ b/src/core/lib/iomgr/socket_mutator.h
@@ -37,6 +37,8 @@
 #include <grpc/impl/codegen/grpc_types.h>
 #include <grpc/support/sync.h>
 
+#include <stdbool.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/src/core/lib/iomgr/socket_utils_common_posix.c b/src/core/lib/iomgr/socket_utils_common_posix.c
index 88e9ade253e9bef1748b7ca630f8c401948c18d6..bbe642d0fb4a439764c5d685701795f01198813b 100644
--- a/src/core/lib/iomgr/socket_utils_common_posix.c
+++ b/src/core/lib/iomgr/socket_utils_common_posix.c
@@ -90,7 +90,7 @@ grpc_error *grpc_set_socket_no_sigpipe_if_possible(int fd) {
     return GRPC_OS_ERROR(errno, "getsockopt(SO_NOSIGPIPE)");
   }
   if ((newval != 0) != (val != 0)) {
-    return GRPC_ERROR_CREATE("Failed to set SO_NOSIGPIPE");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_NOSIGPIPE");
   }
 #endif
   return GRPC_ERROR_NONE;
@@ -164,7 +164,7 @@ grpc_error *grpc_set_socket_reuse_addr(int fd, int reuse) {
     return GRPC_OS_ERROR(errno, "getsockopt(SO_REUSEADDR)");
   }
   if ((newval != 0) != val) {
-    return GRPC_ERROR_CREATE("Failed to set SO_REUSEADDR");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_REUSEADDR");
   }
 
   return GRPC_ERROR_NONE;
@@ -173,7 +173,8 @@ grpc_error *grpc_set_socket_reuse_addr(int fd, int reuse) {
 /* set a socket to reuse old addresses */
 grpc_error *grpc_set_socket_reuse_port(int fd, int reuse) {
 #ifndef SO_REUSEPORT
-  return GRPC_ERROR_CREATE("SO_REUSEPORT unavailable on compiling system");
+  return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+      "SO_REUSEPORT unavailable on compiling system");
 #else
   int val = (reuse != 0);
   int newval;
@@ -185,7 +186,7 @@ grpc_error *grpc_set_socket_reuse_port(int fd, int reuse) {
     return GRPC_OS_ERROR(errno, "getsockopt(SO_REUSEPORT)");
   }
   if ((newval != 0) != val) {
-    return GRPC_ERROR_CREATE("Failed to set SO_REUSEPORT");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_REUSEPORT");
   }
 
   return GRPC_ERROR_NONE;
@@ -204,7 +205,7 @@ grpc_error *grpc_set_socket_low_latency(int fd, int low_latency) {
     return GRPC_OS_ERROR(errno, "getsockopt(TCP_NODELAY)");
   }
   if ((newval != 0) != val) {
-    return GRPC_ERROR_CREATE("Failed to set TCP_NODELAY");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set TCP_NODELAY");
   }
   return GRPC_ERROR_NONE;
 }
@@ -213,7 +214,7 @@ grpc_error *grpc_set_socket_low_latency(int fd, int low_latency) {
 grpc_error *grpc_set_socket_with_mutator(int fd, grpc_socket_mutator *mutator) {
   GPR_ASSERT(mutator);
   if (!grpc_socket_mutator_mutate_fd(mutator, fd)) {
-    return GRPC_ERROR_CREATE("grpc_socket_mutator failed.");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("grpc_socket_mutator failed.");
   }
   return GRPC_ERROR_NONE;
 }
@@ -268,7 +269,8 @@ static grpc_error *error_for_fd(int fd, const grpc_resolved_address *addr) {
   char *addr_str;
   grpc_sockaddr_to_string(&addr_str, addr, 0);
   grpc_error *err = grpc_error_set_str(GRPC_OS_ERROR(errno, "socket"),
-                                       GRPC_ERROR_STR_TARGET_ADDRESS, addr_str);
+                                       GRPC_ERROR_STR_TARGET_ADDRESS,
+                                       grpc_slice_from_copied_string(addr_str));
   gpr_free(addr_str);
   return err;
 }
@@ -276,11 +278,25 @@ static grpc_error *error_for_fd(int fd, const grpc_resolved_address *addr) {
 grpc_error *grpc_create_dualstack_socket(
     const grpc_resolved_address *resolved_addr, int type, int protocol,
     grpc_dualstack_mode *dsmode, int *newfd) {
+  return grpc_create_dualstack_socket_using_factory(NULL, resolved_addr, type,
+                                                    protocol, dsmode, newfd);
+}
+
+static int create_socket(grpc_socket_factory *factory, int domain, int type,
+                         int protocol) {
+  return (factory != NULL)
+             ? grpc_socket_factory_socket(factory, domain, type, protocol)
+             : socket(domain, type, protocol);
+}
+
+grpc_error *grpc_create_dualstack_socket_using_factory(
+    grpc_socket_factory *factory, const grpc_resolved_address *resolved_addr,
+    int type, int protocol, grpc_dualstack_mode *dsmode, int *newfd) {
   const struct sockaddr *addr = (const struct sockaddr *)resolved_addr->addr;
   int family = addr->sa_family;
   if (family == AF_INET6) {
     if (grpc_ipv6_loopback_available()) {
-      *newfd = socket(family, type, protocol);
+      *newfd = create_socket(factory, family, type, protocol);
     } else {
       *newfd = -1;
       errno = EAFNOSUPPORT;
@@ -302,7 +318,7 @@ grpc_error *grpc_create_dualstack_socket(
     family = AF_INET;
   }
   *dsmode = family == AF_INET ? GRPC_DSMODE_IPV4 : GRPC_DSMODE_NONE;
-  *newfd = socket(family, type, protocol);
+  *newfd = create_socket(factory, family, type, protocol);
   return error_for_fd(*newfd, resolved_addr);
 }
 
diff --git a/src/core/lib/iomgr/socket_utils_posix.h b/src/core/lib/iomgr/socket_utils_posix.h
index e84d3781a15f9d193476806f61f568c959870def..2c2fc95ff98460e36a9cd749d067407b7d8b7312 100644
--- a/src/core/lib/iomgr/socket_utils_posix.h
+++ b/src/core/lib/iomgr/socket_utils_posix.h
@@ -41,6 +41,7 @@
 
 #include <grpc/impl/codegen/grpc_types.h>
 #include "src/core/lib/iomgr/error.h"
+#include "src/core/lib/iomgr/socket_factory_posix.h"
 #include "src/core/lib/iomgr/socket_mutator.h"
 
 /* a wrapper for accept or accept4 */
@@ -137,4 +138,10 @@ grpc_error *grpc_create_dualstack_socket(const grpc_resolved_address *addr,
                                          grpc_dualstack_mode *dsmode,
                                          int *newfd);
 
+/* Same as grpc_create_dualstack_socket(), but use the given socket factory (if
+   non-null) to create the socket, rather than calling socket() directly. */
+grpc_error *grpc_create_dualstack_socket_using_factory(
+    grpc_socket_factory *factory, const grpc_resolved_address *addr, int type,
+    int protocol, grpc_dualstack_mode *dsmode, int *newfd);
+
 #endif /* GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_POSIX_H */
diff --git a/src/core/lib/iomgr/tcp_client.h b/src/core/lib/iomgr/tcp_client.h
index 0485661316ad09b45d0c8a8a14c13cd90e047ef8..bc367bdfa5da47ae69cef99001d672d467b6172a 100644
--- a/src/core/lib/iomgr/tcp_client.h
+++ b/src/core/lib/iomgr/tcp_client.h
@@ -40,10 +40,6 @@
 #include "src/core/lib/iomgr/pollset_set.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 
-/* Channel arg (integer) setting how large a slice to try and read from the wire
-   each time recvmsg (or equivalent) is called */
-#define GRPC_ARG_TCP_READ_CHUNK_SIZE "grpc.experimental.tcp_read_chunk_size"
-
 /* Asynchronously connect to an address (specified as (addr, len)), and call
    cb with arg and the completed connection when done (or call cb with arg and
    NULL on failure).
diff --git a/src/core/lib/iomgr/tcp_client_posix.c b/src/core/lib/iomgr/tcp_client_posix.c
index 0144192b71e0045f01c9013e0260f8ac7d3d5ef4..a2692707d9ea5a887244174d4db0fdb4fc971b25 100644
--- a/src/core/lib/iomgr/tcp_client_posix.c
+++ b/src/core/lib/iomgr/tcp_client_posix.c
@@ -121,8 +121,8 @@ static void tc_on_alarm(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
   }
   gpr_mu_lock(&ac->mu);
   if (ac->fd != NULL) {
-    grpc_fd_shutdown(exec_ctx, ac->fd,
-                     GRPC_ERROR_CREATE("connect() timed out"));
+    grpc_fd_shutdown(exec_ctx, ac->fd, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                           "connect() timed out"));
   }
   done = (--ac->refs == 0);
   gpr_mu_unlock(&ac->mu);
@@ -137,29 +137,7 @@ static void tc_on_alarm(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
 grpc_endpoint *grpc_tcp_client_create_from_fd(
     grpc_exec_ctx *exec_ctx, grpc_fd *fd, const grpc_channel_args *channel_args,
     const char *addr_str) {
-  size_t tcp_read_chunk_size = GRPC_TCP_DEFAULT_READ_SLICE_SIZE;
-  grpc_resource_quota *resource_quota = grpc_resource_quota_create(NULL);
-  if (channel_args != NULL) {
-    for (size_t i = 0; i < channel_args->num_args; i++) {
-      if (0 ==
-          strcmp(channel_args->args[i].key, GRPC_ARG_TCP_READ_CHUNK_SIZE)) {
-        grpc_integer_options options = {(int)tcp_read_chunk_size, 1,
-                                        8 * 1024 * 1024};
-        tcp_read_chunk_size = (size_t)grpc_channel_arg_get_integer(
-            &channel_args->args[i], options);
-      } else if (0 ==
-                 strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
-        grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
-        resource_quota = grpc_resource_quota_ref_internal(
-            channel_args->args[i].value.pointer.p);
-      }
-    }
-  }
-
-  grpc_endpoint *ep =
-      grpc_tcp_create(fd, resource_quota, tcp_read_chunk_size, addr_str);
-  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
-  return ep;
+  return grpc_tcp_create(exec_ctx, fd, channel_args, addr_str);
 }
 
 static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
@@ -191,7 +169,8 @@ static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
   gpr_mu_lock(&ac->mu);
   if (error != GRPC_ERROR_NONE) {
     error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, "Timeout occurred");
+        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                           grpc_slice_from_static_string("Timeout occurred"));
     goto finish;
   }
 
@@ -252,12 +231,17 @@ finish:
   gpr_mu_unlock(&ac->mu);
   if (error != GRPC_ERROR_NONE) {
     char *error_descr;
-    gpr_asprintf(&error_descr, "Failed to connect to remote host: %s",
-                 grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION));
-    error = grpc_error_set_str(error, GRPC_ERROR_STR_DESCRIPTION, error_descr);
+    grpc_slice str;
+    bool ret = grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION, &str);
+    GPR_ASSERT(ret);
+    char *desc = grpc_slice_to_c_string(str);
+    gpr_asprintf(&error_descr, "Failed to connect to remote host: %s", desc);
+    error = grpc_error_set_str(error, GRPC_ERROR_STR_DESCRIPTION,
+                               grpc_slice_from_copied_string(error_descr));
     gpr_free(error_descr);
-    error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, ac->addr_str);
+    gpr_free(desc);
+    error = grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS,
+                               grpc_slice_from_copied_string(ac->addr_str));
   }
   if (done) {
     gpr_mu_destroy(&ac->mu);
diff --git a/src/core/lib/iomgr/tcp_client_uv.c b/src/core/lib/iomgr/tcp_client_uv.c
index ae66577cafd23226577a03647fc744037b8c9a78..682c24ed56b820b23f47d95aa68af56b4d375d76 100644
--- a/src/core/lib/iomgr/tcp_client_uv.c
+++ b/src/core/lib/iomgr/tcp_client_uv.c
@@ -76,7 +76,6 @@ static void uv_tc_on_alarm(grpc_exec_ctx *exec_ctx, void *acp,
     const char *str = grpc_error_string(error);
     gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: error=%s",
             connect->addr_name, str);
-    grpc_error_free_string(str);
   }
   if (error == GRPC_ERROR_NONE) {
     /* error == NONE implies that the timer ran out, and wasn't cancelled. If
@@ -101,17 +100,21 @@ static void uv_tc_on_connect(uv_connect_t *req, int status) {
     *connect->endpoint = grpc_tcp_create(
         connect->tcp_handle, connect->resource_quota, connect->addr_name);
   } else {
-    error = GRPC_ERROR_CREATE("Failed to connect to remote host");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Failed to connect to remote host");
     error = grpc_error_set_int(error, GRPC_ERROR_INT_ERRNO, -status);
     error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, uv_strerror(status));
+        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                           grpc_slice_from_static_string(uv_strerror(status)));
     if (status == UV_ECANCELED) {
-      error = grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
-                                 "Timeout occurred");
+      error =
+          grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                             grpc_slice_from_static_string("Timeout occurred"));
       // This should only happen if the handle is already closed
     } else {
-      error = grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
-                                 uv_strerror(status));
+      error = grpc_error_set_str(
+          error, GRPC_ERROR_STR_OS_ERROR,
+          grpc_slice_from_static_string(uv_strerror(status)));
       uv_close((uv_handle_t *)connect->tcp_handle, tcp_close_callback);
     }
   }
diff --git a/src/core/lib/iomgr/tcp_client_windows.c b/src/core/lib/iomgr/tcp_client_windows.c
index c8dc9e64bdbb314841d4bf8fbb6836f849fc9781..d6baca50baf363d367d4c0a975a0560d5d40f11b 100644
--- a/src/core/lib/iomgr/tcp_client_windows.c
+++ b/src/core/lib/iomgr/tcp_client_windows.c
@@ -63,7 +63,7 @@ typedef struct {
   int refs;
   grpc_closure on_connect;
   grpc_endpoint **endpoint;
-  grpc_resource_quota *resource_quota;
+  grpc_channel_args *channel_args;
 } async_connect;
 
 static void async_connect_unlock_and_cleanup(grpc_exec_ctx *exec_ctx,
@@ -72,7 +72,7 @@ static void async_connect_unlock_and_cleanup(grpc_exec_ctx *exec_ctx,
   int done = (--ac->refs == 0);
   gpr_mu_unlock(&ac->mu);
   if (done) {
-    grpc_resource_quota_unref_internal(exec_ctx, ac->resource_quota);
+    grpc_channel_args_destroy(exec_ctx, ac->channel_args);
     gpr_mu_destroy(&ac->mu);
     gpr_free(ac->addr_name);
     gpr_free(ac);
@@ -119,11 +119,12 @@ static void on_connect(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
       if (!wsa_success) {
         error = GRPC_WSA_ERROR(WSAGetLastError(), "ConnectEx");
       } else {
-        *ep = grpc_tcp_create(socket, ac->resource_quota, ac->addr_name);
+        *ep =
+            grpc_tcp_create(exec_ctx, socket, ac->channel_args, ac->addr_name);
         socket = NULL;
       }
     } else {
-      error = GRPC_ERROR_CREATE("socket is null");
+      error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("socket is null");
     }
   }
 
@@ -152,17 +153,6 @@ static void tcp_client_connect_impl(
   grpc_winsocket_callback_info *info;
   grpc_error *error = GRPC_ERROR_NONE;
 
-  grpc_resource_quota *resource_quota = grpc_resource_quota_create(NULL);
-  if (channel_args != NULL) {
-    for (size_t i = 0; i < channel_args->num_args; i++) {
-      if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
-        grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
-        resource_quota = grpc_resource_quota_ref_internal(
-            channel_args->args[i].value.pointer.p);
-      }
-    }
-  }
-
   *endpoint = NULL;
 
   /* Use dualstack sockets where available. */
@@ -225,7 +215,7 @@ static void tcp_client_connect_impl(
   ac->refs = 2;
   ac->addr_name = grpc_sockaddr_to_uri(addr);
   ac->endpoint = endpoint;
-  ac->resource_quota = resource_quota;
+  ac->channel_args = grpc_channel_args_copy(channel_args);
   grpc_closure_init(&ac->on_connect, on_connect, ac, grpc_schedule_on_exec_ctx);
 
   grpc_closure_init(&ac->on_alarm, on_alarm, ac, grpc_schedule_on_exec_ctx);
@@ -238,15 +228,15 @@ failure:
   GPR_ASSERT(error != GRPC_ERROR_NONE);
   char *target_uri = grpc_sockaddr_to_uri(addr);
   grpc_error *final_error = grpc_error_set_str(
-      GRPC_ERROR_CREATE_REFERENCING("Failed to connect", &error, 1),
-      GRPC_ERROR_STR_TARGET_ADDRESS, target_uri);
+      GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Failed to connect",
+                                                       &error, 1),
+      GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(target_uri));
   GRPC_ERROR_UNREF(error);
   if (socket != NULL) {
     grpc_winsocket_destroy(socket);
   } else if (sock != INVALID_SOCKET) {
     closesocket(sock);
   }
-  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
   grpc_closure_sched(exec_ctx, on_done, final_error);
 }
 
diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c
index a4381f8fc969042316b3c1f158b60d71be53a38b..5f4b38de2b9c17e0fb02f320dda5a694df75a190 100644
--- a/src/core/lib/iomgr/tcp_posix.c
+++ b/src/core/lib/iomgr/tcp_posix.c
@@ -52,7 +52,9 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
+#include <grpc/support/useful.h>
 
+#include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/debug/trace.h"
 #include "src/core/lib/iomgr/ev_posix.h"
 #include "src/core/lib/profiling/timers.h"
@@ -80,10 +82,14 @@ typedef struct {
   int fd;
   bool finished_edge;
   msg_iovlen_type iov_size; /* Number of slices to allocate per read attempt */
-  size_t slice_size;
+  double target_length;
+  double bytes_read_this_round;
   gpr_refcount refcount;
   gpr_atm shutdown_count;
 
+  int min_read_chunk_size;
+  int max_read_chunk_size;
+
   /* garbage after the last read */
   grpc_slice_buffer last_read_buffer;
 
@@ -108,10 +114,47 @@ typedef struct {
   grpc_resource_user_slice_allocator slice_allocator;
 } grpc_tcp;
 
+static void add_to_estimate(grpc_tcp *tcp, size_t bytes) {
+  tcp->bytes_read_this_round += (double)bytes;
+}
+
+static void finish_estimate(grpc_tcp *tcp) {
+  /* If we read >80% of the target buffer in one read loop, increase the size
+     of the target buffer to either the amount read, or twice its previous
+     value */
+  if (tcp->bytes_read_this_round > tcp->target_length * 0.8) {
+    tcp->target_length =
+        GPR_MAX(2 * tcp->target_length, tcp->bytes_read_this_round);
+  } else {
+    tcp->target_length =
+        0.99 * tcp->target_length + 0.01 * tcp->bytes_read_this_round;
+  }
+  tcp->bytes_read_this_round = 0;
+}
+
+static size_t get_target_read_size(grpc_tcp *tcp) {
+  grpc_resource_quota *rq = grpc_resource_user_quota(tcp->resource_user);
+  double pressure = grpc_resource_quota_get_memory_pressure(rq);
+  double target =
+      tcp->target_length * (pressure > 0.8 ? (1.0 - pressure) / 0.2 : 1.0);
+  size_t sz = (((size_t)GPR_CLAMP(target, tcp->min_read_chunk_size,
+                                  tcp->max_read_chunk_size)) +
+               255) &
+              ~(size_t)255;
+  /* don't use more than 1/16th of the overall resource quota for a single read
+   * alloc */
+  size_t rqmax = grpc_resource_quota_peek_size(rq);
+  if (sz > rqmax / 16 && rqmax > 1024) {
+    sz = rqmax / 16;
+  }
+  return sz;
+}
+
 static grpc_error *tcp_annotate_error(grpc_error *src_error, grpc_tcp *tcp) {
   return grpc_error_set_str(
       grpc_error_set_int(src_error, GRPC_ERROR_INT_FD, tcp->fd),
-      GRPC_ERROR_STR_TARGET_ADDRESS, tcp->peer_string);
+      GRPC_ERROR_STR_TARGET_ADDRESS,
+      grpc_slice_from_copied_string(tcp->peer_string));
 }
 
 static void tcp_handle_read(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */,
@@ -231,9 +274,7 @@ static void tcp_do_read(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
     /* NB: After calling call_read_cb a parallel call of the read handler may
      * be running. */
     if (errno == EAGAIN) {
-      if (tcp->iov_size > 1) {
-        tcp->iov_size /= 2;
-      }
+      finish_estimate(tcp);
       /* We've consumed the edge, request a new one */
       grpc_fd_notify_on_read(exec_ctx, tcp->em_fd, &tcp->read_closure);
     } else {
@@ -246,18 +287,19 @@ static void tcp_do_read(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
   } else if (read_bytes == 0) {
     /* 0 read size ==> end of stream */
     grpc_slice_buffer_reset_and_unref_internal(exec_ctx, tcp->incoming_buffer);
-    call_read_cb(exec_ctx, tcp,
-                 tcp_annotate_error(GRPC_ERROR_CREATE("Socket closed"), tcp));
+    call_read_cb(
+        exec_ctx, tcp,
+        tcp_annotate_error(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Socket closed"), tcp));
     TCP_UNREF(exec_ctx, tcp, "read");
   } else {
+    add_to_estimate(tcp, (size_t)read_bytes);
     GPR_ASSERT((size_t)read_bytes <= tcp->incoming_buffer->length);
     if ((size_t)read_bytes < tcp->incoming_buffer->length) {
       grpc_slice_buffer_trim_end(
           tcp->incoming_buffer,
           tcp->incoming_buffer->length - (size_t)read_bytes,
           &tcp->last_read_buffer);
-    } else if (tcp->iov_size < MAX_READ_IOVEC) {
-      ++tcp->iov_size;
     }
     GPR_ASSERT((size_t)read_bytes == tcp->incoming_buffer->length);
     call_read_cb(exec_ctx, tcp, GRPC_ERROR_NONE);
@@ -282,11 +324,11 @@ static void tcp_read_allocation_done(grpc_exec_ctx *exec_ctx, void *tcpp,
 }
 
 static void tcp_continue_read(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
-  if (tcp->incoming_buffer->count < (size_t)tcp->iov_size) {
-    grpc_resource_user_alloc_slices(
-        exec_ctx, &tcp->slice_allocator, tcp->slice_size,
-        (size_t)tcp->iov_size - tcp->incoming_buffer->count,
-        tcp->incoming_buffer);
+  size_t target_read_size = get_target_read_size(tcp);
+  if (tcp->incoming_buffer->length < target_read_size &&
+      tcp->incoming_buffer->count < MAX_READ_IOVEC) {
+    grpc_resource_user_alloc_slices(exec_ctx, &tcp->slice_allocator,
+                                    target_read_size, 1, tcp->incoming_buffer);
   } else {
     tcp_do_read(exec_ctx, tcp);
   }
@@ -464,10 +506,12 @@ static void tcp_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
 
   if (buf->length == 0) {
     GPR_TIMER_END("tcp_write", 0);
-    grpc_closure_sched(exec_ctx, cb,
-                       grpc_fd_is_shutdown(tcp->em_fd)
-                           ? tcp_annotate_error(GRPC_ERROR_CREATE("EOF"), tcp)
-                           : GRPC_ERROR_NONE);
+    grpc_closure_sched(
+        exec_ctx, cb,
+        grpc_fd_is_shutdown(tcp->em_fd)
+            ? tcp_annotate_error(GRPC_ERROR_CREATE_FROM_STATIC_STRING("EOF"),
+                                 tcp)
+            : GRPC_ERROR_NONE);
     return;
   }
   tcp->outgoing_buffer = buf;
@@ -535,9 +579,50 @@ static const grpc_endpoint_vtable vtable = {tcp_read,
                                             tcp_get_peer,
                                             tcp_get_fd};
 
-grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd,
-                               grpc_resource_quota *resource_quota,
-                               size_t slice_size, const char *peer_string) {
+#define MAX_CHUNK_SIZE 32 * 1024 * 1024
+
+grpc_endpoint *grpc_tcp_create(grpc_exec_ctx *exec_ctx, grpc_fd *em_fd,
+                               const grpc_channel_args *channel_args,
+                               const char *peer_string) {
+  int tcp_read_chunk_size = GRPC_TCP_DEFAULT_READ_SLICE_SIZE;
+  int tcp_max_read_chunk_size = 4 * 1024 * 1024;
+  int tcp_min_read_chunk_size = 256;
+  grpc_resource_quota *resource_quota = grpc_resource_quota_create(NULL);
+  if (channel_args != NULL) {
+    for (size_t i = 0; i < channel_args->num_args; i++) {
+      if (0 ==
+          strcmp(channel_args->args[i].key, GRPC_ARG_TCP_READ_CHUNK_SIZE)) {
+        grpc_integer_options options = {(int)tcp_read_chunk_size, 1,
+                                        MAX_CHUNK_SIZE};
+        tcp_read_chunk_size =
+            grpc_channel_arg_get_integer(&channel_args->args[i], options);
+      } else if (0 == strcmp(channel_args->args[i].key,
+                             GRPC_ARG_TCP_MIN_READ_CHUNK_SIZE)) {
+        grpc_integer_options options = {(int)tcp_read_chunk_size, 1,
+                                        MAX_CHUNK_SIZE};
+        tcp_min_read_chunk_size =
+            grpc_channel_arg_get_integer(&channel_args->args[i], options);
+      } else if (0 == strcmp(channel_args->args[i].key,
+                             GRPC_ARG_TCP_MAX_READ_CHUNK_SIZE)) {
+        grpc_integer_options options = {(int)tcp_read_chunk_size, 1,
+                                        MAX_CHUNK_SIZE};
+        tcp_max_read_chunk_size =
+            grpc_channel_arg_get_integer(&channel_args->args[i], options);
+      } else if (0 ==
+                 strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
+        grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
+        resource_quota = grpc_resource_quota_ref_internal(
+            channel_args->args[i].value.pointer.p);
+      }
+    }
+  }
+
+  if (tcp_min_read_chunk_size > tcp_max_read_chunk_size) {
+    tcp_min_read_chunk_size = tcp_max_read_chunk_size;
+  }
+  tcp_read_chunk_size = GPR_CLAMP(tcp_read_chunk_size, tcp_min_read_chunk_size,
+                                  tcp_max_read_chunk_size);
+
   grpc_tcp *tcp = (grpc_tcp *)gpr_malloc(sizeof(grpc_tcp));
   tcp->base.vtable = &vtable;
   tcp->peer_string = gpr_strdup(peer_string);
@@ -547,7 +632,10 @@ grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd,
   tcp->release_fd_cb = NULL;
   tcp->release_fd = NULL;
   tcp->incoming_buffer = NULL;
-  tcp->slice_size = slice_size;
+  tcp->target_length = (double)tcp_read_chunk_size;
+  tcp->min_read_chunk_size = tcp_min_read_chunk_size;
+  tcp->max_read_chunk_size = tcp_max_read_chunk_size;
+  tcp->bytes_read_this_round = 0;
   tcp->iov_size = 1;
   tcp->finished_edge = true;
   /* paired with unref in grpc_tcp_destroy */
@@ -564,6 +652,7 @@ grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd,
       &tcp->slice_allocator, tcp->resource_user, tcp_read_allocation_done, tcp);
   /* Tell network status tracker about new endpoint */
   grpc_network_status_register_endpoint(&tcp->base);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
 
   return &tcp->base;
 }
diff --git a/src/core/lib/iomgr/tcp_posix.h b/src/core/lib/iomgr/tcp_posix.h
index 1c0d13f96e2d3d2c726863cfabae6772e6c27141..1ad5788331ffd7cc0b525cd90a90ca839fe0b931 100644
--- a/src/core/lib/iomgr/tcp_posix.h
+++ b/src/core/lib/iomgr/tcp_posix.h
@@ -47,14 +47,13 @@
 #include "src/core/lib/iomgr/endpoint.h"
 #include "src/core/lib/iomgr/ev_posix.h"
 
-#define GRPC_TCP_DEFAULT_READ_SLICE_SIZE 8192
-
 extern int grpc_tcp_trace;
 
 /* Create a tcp endpoint given a file desciptor and a read slice size.
    Takes ownership of fd. */
-grpc_endpoint *grpc_tcp_create(grpc_fd *fd, grpc_resource_quota *resource_quota,
-                               size_t read_slice_size, const char *peer_string);
+grpc_endpoint *grpc_tcp_create(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
+                               const grpc_channel_args *args,
+                               const char *peer_string);
 
 /* Return the tcp endpoint's fd, or -1 if this is not available. Does not
    release the fd.
diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c
index 36f878fdd4ddb7912d6e0c9434f2c3d647198842..e66ffc9b1c22cf8c56a1910c42d0b9f4b6595f0a 100644
--- a/src/core/lib/iomgr/tcp_server_posix.c
+++ b/src/core/lib/iomgr/tcp_server_posix.c
@@ -44,11 +44,8 @@
 
 #include <errno.h>
 #include <fcntl.h>
-#include <ifaddrs.h>
-#include <limits.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
-#include <stdio.h>
 #include <string.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
@@ -62,85 +59,16 @@
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/sockaddr.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/iomgr/socket_utils_posix.h"
 #include "src/core/lib/iomgr/tcp_posix.h"
+#include "src/core/lib/iomgr/tcp_server_utils_posix.h"
 #include "src/core/lib/iomgr/unix_sockets_posix.h"
 #include "src/core/lib/support/string.h"
 
-#define MIN_SAFE_ACCEPT_QUEUE_SIZE 100
-
-static gpr_once s_init_max_accept_queue_size;
-static int s_max_accept_queue_size;
-
-/* one listening port */
-typedef struct grpc_tcp_listener grpc_tcp_listener;
-struct grpc_tcp_listener {
-  int fd;
-  grpc_fd *emfd;
-  grpc_tcp_server *server;
-  grpc_resolved_address addr;
-  int port;
-  unsigned port_index;
-  unsigned fd_index;
-  grpc_closure read_closure;
-  grpc_closure destroyed_closure;
-  struct grpc_tcp_listener *next;
-  /* sibling is a linked list of all listeners for a given port. add_port and
-     clone_port place all new listeners in the same sibling list. A member of
-     the 'sibling' list is also a member of the 'next' list. The head of each
-     sibling list has is_sibling==0, and subsequent members of sibling lists
-     have is_sibling==1. is_sibling allows separate sibling lists to be
-     identified while iterating through 'next'. */
-  struct grpc_tcp_listener *sibling;
-  int is_sibling;
-};
-
-/* the overall server */
-struct grpc_tcp_server {
-  gpr_refcount refs;
-  /* Called whenever accept() succeeds on a server port. */
-  grpc_tcp_server_cb on_accept_cb;
-  void *on_accept_cb_arg;
-
-  gpr_mu mu;
-
-  /* active port count: how many ports are actually still listening */
-  size_t active_ports;
-  /* destroyed port count: how many ports are completely destroyed */
-  size_t destroyed_ports;
-
-  /* is this server shutting down? */
-  bool shutdown;
-  /* use SO_REUSEPORT */
-  bool so_reuseport;
-  /* expand wildcard addresses to a list of all local addresses */
-  bool expand_wildcard_addrs;
-
-  /* linked list of server ports */
-  grpc_tcp_listener *head;
-  grpc_tcp_listener *tail;
-  unsigned nports;
-
-  /* List of closures passed to shutdown_starting_add(). */
-  grpc_closure_list shutdown_starting;
-
-  /* shutdown callback */
-  grpc_closure *shutdown_complete;
-
-  /* all pollsets interested in new connections */
-  grpc_pollset **pollsets;
-  /* number of pollsets in the pollsets array */
-  size_t pollset_count;
-
-  /* next pollset to assign a channel to */
-  gpr_atm next_pollset_to_assign;
-
-  grpc_resource_quota *resource_quota;
-};
-
 static gpr_once check_init = GPR_ONCE_INIT;
 static bool has_so_reuseport = false;
 
@@ -161,9 +89,8 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
                                    grpc_tcp_server **server) {
   gpr_once_init(&check_init, init);
 
-  grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
+  grpc_tcp_server *s = gpr_zalloc(sizeof(grpc_tcp_server));
   s->so_reuseport = has_so_reuseport;
-  s->resource_quota = grpc_resource_quota_create(NULL);
   s->expand_wildcard_addrs = false;
   for (size_t i = 0; i < (args == NULL ? 0 : args->num_args); i++) {
     if (0 == strcmp(GRPC_ARG_ALLOW_REUSEPORT, args->args[i].key)) {
@@ -171,30 +98,17 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
         s->so_reuseport =
             has_so_reuseport && (args->args[i].value.integer != 0);
       } else {
-        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
-        gpr_free(s);
-        return GRPC_ERROR_CREATE(GRPC_ARG_ALLOW_REUSEPORT
-                                 " must be an integer");
-      }
-    } else if (0 == strcmp(GRPC_ARG_RESOURCE_QUOTA, args->args[i].key)) {
-      if (args->args[i].type == GRPC_ARG_POINTER) {
-        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
-        s->resource_quota =
-            grpc_resource_quota_ref_internal(args->args[i].value.pointer.p);
-      } else {
-        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         gpr_free(s);
-        return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
-                                 " must be a pointer to a buffer pool");
+        return GRPC_ERROR_CREATE_FROM_STATIC_STRING(GRPC_ARG_ALLOW_REUSEPORT
+                                                    " must be an integer");
       }
     } else if (0 == strcmp(GRPC_ARG_EXPAND_WILDCARD_ADDRS, args->args[i].key)) {
       if (args->args[i].type == GRPC_ARG_INTEGER) {
         s->expand_wildcard_addrs = (args->args[i].value.integer != 0);
       } else {
-        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         gpr_free(s);
-        return GRPC_ERROR_CREATE(GRPC_ARG_EXPAND_WILDCARD_ADDRS
-                                 " must be an integer");
+        return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+            GRPC_ARG_EXPAND_WILDCARD_ADDRS " must be an integer");
       }
     }
   }
@@ -211,6 +125,7 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
   s->head = NULL;
   s->tail = NULL;
   s->nports = 0;
+  s->channel_args = grpc_channel_args_copy(args);
   gpr_atm_no_barrier_store(&s->next_pollset_to_assign, 0);
   *server = s;
   return GRPC_ERROR_NONE;
@@ -231,8 +146,7 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
     s->head = sp->next;
     gpr_free(sp);
   }
-
-  grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
+  grpc_channel_args_destroy(exec_ctx, s->channel_args);
 
   gpr_free(s);
 }
@@ -258,10 +172,7 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
   /* delete ALL the things */
   gpr_mu_lock(&s->mu);
 
-  if (!s->shutdown) {
-    gpr_mu_unlock(&s->mu);
-    return;
-  }
+  GPR_ASSERT(s->shutdown);
 
   if (s->head) {
     grpc_tcp_listener *sp;
@@ -289,8 +200,8 @@ static void tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
   if (s->active_ports) {
     grpc_tcp_listener *sp;
     for (sp = s->head; sp; sp = sp->next) {
-      grpc_fd_shutdown(exec_ctx, sp->emfd,
-                       GRPC_ERROR_CREATE("Server destroyed"));
+      grpc_fd_shutdown(exec_ctx, sp->emfd, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                               "Server destroyed"));
     }
     gpr_mu_unlock(&s->mu);
   } else {
@@ -299,99 +210,6 @@ static void tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
   }
 }
 
-/* get max listen queue size on linux */
-static void init_max_accept_queue_size(void) {
-  int n = SOMAXCONN;
-  char buf[64];
-  FILE *fp = fopen("/proc/sys/net/core/somaxconn", "r");
-  if (fp == NULL) {
-    /* 2.4 kernel. */
-    s_max_accept_queue_size = SOMAXCONN;
-    return;
-  }
-  if (fgets(buf, sizeof buf, fp)) {
-    char *end;
-    long i = strtol(buf, &end, 10);
-    if (i > 0 && i <= INT_MAX && end && *end == 0) {
-      n = (int)i;
-    }
-  }
-  fclose(fp);
-  s_max_accept_queue_size = n;
-
-  if (s_max_accept_queue_size < MIN_SAFE_ACCEPT_QUEUE_SIZE) {
-    gpr_log(GPR_INFO,
-            "Suspiciously small accept queue (%d) will probably lead to "
-            "connection drops",
-            s_max_accept_queue_size);
-  }
-}
-
-static int get_max_accept_queue_size(void) {
-  gpr_once_init(&s_init_max_accept_queue_size, init_max_accept_queue_size);
-  return s_max_accept_queue_size;
-}
-
-/* Prepare a recently-created socket for listening. */
-static grpc_error *prepare_socket(int fd, const grpc_resolved_address *addr,
-                                  bool so_reuseport, int *port) {
-  grpc_resolved_address sockname_temp;
-  grpc_error *err = GRPC_ERROR_NONE;
-
-  GPR_ASSERT(fd >= 0);
-
-  if (so_reuseport && !grpc_is_unix_socket(addr)) {
-    err = grpc_set_socket_reuse_port(fd, 1);
-    if (err != GRPC_ERROR_NONE) goto error;
-  }
-
-  err = grpc_set_socket_nonblocking(fd, 1);
-  if (err != GRPC_ERROR_NONE) goto error;
-  err = grpc_set_socket_cloexec(fd, 1);
-  if (err != GRPC_ERROR_NONE) goto error;
-  if (!grpc_is_unix_socket(addr)) {
-    err = grpc_set_socket_low_latency(fd, 1);
-    if (err != GRPC_ERROR_NONE) goto error;
-    err = grpc_set_socket_reuse_addr(fd, 1);
-    if (err != GRPC_ERROR_NONE) goto error;
-  }
-  err = grpc_set_socket_no_sigpipe_if_possible(fd);
-  if (err != GRPC_ERROR_NONE) goto error;
-
-  GPR_ASSERT(addr->len < ~(socklen_t)0);
-  if (bind(fd, (struct sockaddr *)addr->addr, (socklen_t)addr->len) < 0) {
-    err = GRPC_OS_ERROR(errno, "bind");
-    goto error;
-  }
-
-  if (listen(fd, get_max_accept_queue_size()) < 0) {
-    err = GRPC_OS_ERROR(errno, "listen");
-    goto error;
-  }
-
-  sockname_temp.len = sizeof(struct sockaddr_storage);
-
-  if (getsockname(fd, (struct sockaddr *)sockname_temp.addr,
-                  (socklen_t *)&sockname_temp.len) < 0) {
-    err = GRPC_OS_ERROR(errno, "getsockname");
-    goto error;
-  }
-
-  *port = grpc_sockaddr_get_port(&sockname_temp);
-  return GRPC_ERROR_NONE;
-
-error:
-  GPR_ASSERT(err != GRPC_ERROR_NONE);
-  if (fd >= 0) {
-    close(fd);
-  }
-  grpc_error *ret = grpc_error_set_int(
-      GRPC_ERROR_CREATE_REFERENCING("Unable to configure socket", &err, 1),
-      GRPC_ERROR_INT_FD, fd);
-  GRPC_ERROR_UNREF(err);
-  return ret;
-}
-
 /* event manager callback when reads are ready */
 static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *err) {
   grpc_tcp_listener *sp = arg;
@@ -422,7 +240,14 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *err) {
           grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
           return;
         default:
-          gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno));
+          gpr_mu_lock(&sp->server->mu);
+          if (!sp->server->shutdown_listeners) {
+            gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno));
+          } else {
+            /* if we have shutdown listeners, accept4 could fail, and we
+               needn't notify users */
+          }
+          gpr_mu_unlock(&sp->server->mu);
           goto error;
       }
     }
@@ -438,11 +263,6 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *err) {
 
     grpc_fd *fdobj = grpc_fd_create(fd, name);
 
-    if (read_notifier_pollset == NULL) {
-      gpr_log(GPR_ERROR, "Read notifier pollset is not set on the fd");
-      goto error;
-    }
-
     grpc_pollset_add_fd(exec_ctx, read_notifier_pollset, fdobj);
 
     // Create acceptor.
@@ -453,8 +273,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *err) {
 
     sp->server->on_accept_cb(
         exec_ctx, sp->server->on_accept_cb_arg,
-        grpc_tcp_create(fdobj, sp->server->resource_quota,
-                        GRPC_TCP_DEFAULT_READ_SLICE_SIZE, addr_str),
+        grpc_tcp_create(exec_ctx, fdobj, sp->server->channel_args, addr_str),
         read_notifier_pollset, acceptor);
 
     gpr_free(name);
@@ -465,7 +284,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *err) {
 
 error:
   gpr_mu_lock(&sp->server->mu);
-  if (0 == --sp->server->active_ports) {
+  if (0 == --sp->server->active_ports && sp->server->shutdown) {
     gpr_mu_unlock(&sp->server->mu);
     deactivated_all_ports(exec_ctx, sp->server);
   } else {
@@ -473,216 +292,6 @@ error:
   }
 }
 
-static grpc_error *add_socket_to_server(grpc_tcp_server *s, int fd,
-                                        const grpc_resolved_address *addr,
-                                        unsigned port_index, unsigned fd_index,
-                                        grpc_tcp_listener **listener) {
-  grpc_tcp_listener *sp = NULL;
-  int port = -1;
-  char *addr_str;
-  char *name;
-
-  grpc_error *err = prepare_socket(fd, addr, s->so_reuseport, &port);
-  if (err == GRPC_ERROR_NONE) {
-    GPR_ASSERT(port > 0);
-    grpc_sockaddr_to_string(&addr_str, addr, 1);
-    gpr_asprintf(&name, "tcp-server-listener:%s", addr_str);
-    gpr_mu_lock(&s->mu);
-    s->nports++;
-    GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
-    sp = gpr_malloc(sizeof(grpc_tcp_listener));
-    sp->next = NULL;
-    if (s->head == NULL) {
-      s->head = sp;
-    } else {
-      s->tail->next = sp;
-    }
-    s->tail = sp;
-    sp->server = s;
-    sp->fd = fd;
-    sp->emfd = grpc_fd_create(fd, name);
-    memcpy(&sp->addr, addr, sizeof(grpc_resolved_address));
-    sp->port = port;
-    sp->port_index = port_index;
-    sp->fd_index = fd_index;
-    sp->is_sibling = 0;
-    sp->sibling = NULL;
-    GPR_ASSERT(sp->emfd);
-    gpr_mu_unlock(&s->mu);
-    gpr_free(addr_str);
-    gpr_free(name);
-  }
-
-  *listener = sp;
-  return err;
-}
-
-/* If successful, add a listener to s for addr, set *dsmode for the socket, and
-   return the *listener. */
-static grpc_error *add_addr_to_server(grpc_tcp_server *s,
-                                      const grpc_resolved_address *addr,
-                                      unsigned port_index, unsigned fd_index,
-                                      grpc_dualstack_mode *dsmode,
-                                      grpc_tcp_listener **listener) {
-  grpc_resolved_address addr4_copy;
-  int fd;
-  grpc_error *err =
-      grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, dsmode, &fd);
-  if (err != GRPC_ERROR_NONE) {
-    return err;
-  }
-  if (*dsmode == GRPC_DSMODE_IPV4 &&
-      grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
-    addr = &addr4_copy;
-  }
-  return add_socket_to_server(s, fd, addr, port_index, fd_index, listener);
-}
-
-/* Bind to "::" to get a port number not used by any address. */
-static grpc_error *get_unused_port(int *port) {
-  grpc_resolved_address wild;
-  grpc_sockaddr_make_wildcard6(0, &wild);
-  grpc_dualstack_mode dsmode;
-  int fd;
-  grpc_error *err =
-      grpc_create_dualstack_socket(&wild, SOCK_STREAM, 0, &dsmode, &fd);
-  if (err != GRPC_ERROR_NONE) {
-    return err;
-  }
-  if (dsmode == GRPC_DSMODE_IPV4) {
-    grpc_sockaddr_make_wildcard4(0, &wild);
-  }
-  if (bind(fd, (const struct sockaddr *)wild.addr, (socklen_t)wild.len) != 0) {
-    err = GRPC_OS_ERROR(errno, "bind");
-    close(fd);
-    return err;
-  }
-  if (getsockname(fd, (struct sockaddr *)wild.addr, (socklen_t *)&wild.len) !=
-      0) {
-    err = GRPC_OS_ERROR(errno, "getsockname");
-    close(fd);
-    return err;
-  }
-  close(fd);
-  *port = grpc_sockaddr_get_port(&wild);
-  return *port <= 0 ? GRPC_ERROR_CREATE("Bad port") : GRPC_ERROR_NONE;
-}
-
-/* Return the listener in s with address addr or NULL. */
-static grpc_tcp_listener *find_listener_with_addr(grpc_tcp_server *s,
-                                                  grpc_resolved_address *addr) {
-  grpc_tcp_listener *l;
-  gpr_mu_lock(&s->mu);
-  for (l = s->head; l != NULL; l = l->next) {
-    if (l->addr.len != addr->len) {
-      continue;
-    }
-    if (memcmp(l->addr.addr, addr->addr, addr->len) == 0) {
-      break;
-    }
-  }
-  gpr_mu_unlock(&s->mu);
-  return l;
-}
-
-/* Get all addresses assigned to network interfaces on the machine and create a
-   listener for each. requested_port is the port to use for every listener, or 0
-   to select one random port that will be used for every listener. Set *out_port
-   to the port selected. Return GRPC_ERROR_NONE only if all listeners were
-   added. */
-static grpc_error *add_all_local_addrs_to_server(grpc_tcp_server *s,
-                                                 unsigned port_index,
-                                                 int requested_port,
-                                                 int *out_port) {
-  struct ifaddrs *ifa = NULL;
-  struct ifaddrs *ifa_it;
-  unsigned fd_index = 0;
-  grpc_tcp_listener *sp = NULL;
-  grpc_error *err = GRPC_ERROR_NONE;
-  if (requested_port == 0) {
-    /* Note: There could be a race where some local addrs can listen on the
-       selected port and some can't. The sane way to handle this would be to
-       retry by recreating the whole grpc_tcp_server. Backing out individual
-       listeners and orphaning the FDs looks like too much trouble. */
-    if ((err = get_unused_port(&requested_port)) != GRPC_ERROR_NONE) {
-      return err;
-    } else if (requested_port <= 0) {
-      return GRPC_ERROR_CREATE("Bad get_unused_port()");
-    }
-    gpr_log(GPR_DEBUG, "Picked unused port %d", requested_port);
-  }
-  if (getifaddrs(&ifa) != 0 || ifa == NULL) {
-    return GRPC_OS_ERROR(errno, "getifaddrs");
-  }
-  for (ifa_it = ifa; ifa_it != NULL; ifa_it = ifa_it->ifa_next) {
-    grpc_resolved_address addr;
-    char *addr_str = NULL;
-    grpc_dualstack_mode dsmode;
-    grpc_tcp_listener *new_sp = NULL;
-    const char *ifa_name = (ifa_it->ifa_name ? ifa_it->ifa_name : "<unknown>");
-    if (ifa_it->ifa_addr == NULL) {
-      continue;
-    } else if (ifa_it->ifa_addr->sa_family == AF_INET) {
-      addr.len = sizeof(struct sockaddr_in);
-    } else if (ifa_it->ifa_addr->sa_family == AF_INET6) {
-      addr.len = sizeof(struct sockaddr_in6);
-    } else {
-      continue;
-    }
-    memcpy(addr.addr, ifa_it->ifa_addr, addr.len);
-    if (!grpc_sockaddr_set_port(&addr, requested_port)) {
-      /* Should never happen, because we check sa_family above. */
-      err = GRPC_ERROR_CREATE("Failed to set port");
-      break;
-    }
-    if (grpc_sockaddr_to_string(&addr_str, &addr, 0) < 0) {
-      addr_str = gpr_strdup("<error>");
-    }
-    gpr_log(GPR_DEBUG,
-            "Adding local addr from interface %s flags 0x%x to server: %s",
-            ifa_name, ifa_it->ifa_flags, addr_str);
-    /* We could have multiple interfaces with the same address (e.g., bonding),
-       so look for duplicates. */
-    if (find_listener_with_addr(s, &addr) != NULL) {
-      gpr_log(GPR_DEBUG, "Skipping duplicate addr %s on interface %s", addr_str,
-              ifa_name);
-      gpr_free(addr_str);
-      continue;
-    }
-    if ((err = add_addr_to_server(s, &addr, port_index, fd_index, &dsmode,
-                                  &new_sp)) != GRPC_ERROR_NONE) {
-      char *err_str = NULL;
-      grpc_error *root_err;
-      if (gpr_asprintf(&err_str, "Failed to add listener: %s", addr_str) < 0) {
-        err_str = gpr_strdup("Failed to add listener");
-      }
-      root_err = GRPC_ERROR_CREATE(err_str);
-      gpr_free(err_str);
-      gpr_free(addr_str);
-      err = grpc_error_add_child(root_err, err);
-      break;
-    } else {
-      GPR_ASSERT(requested_port == new_sp->port);
-      ++fd_index;
-      if (sp != NULL) {
-        new_sp->is_sibling = 1;
-        sp->sibling = new_sp;
-      }
-      sp = new_sp;
-    }
-    gpr_free(addr_str);
-  }
-  freeifaddrs(ifa);
-  if (err != GRPC_ERROR_NONE) {
-    return err;
-  } else if (sp == NULL) {
-    return GRPC_ERROR_CREATE("No local addresses");
-  } else {
-    *out_port = sp->port;
-    return GRPC_ERROR_NONE;
-  }
-}
-
 /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
 static grpc_error *add_wildcard_addrs_to_server(grpc_tcp_server *s,
                                                 unsigned port_index,
@@ -697,14 +306,16 @@ static grpc_error *add_wildcard_addrs_to_server(grpc_tcp_server *s,
   grpc_error *v6_err = GRPC_ERROR_NONE;
   grpc_error *v4_err = GRPC_ERROR_NONE;
   *out_port = -1;
-  if (s->expand_wildcard_addrs) {
-    return add_all_local_addrs_to_server(s, port_index, requested_port,
-                                         out_port);
+
+  if (grpc_tcp_server_have_ifaddrs() && s->expand_wildcard_addrs) {
+    return grpc_tcp_server_add_all_local_addrs(s, port_index, requested_port,
+                                               out_port);
   }
+
   grpc_sockaddr_make_wildcards(requested_port, &wild4, &wild6);
   /* Try listening on IPv6 first. */
-  if ((v6_err = add_addr_to_server(s, &wild6, port_index, fd_index, &dsmode,
-                                   &sp)) == GRPC_ERROR_NONE) {
+  if ((v6_err = grpc_tcp_server_add_addr(s, &wild6, port_index, fd_index,
+                                         &dsmode, &sp)) == GRPC_ERROR_NONE) {
     ++fd_index;
     requested_port = *out_port = sp->port;
     if (dsmode == GRPC_DSMODE_DUALSTACK || dsmode == GRPC_DSMODE_IPV4) {
@@ -713,8 +324,8 @@ static grpc_error *add_wildcard_addrs_to_server(grpc_tcp_server *s,
   }
   /* If we got a v6-only socket or nothing, try adding 0.0.0.0. */
   grpc_sockaddr_set_port(&wild4, requested_port);
-  if ((v4_err = add_addr_to_server(s, &wild4, port_index, fd_index, &dsmode,
-                                   &sp2)) == GRPC_ERROR_NONE) {
+  if ((v4_err = grpc_tcp_server_add_addr(s, &wild4, port_index, fd_index,
+                                         &dsmode, &sp2)) == GRPC_ERROR_NONE) {
     *out_port = sp2->port;
     if (sp != NULL) {
       sp2->is_sibling = 1;
@@ -722,12 +333,24 @@ static grpc_error *add_wildcard_addrs_to_server(grpc_tcp_server *s,
     }
   }
   if (*out_port > 0) {
-    GRPC_LOG_IF_ERROR("Failed to add :: listener", v6_err);
-    GRPC_LOG_IF_ERROR("Failed to add 0.0.0.0 listener", v4_err);
+    if (v6_err != GRPC_ERROR_NONE) {
+      gpr_log(GPR_INFO,
+              "Failed to add :: listener, "
+              "the environment may not support IPv6: %s",
+              grpc_error_string(v6_err));
+      GRPC_ERROR_UNREF(v6_err);
+    }
+    if (v4_err != GRPC_ERROR_NONE) {
+      gpr_log(GPR_INFO,
+              "Failed to add 0.0.0.0 listener, "
+              "the environment may not support IPv4: %s",
+              grpc_error_string(v4_err));
+      GRPC_ERROR_UNREF(v4_err);
+    }
     return GRPC_ERROR_NONE;
   } else {
-    grpc_error *root_err =
-        GRPC_ERROR_CREATE("Failed to add any wildcard listeners");
+    grpc_error *root_err = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Failed to add any wildcard listeners");
     GPR_ASSERT(v6_err != GRPC_ERROR_NONE && v4_err != GRPC_ERROR_NONE);
     root_err = grpc_error_add_child(root_err, v6_err);
     root_err = grpc_error_add_child(root_err, v4_err);
@@ -752,7 +375,7 @@ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) {
     err = grpc_create_dualstack_socket(&listener->addr, SOCK_STREAM, 0, &dsmode,
                                        &fd);
     if (err != GRPC_ERROR_NONE) return err;
-    err = prepare_socket(fd, &listener->addr, true, &port);
+    err = grpc_tcp_server_prepare_socket(fd, &listener->addr, true, &port);
     if (err != GRPC_ERROR_NONE) return err;
     listener->server->nports++;
     grpc_sockaddr_to_string(&addr_str, &listener->addr, 1);
@@ -824,7 +447,7 @@ grpc_error *grpc_tcp_server_add_port(grpc_tcp_server *s,
   if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
     addr = &addr6_v4mapped;
   }
-  if ((err = add_addr_to_server(s, addr, port_index, 0, &dsmode, &sp)) ==
+  if ((err = grpc_tcp_server_add_addr(s, addr, port_index, 0, &dsmode, &sp)) ==
       GRPC_ERROR_NONE) {
     *out_port = sp->port;
   }
@@ -941,12 +564,13 @@ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
 void grpc_tcp_server_shutdown_listeners(grpc_exec_ctx *exec_ctx,
                                         grpc_tcp_server *s) {
   gpr_mu_lock(&s->mu);
+  s->shutdown_listeners = true;
   /* shutdown all fd's */
   if (s->active_ports) {
     grpc_tcp_listener *sp;
     for (sp = s->head; sp; sp = sp->next) {
       grpc_fd_shutdown(exec_ctx, sp->emfd,
-                       GRPC_ERROR_CREATE("Server shutdown"));
+                       GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server shutdown"));
     }
   }
   gpr_mu_unlock(&s->mu);
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix.h b/src/core/lib/iomgr/tcp_server_utils_posix.h
new file mode 100644
index 0000000000000000000000000000000000000000..c15e2e1493a4e2462e066c2eb75c7b906016bd0d
--- /dev/null
+++ b/src/core/lib/iomgr/tcp_server_utils_posix.h
@@ -0,0 +1,135 @@
+/*
+ *
+ * Copyright 2017, 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_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H
+#define GRPC_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H
+
+#include "src/core/lib/iomgr/ev_posix.h"
+#include "src/core/lib/iomgr/resolve_address.h"
+#include "src/core/lib/iomgr/socket_utils_posix.h"
+#include "src/core/lib/iomgr/tcp_server.h"
+
+/* one listening port */
+typedef struct grpc_tcp_listener {
+  int fd;
+  grpc_fd *emfd;
+  grpc_tcp_server *server;
+  grpc_resolved_address addr;
+  int port;
+  unsigned port_index;
+  unsigned fd_index;
+  grpc_closure read_closure;
+  grpc_closure destroyed_closure;
+  struct grpc_tcp_listener *next;
+  /* sibling is a linked list of all listeners for a given port. add_port and
+     clone_port place all new listeners in the same sibling list. A member of
+     the 'sibling' list is also a member of the 'next' list. The head of each
+     sibling list has is_sibling==0, and subsequent members of sibling lists
+     have is_sibling==1. is_sibling allows separate sibling lists to be
+     identified while iterating through 'next'. */
+  struct grpc_tcp_listener *sibling;
+  int is_sibling;
+} grpc_tcp_listener;
+
+/* the overall server */
+struct grpc_tcp_server {
+  gpr_refcount refs;
+  /* Called whenever accept() succeeds on a server port. */
+  grpc_tcp_server_cb on_accept_cb;
+  void *on_accept_cb_arg;
+
+  gpr_mu mu;
+
+  /* active port count: how many ports are actually still listening */
+  size_t active_ports;
+  /* destroyed port count: how many ports are completely destroyed */
+  size_t destroyed_ports;
+
+  /* is this server shutting down? */
+  bool shutdown;
+  /* have listeners been shutdown? */
+  bool shutdown_listeners;
+  /* use SO_REUSEPORT */
+  bool so_reuseport;
+  /* expand wildcard addresses to a list of all local addresses */
+  bool expand_wildcard_addrs;
+
+  /* linked list of server ports */
+  grpc_tcp_listener *head;
+  grpc_tcp_listener *tail;
+  unsigned nports;
+
+  /* List of closures passed to shutdown_starting_add(). */
+  grpc_closure_list shutdown_starting;
+
+  /* shutdown callback */
+  grpc_closure *shutdown_complete;
+
+  /* all pollsets interested in new connections */
+  grpc_pollset **pollsets;
+  /* number of pollsets in the pollsets array */
+  size_t pollset_count;
+
+  /* next pollset to assign a channel to */
+  gpr_atm next_pollset_to_assign;
+
+  /* channel args for this server */
+  grpc_channel_args *channel_args;
+};
+
+/* If successful, add a listener to \a s for \a addr, set \a dsmode for the
+   socket, and return the \a listener. */
+grpc_error *grpc_tcp_server_add_addr(grpc_tcp_server *s,
+                                     const grpc_resolved_address *addr,
+                                     unsigned port_index, unsigned fd_index,
+                                     grpc_dualstack_mode *dsmode,
+                                     grpc_tcp_listener **listener);
+
+/* Get all addresses assigned to network interfaces on the machine and create a
+   listener for each. requested_port is the port to use for every listener, or 0
+   to select one random port that will be used for every listener. Set *out_port
+   to the port selected. Return GRPC_ERROR_NONE only if all listeners were
+   added. */
+grpc_error *grpc_tcp_server_add_all_local_addrs(grpc_tcp_server *s,
+                                                unsigned port_index,
+                                                int requested_port,
+                                                int *out_port);
+
+/* Prepare a recently-created socket for listening. */
+grpc_error *grpc_tcp_server_prepare_socket(int fd,
+                                           const grpc_resolved_address *addr,
+                                           bool so_reuseport, int *port);
+/* Ruturn true if the platform supports ifaddrs */
+bool grpc_tcp_server_have_ifaddrs(void);
+
+#endif /* GRPC_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H */
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_common.c b/src/core/lib/iomgr/tcp_server_utils_posix_common.c
new file mode 100644
index 0000000000000000000000000000000000000000..af2b00b4b541edc5f021dd2f8df0edc6ab49f552
--- /dev/null
+++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.c
@@ -0,0 +1,221 @@
+/*
+ *
+ * Copyright 2017, 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/lib/iomgr/port.h"
+
+#ifdef GRPC_POSIX_SOCKET
+
+#include "src/core/lib/iomgr/tcp_server_utils_posix.h"
+
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/sync.h>
+
+#include "src/core/lib/iomgr/error.h"
+#include "src/core/lib/iomgr/sockaddr.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
+#include "src/core/lib/iomgr/unix_sockets_posix.h"
+
+#define MIN_SAFE_ACCEPT_QUEUE_SIZE 100
+
+static gpr_once s_init_max_accept_queue_size;
+static int s_max_accept_queue_size;
+
+/* get max listen queue size on linux */
+static void init_max_accept_queue_size(void) {
+  int n = SOMAXCONN;
+  char buf[64];
+  FILE *fp = fopen("/proc/sys/net/core/somaxconn", "r");
+  if (fp == NULL) {
+    /* 2.4 kernel. */
+    s_max_accept_queue_size = SOMAXCONN;
+    return;
+  }
+  if (fgets(buf, sizeof buf, fp)) {
+    char *end;
+    long i = strtol(buf, &end, 10);
+    if (i > 0 && i <= INT_MAX && end && *end == 0) {
+      n = (int)i;
+    }
+  }
+  fclose(fp);
+  s_max_accept_queue_size = n;
+
+  if (s_max_accept_queue_size < MIN_SAFE_ACCEPT_QUEUE_SIZE) {
+    gpr_log(GPR_INFO,
+            "Suspiciously small accept queue (%d) will probably lead to "
+            "connection drops",
+            s_max_accept_queue_size);
+  }
+}
+
+static int get_max_accept_queue_size(void) {
+  gpr_once_init(&s_init_max_accept_queue_size, init_max_accept_queue_size);
+  return s_max_accept_queue_size;
+}
+
+static grpc_error *add_socket_to_server(grpc_tcp_server *s, int fd,
+                                        const grpc_resolved_address *addr,
+                                        unsigned port_index, unsigned fd_index,
+                                        grpc_tcp_listener **listener) {
+  grpc_tcp_listener *sp = NULL;
+  int port = -1;
+  char *addr_str;
+  char *name;
+
+  grpc_error *err =
+      grpc_tcp_server_prepare_socket(fd, addr, s->so_reuseport, &port);
+  if (err == GRPC_ERROR_NONE) {
+    GPR_ASSERT(port > 0);
+    grpc_sockaddr_to_string(&addr_str, addr, 1);
+    gpr_asprintf(&name, "tcp-server-listener:%s", addr_str);
+    gpr_mu_lock(&s->mu);
+    s->nports++;
+    GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
+    sp = gpr_malloc(sizeof(grpc_tcp_listener));
+    sp->next = NULL;
+    if (s->head == NULL) {
+      s->head = sp;
+    } else {
+      s->tail->next = sp;
+    }
+    s->tail = sp;
+    sp->server = s;
+    sp->fd = fd;
+    sp->emfd = grpc_fd_create(fd, name);
+    memcpy(&sp->addr, addr, sizeof(grpc_resolved_address));
+    sp->port = port;
+    sp->port_index = port_index;
+    sp->fd_index = fd_index;
+    sp->is_sibling = 0;
+    sp->sibling = NULL;
+    GPR_ASSERT(sp->emfd);
+    gpr_mu_unlock(&s->mu);
+    gpr_free(addr_str);
+    gpr_free(name);
+  }
+
+  *listener = sp;
+  return err;
+}
+
+/* If successful, add a listener to s for addr, set *dsmode for the socket, and
+   return the *listener. */
+grpc_error *grpc_tcp_server_add_addr(grpc_tcp_server *s,
+                                     const grpc_resolved_address *addr,
+                                     unsigned port_index, unsigned fd_index,
+                                     grpc_dualstack_mode *dsmode,
+                                     grpc_tcp_listener **listener) {
+  grpc_resolved_address addr4_copy;
+  int fd;
+  grpc_error *err =
+      grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, dsmode, &fd);
+  if (err != GRPC_ERROR_NONE) {
+    return err;
+  }
+  if (*dsmode == GRPC_DSMODE_IPV4 &&
+      grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
+    addr = &addr4_copy;
+  }
+  return add_socket_to_server(s, fd, addr, port_index, fd_index, listener);
+}
+
+/* Prepare a recently-created socket for listening. */
+grpc_error *grpc_tcp_server_prepare_socket(int fd,
+                                           const grpc_resolved_address *addr,
+                                           bool so_reuseport, int *port) {
+  grpc_resolved_address sockname_temp;
+  grpc_error *err = GRPC_ERROR_NONE;
+
+  GPR_ASSERT(fd >= 0);
+
+  if (so_reuseport && !grpc_is_unix_socket(addr)) {
+    err = grpc_set_socket_reuse_port(fd, 1);
+    if (err != GRPC_ERROR_NONE) goto error;
+  }
+
+  err = grpc_set_socket_nonblocking(fd, 1);
+  if (err != GRPC_ERROR_NONE) goto error;
+  err = grpc_set_socket_cloexec(fd, 1);
+  if (err != GRPC_ERROR_NONE) goto error;
+  if (!grpc_is_unix_socket(addr)) {
+    err = grpc_set_socket_low_latency(fd, 1);
+    if (err != GRPC_ERROR_NONE) goto error;
+    err = grpc_set_socket_reuse_addr(fd, 1);
+    if (err != GRPC_ERROR_NONE) goto error;
+  }
+  err = grpc_set_socket_no_sigpipe_if_possible(fd);
+  if (err != GRPC_ERROR_NONE) goto error;
+
+  GPR_ASSERT(addr->len < ~(socklen_t)0);
+  if (bind(fd, (struct sockaddr *)addr->addr, (socklen_t)addr->len) < 0) {
+    err = GRPC_OS_ERROR(errno, "bind");
+    goto error;
+  }
+
+  if (listen(fd, get_max_accept_queue_size()) < 0) {
+    err = GRPC_OS_ERROR(errno, "listen");
+    goto error;
+  }
+
+  sockname_temp.len = sizeof(struct sockaddr_storage);
+
+  if (getsockname(fd, (struct sockaddr *)sockname_temp.addr,
+                  (socklen_t *)&sockname_temp.len) < 0) {
+    err = GRPC_OS_ERROR(errno, "getsockname");
+    goto error;
+  }
+
+  *port = grpc_sockaddr_get_port(&sockname_temp);
+  return GRPC_ERROR_NONE;
+
+error:
+  GPR_ASSERT(err != GRPC_ERROR_NONE);
+  if (fd >= 0) {
+    close(fd);
+  }
+  grpc_error *ret =
+      grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                             "Unable to configure socket", &err, 1),
+                         GRPC_ERROR_INT_FD, fd);
+  GRPC_ERROR_UNREF(err);
+  return ret;
+}
+
+#endif /* GRPC_POSIX_SOCKET */
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c b/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
new file mode 100644
index 0000000000000000000000000000000000000000..2078a681268de1078ad66d662b68c9894ce7a13c
--- /dev/null
+++ b/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
@@ -0,0 +1,196 @@
+/*
+ *
+ * Copyright 2017, 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/lib/iomgr/port.h"
+
+#ifdef GRPC_HAVE_IFADDRS
+
+#include "src/core/lib/iomgr/tcp_server_utils_posix.h"
+
+#include <errno.h>
+#include <ifaddrs.h>
+#include <stddef.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/lib/iomgr/error.h"
+#include "src/core/lib/iomgr/sockaddr.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
+
+/* Return the listener in s with address addr or NULL. */
+static grpc_tcp_listener *find_listener_with_addr(grpc_tcp_server *s,
+                                                  grpc_resolved_address *addr) {
+  grpc_tcp_listener *l;
+  gpr_mu_lock(&s->mu);
+  for (l = s->head; l != NULL; l = l->next) {
+    if (l->addr.len != addr->len) {
+      continue;
+    }
+    if (memcmp(l->addr.addr, addr->addr, addr->len) == 0) {
+      break;
+    }
+  }
+  gpr_mu_unlock(&s->mu);
+  return l;
+}
+
+/* Bind to "::" to get a port number not used by any address. */
+static grpc_error *get_unused_port(int *port) {
+  grpc_resolved_address wild;
+  grpc_sockaddr_make_wildcard6(0, &wild);
+  grpc_dualstack_mode dsmode;
+  int fd;
+  grpc_error *err =
+      grpc_create_dualstack_socket(&wild, SOCK_STREAM, 0, &dsmode, &fd);
+  if (err != GRPC_ERROR_NONE) {
+    return err;
+  }
+  if (dsmode == GRPC_DSMODE_IPV4) {
+    grpc_sockaddr_make_wildcard4(0, &wild);
+  }
+  if (bind(fd, (const struct sockaddr *)wild.addr, (socklen_t)wild.len) != 0) {
+    err = GRPC_OS_ERROR(errno, "bind");
+    close(fd);
+    return err;
+  }
+  if (getsockname(fd, (struct sockaddr *)wild.addr, (socklen_t *)&wild.len) !=
+      0) {
+    err = GRPC_OS_ERROR(errno, "getsockname");
+    close(fd);
+    return err;
+  }
+  close(fd);
+  *port = grpc_sockaddr_get_port(&wild);
+  return *port <= 0 ? GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad port")
+                    : GRPC_ERROR_NONE;
+}
+
+grpc_error *grpc_tcp_server_add_all_local_addrs(grpc_tcp_server *s,
+                                                unsigned port_index,
+                                                int requested_port,
+                                                int *out_port) {
+  struct ifaddrs *ifa = NULL;
+  struct ifaddrs *ifa_it;
+  unsigned fd_index = 0;
+  grpc_tcp_listener *sp = NULL;
+  grpc_error *err = GRPC_ERROR_NONE;
+  if (requested_port == 0) {
+    /* Note: There could be a race where some local addrs can listen on the
+       selected port and some can't. The sane way to handle this would be to
+       retry by recreating the whole grpc_tcp_server. Backing out individual
+       listeners and orphaning the FDs looks like too much trouble. */
+    if ((err = get_unused_port(&requested_port)) != GRPC_ERROR_NONE) {
+      return err;
+    } else if (requested_port <= 0) {
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad get_unused_port()");
+    }
+    gpr_log(GPR_DEBUG, "Picked unused port %d", requested_port);
+  }
+  if (getifaddrs(&ifa) != 0 || ifa == NULL) {
+    return GRPC_OS_ERROR(errno, "getifaddrs");
+  }
+  for (ifa_it = ifa; ifa_it != NULL; ifa_it = ifa_it->ifa_next) {
+    grpc_resolved_address addr;
+    char *addr_str = NULL;
+    grpc_dualstack_mode dsmode;
+    grpc_tcp_listener *new_sp = NULL;
+    const char *ifa_name = (ifa_it->ifa_name ? ifa_it->ifa_name : "<unknown>");
+    if (ifa_it->ifa_addr == NULL) {
+      continue;
+    } else if (ifa_it->ifa_addr->sa_family == AF_INET) {
+      addr.len = sizeof(struct sockaddr_in);
+    } else if (ifa_it->ifa_addr->sa_family == AF_INET6) {
+      addr.len = sizeof(struct sockaddr_in6);
+    } else {
+      continue;
+    }
+    memcpy(addr.addr, ifa_it->ifa_addr, addr.len);
+    if (!grpc_sockaddr_set_port(&addr, requested_port)) {
+      /* Should never happen, because we check sa_family above. */
+      err = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set port");
+      break;
+    }
+    if (grpc_sockaddr_to_string(&addr_str, &addr, 0) < 0) {
+      addr_str = gpr_strdup("<error>");
+    }
+    gpr_log(GPR_DEBUG,
+            "Adding local addr from interface %s flags 0x%x to server: %s",
+            ifa_name, ifa_it->ifa_flags, addr_str);
+    /* We could have multiple interfaces with the same address (e.g., bonding),
+       so look for duplicates. */
+    if (find_listener_with_addr(s, &addr) != NULL) {
+      gpr_log(GPR_DEBUG, "Skipping duplicate addr %s on interface %s", addr_str,
+              ifa_name);
+      gpr_free(addr_str);
+      continue;
+    }
+    if ((err = grpc_tcp_server_add_addr(s, &addr, port_index, fd_index, &dsmode,
+                                        &new_sp)) != GRPC_ERROR_NONE) {
+      char *err_str = NULL;
+      grpc_error *root_err;
+      if (gpr_asprintf(&err_str, "Failed to add listener: %s", addr_str) < 0) {
+        err_str = gpr_strdup("Failed to add listener");
+      }
+      root_err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(err_str);
+      gpr_free(err_str);
+      gpr_free(addr_str);
+      err = grpc_error_add_child(root_err, err);
+      break;
+    } else {
+      GPR_ASSERT(requested_port == new_sp->port);
+      ++fd_index;
+      if (sp != NULL) {
+        new_sp->is_sibling = 1;
+        sp->sibling = new_sp;
+      }
+      sp = new_sp;
+    }
+    gpr_free(addr_str);
+  }
+  freeifaddrs(ifa);
+  if (err != GRPC_ERROR_NONE) {
+    return err;
+  } else if (sp == NULL) {
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("No local addresses");
+  } else {
+    *out_port = sp->port;
+    return GRPC_ERROR_NONE;
+  }
+}
+
+bool grpc_tcp_server_have_ifaddrs(void) { return true; }
+
+#endif /* GRPC_HAVE_IFADDRS */
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c b/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
new file mode 100644
index 0000000000000000000000000000000000000000..d6a1a0693e01a9cc7647cc3c04a58fc89229b9f2
--- /dev/null
+++ b/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
@@ -0,0 +1,49 @@
+/*
+ *
+ * Copyright 2017, 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/lib/iomgr/port.h"
+
+#if defined(GRPC_POSIX_SOCKET) && !defined(GRPC_HAVE_IFADDRS)
+
+#include "src/core/lib/iomgr/tcp_server_utils_posix.h"
+
+grpc_error *grpc_tcp_server_add_all_local_addrs(grpc_tcp_server *s,
+                                                unsigned port_index,
+                                                int requested_port,
+                                                int *out_port) {
+  return GRPC_ERROR_CREATE_FROM_STATIC_STRING("no ifaddrs available");
+}
+
+bool grpc_tcp_server_have_ifaddrs(void) { return false; }
+
+#endif /* defined(GRPC_POSIX_SOCKET) && !defined(GRPC_HAVE_IFADDRS) */
diff --git a/src/core/lib/iomgr/tcp_server_uv.c b/src/core/lib/iomgr/tcp_server_uv.c
index eed2773f8a0b4ef67a97c29ee2f4efc71b806c2e..e9246948f5b063ee78792878f998a239d2206a2c 100644
--- a/src/core/lib/iomgr/tcp_server_uv.c
+++ b/src/core/lib/iomgr/tcp_server_uv.c
@@ -95,8 +95,8 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
       } else {
         grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         gpr_free(s);
-        return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
-                                 " must be a pointer to a buffer pool");
+        return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+            GRPC_ARG_RESOURCE_QUOTA " must be a pointer to a buffer pool");
       }
     }
   }
@@ -244,17 +244,19 @@ static grpc_error *add_socket_to_server(grpc_tcp_server *s, uv_tcp_t *handle,
   // The last argument to uv_tcp_bind is flags
   status = uv_tcp_bind(handle, (struct sockaddr *)addr->addr, 0);
   if (status != 0) {
-    error = GRPC_ERROR_CREATE("Failed to bind to port");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to bind to port");
     error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, uv_strerror(status));
+        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                           grpc_slice_from_static_string(uv_strerror(status)));
     return error;
   }
 
   status = uv_listen((uv_stream_t *)handle, SOMAXCONN, on_connect);
   if (status != 0) {
-    error = GRPC_ERROR_CREATE("Failed to listen to port");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to listen to port");
     error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, uv_strerror(status));
+        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                           grpc_slice_from_static_string(uv_strerror(status)));
     return error;
   }
 
@@ -262,9 +264,10 @@ static grpc_error *add_socket_to_server(grpc_tcp_server *s, uv_tcp_t *handle,
   status = uv_tcp_getsockname(handle, (struct sockaddr *)&sockname_temp.addr,
                               (int *)&sockname_temp.len);
   if (status != 0) {
-    error = GRPC_ERROR_CREATE("getsockname failed");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("getsockname failed");
     error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, uv_strerror(status));
+        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                           grpc_slice_from_static_string(uv_strerror(status)));
     return error;
   }
 
@@ -346,15 +349,17 @@ grpc_error *grpc_tcp_server_add_port(grpc_tcp_server *s,
   if (status == 0) {
     error = add_socket_to_server(s, handle, addr, port_index, &sp);
   } else {
-    error = GRPC_ERROR_CREATE("Failed to initialize UV tcp handle");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Failed to initialize UV tcp handle");
     error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, uv_strerror(status));
+        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                           grpc_slice_from_static_string(uv_strerror(status)));
   }
 
   gpr_free(allocated_addr);
 
   if (error != GRPC_ERROR_NONE) {
-    grpc_error *error_out = GRPC_ERROR_CREATE_REFERENCING(
+    grpc_error *error_out = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
         "Failed to add port to server", &error, 1);
     GRPC_ERROR_UNREF(error);
     error = error_out;
diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c
index bd4b9b2df11856bf966e6ea49e5b762b6c7b9a04..4c17f08918b1ec86c7568a08fb2233276eeb161b 100644
--- a/src/core/lib/iomgr/tcp_server_windows.c
+++ b/src/core/lib/iomgr/tcp_server_windows.c
@@ -46,6 +46,7 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
 
+#include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/iocp_windows.h"
 #include "src/core/lib/iomgr/pollset_windows.h"
 #include "src/core/lib/iomgr/resolve_address.h"
@@ -102,7 +103,7 @@ struct grpc_tcp_server {
   /* shutdown callback */
   grpc_closure *shutdown_complete;
 
-  grpc_resource_quota *resource_quota;
+  grpc_channel_args *channel_args;
 };
 
 /* Public function. Allocates the proper data structures to hold a
@@ -112,21 +113,7 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
                                    const grpc_channel_args *args,
                                    grpc_tcp_server **server) {
   grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
-  s->resource_quota = grpc_resource_quota_create(NULL);
-  for (size_t i = 0; i < (args == NULL ? 0 : args->num_args); i++) {
-    if (0 == strcmp(GRPC_ARG_RESOURCE_QUOTA, args->args[i].key)) {
-      if (args->args[i].type == GRPC_ARG_POINTER) {
-        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
-        s->resource_quota =
-            grpc_resource_quota_ref_internal(args->args[i].value.pointer.p);
-      } else {
-        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
-        gpr_free(s);
-        return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
-                                 " must be a pointer to a buffer pool");
-      }
-    }
-  }
+  s->channel_args = grpc_channel_args_copy(args);
   gpr_ref_init(&s->refs, 1);
   gpr_mu_init(&s->mu);
   s->active_ports = 0;
@@ -155,7 +142,7 @@ static void destroy_server(grpc_exec_ctx *exec_ctx, void *arg,
     grpc_winsocket_destroy(sp->socket);
     gpr_free(sp);
   }
-  grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
+  grpc_channel_args_destroy(exec_ctx, s->channel_args);
   gpr_free(s);
 }
 
@@ -248,9 +235,10 @@ failure:
   GPR_ASSERT(error != GRPC_ERROR_NONE);
   char *tgtaddr = grpc_sockaddr_to_uri(addr);
   grpc_error_set_int(
-      grpc_error_set_str(GRPC_ERROR_CREATE_REFERENCING(
+      grpc_error_set_str(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
                              "Failed to prepare server socket", &error, 1),
-                         GRPC_ERROR_STR_TARGET_ADDRESS, tgtaddr),
+                         GRPC_ERROR_STR_TARGET_ADDRESS,
+                         grpc_slice_from_copied_string(tgtaddr)),
       GRPC_ERROR_INT_FD, (intptr_t)sock);
   gpr_free(tgtaddr);
   GRPC_ERROR_UNREF(error);
@@ -382,8 +370,8 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
         gpr_free(utf8_message);
       }
       gpr_asprintf(&fd_name, "tcp_server:%s", peer_name_string);
-      ep = grpc_tcp_create(grpc_winsocket_create(sock, fd_name),
-                           sp->server->resource_quota, peer_name_string);
+      ep = grpc_tcp_create(exec_ctx, grpc_winsocket_create(sock, fd_name),
+                           sp->server->channel_args, peer_name_string);
       gpr_free(fd_name);
       gpr_free(peer_name_string);
     } else {
@@ -533,7 +521,7 @@ done:
   gpr_free(allocated_addr);
 
   if (error != GRPC_ERROR_NONE) {
-    grpc_error *error_out = GRPC_ERROR_CREATE_REFERENCING(
+    grpc_error *error_out = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
         "Failed to add port to server", &error, 1);
     GRPC_ERROR_UNREF(error);
     error = error_out;
diff --git a/src/core/lib/iomgr/tcp_uv.c b/src/core/lib/iomgr/tcp_uv.c
index 5541c620683677aa9a578d78f6b6a18d8afc478e..8e8db9f7b45b0de81f7187dd50005805c7ed7072 100644
--- a/src/core/lib/iomgr/tcp_uv.c
+++ b/src/core/lib/iomgr/tcp_uv.c
@@ -152,7 +152,7 @@ static void read_callback(uv_stream_t *stream, ssize_t nread,
   // TODO(murgatroid99): figure out what the return value here means
   uv_read_stop(stream);
   if (nread == UV_EOF) {
-    error = GRPC_ERROR_CREATE("EOF");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("EOF");
   } else if (nread > 0) {
     // Successful read
     sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, (size_t)nread);
@@ -173,7 +173,7 @@ static void read_callback(uv_stream_t *stream, ssize_t nread,
     }
   } else {
     // nread < 0: Error
-    error = GRPC_ERROR_CREATE("TCP Read failed");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("TCP Read failed");
   }
   grpc_closure_sched(&exec_ctx, cb, error);
   grpc_exec_ctx_finish(&exec_ctx);
@@ -193,9 +193,10 @@ static void uv_endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   status =
       uv_read_start((uv_stream_t *)tcp->handle, alloc_uv_buf, read_callback);
   if (status != 0) {
-    error = GRPC_ERROR_CREATE("TCP Read failed at start");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("TCP Read failed at start");
     error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, uv_strerror(status));
+        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                           grpc_slice_from_static_string(uv_strerror(status)));
     grpc_closure_sched(exec_ctx, cb, error);
   }
   if (grpc_tcp_trace) {
@@ -214,7 +215,7 @@ static void write_callback(uv_write_t *req, int status) {
   if (status == 0) {
     error = GRPC_ERROR_NONE;
   } else {
-    error = GRPC_ERROR_CREATE("TCP Write failed");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("TCP Write failed");
   }
   if (grpc_tcp_trace) {
     const char *str = grpc_error_string(error);
@@ -249,8 +250,8 @@ static void uv_endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   }
 
   if (tcp->shutting_down) {
-    grpc_closure_sched(exec_ctx, cb,
-                       GRPC_ERROR_CREATE("TCP socket is shutting down"));
+    grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                         "TCP socket is shutting down"));
     return;
   }
 
diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c
index 6c413971e33d26bd4ad56474a7be9591ac683cd5..bdd4dd07afc0c103327ca5b3794b828b354cffd2 100644
--- a/src/core/lib/iomgr/tcp_windows.c
+++ b/src/core/lib/iomgr/tcp_windows.c
@@ -175,7 +175,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *tcpp, grpc_error *error) {
   if (error == GRPC_ERROR_NONE) {
     if (info->wsa_error != 0 && !tcp->shutting_down) {
       char *utf8_message = gpr_format_message(info->wsa_error);
-      error = GRPC_ERROR_CREATE(utf8_message);
+      error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(utf8_message);
       gpr_free(utf8_message);
       grpc_slice_unref_internal(exec_ctx, tcp->read_slice);
     } else {
@@ -185,9 +185,9 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *tcpp, grpc_error *error) {
       } else {
         grpc_slice_unref_internal(exec_ctx, tcp->read_slice);
         error = tcp->shutting_down
-                    ? GRPC_ERROR_CREATE_REFERENCING("TCP stream shutting down",
-                                                    &tcp->shutdown_error, 1)
-                    : GRPC_ERROR_CREATE("End of TCP stream");
+                    ? GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                          "TCP stream shutting down", &tcp->shutdown_error, 1)
+                    : GRPC_ERROR_CREATE_FROM_STATIC_STRING("End of TCP stream");
       }
     }
   }
@@ -208,9 +208,10 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   WSABUF buffer;
 
   if (tcp->shutting_down) {
-    grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_CREATE_REFERENCING(
-                                         "TCP socket is shutting down",
-                                         &tcp->shutdown_error, 1));
+    grpc_closure_sched(
+        exec_ctx, cb,
+        GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+            "TCP socket is shutting down", &tcp->shutdown_error, 1));
     return;
   }
 
@@ -218,7 +219,7 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   tcp->read_slices = read_slices;
   grpc_slice_buffer_reset_and_unref_internal(exec_ctx, read_slices);
 
-  tcp->read_slice = grpc_slice_malloc(8192);
+  tcp->read_slice = GRPC_SLICE_MALLOC(8192);
 
   buffer.len = (ULONG)GRPC_SLICE_LENGTH(
       tcp->read_slice);  // we know slice size fits in 32bit.
@@ -297,9 +298,10 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   size_t len;
 
   if (tcp->shutting_down) {
-    grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_CREATE_REFERENCING(
-                                         "TCP socket is shutting down",
-                                         &tcp->shutdown_error, 1));
+    grpc_closure_sched(
+        exec_ctx, cb,
+        GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+            "TCP socket is shutting down", &tcp->shutdown_error, 1));
     return;
   }
 
@@ -428,9 +430,19 @@ static grpc_endpoint_vtable vtable = {win_read,
                                       win_get_peer,
                                       win_get_fd};
 
-grpc_endpoint *grpc_tcp_create(grpc_winsocket *socket,
-                               grpc_resource_quota *resource_quota,
+grpc_endpoint *grpc_tcp_create(grpc_exec_ctx *exec_ctx, grpc_winsocket *socket,
+                               grpc_channel_args *channel_args,
                                char *peer_string) {
+  grpc_resource_quota *resource_quota = grpc_resource_quota_create(NULL);
+  if (channel_args != NULL) {
+    for (size_t i = 0; i < channel_args->num_args; i++) {
+      if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
+        grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
+        resource_quota = grpc_resource_quota_ref_internal(
+            channel_args->args[i].value.pointer.p);
+      }
+    }
+  }
   grpc_tcp *tcp = (grpc_tcp *)gpr_malloc(sizeof(grpc_tcp));
   memset(tcp, 0, sizeof(grpc_tcp));
   tcp->base.vtable = &vtable;
diff --git a/src/core/lib/iomgr/tcp_windows.h b/src/core/lib/iomgr/tcp_windows.h
index 4402de1c385290eaed1839546571ab04c5223313..abafdb22d202292c84628e390e7c6dfbe16474ec 100644
--- a/src/core/lib/iomgr/tcp_windows.h
+++ b/src/core/lib/iomgr/tcp_windows.h
@@ -50,8 +50,8 @@
 /* Create a tcp endpoint given a winsock handle.
  * Takes ownership of the handle.
  */
-grpc_endpoint *grpc_tcp_create(grpc_winsocket *socket,
-                               grpc_resource_quota *resource_quota,
+grpc_endpoint *grpc_tcp_create(grpc_exec_ctx *exec_ctx, grpc_winsocket *socket,
+                               grpc_channel_args *channel_args,
                                char *peer_string);
 
 grpc_error *grpc_tcp_prepare_socket(SOCKET sock);
diff --git a/src/core/lib/iomgr/timer.h b/src/core/lib/iomgr/timer.h
index d84a278b183d2c2dc95af3faa7ab053e84c661ca..e0338f93c7d6f7a41a88ff4c823e68821ee59e58 100644
--- a/src/core/lib/iomgr/timer.h
+++ b/src/core/lib/iomgr/timer.h
@@ -101,6 +101,9 @@ bool grpc_timer_check(grpc_exec_ctx *exec_ctx, gpr_timespec now,
 void grpc_timer_list_init(gpr_timespec now);
 void grpc_timer_list_shutdown(grpc_exec_ctx *exec_ctx);
 
+/* Consume a kick issued by grpc_kick_poller */
+void grpc_timer_consume_kick(void);
+
 /* the following must be implemented by each iomgr implementation */
 
 void grpc_kick_poller(void);
diff --git a/src/core/lib/iomgr/timer_generic.c b/src/core/lib/iomgr/timer_generic.c
index d4df96c214def63294dd4a1908884fde950db74a..d8e60684312bda411aed4c2e5fa73336109ab2f8 100644
--- a/src/core/lib/iomgr/timer_generic.c
+++ b/src/core/lib/iomgr/timer_generic.c
@@ -37,9 +37,13 @@
 
 #include "src/core/lib/iomgr/timer.h"
 
+#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
 #include <grpc/support/sync.h>
+#include <grpc/support/tls.h>
 #include <grpc/support/useful.h>
+#include "src/core/lib/debug/trace.h"
 #include "src/core/lib/iomgr/time_averaged_stats.h"
 #include "src/core/lib/iomgr/timer_heap.h"
 #include "src/core/lib/support/spinlock.h"
@@ -52,12 +56,15 @@
 #define MIN_QUEUE_WINDOW_DURATION 0.01
 #define MAX_QUEUE_WINDOW_DURATION 1
 
+int grpc_timer_trace = 0;
+int grpc_timer_check_trace = 0;
+
 typedef struct {
   gpr_mu mu;
   grpc_time_averaged_stats stats;
   /* All and only timers with deadlines <= this will be in the heap. */
-  gpr_timespec queue_deadline_cap;
-  gpr_timespec min_deadline;
+  gpr_atm queue_deadline_cap;
+  gpr_atm min_deadline;
   /* Index in the g_shard_queue */
   uint32_t shard_queue_index;
   /* This holds all timers with deadlines < queue_deadline_cap. Timers in this
@@ -67,38 +74,92 @@ typedef struct {
   grpc_timer list;
 } shard_type;
 
-/* Protects g_shard_queue */
-static gpr_mu g_mu;
-/* Allow only one run_some_expired_timers at once */
-static gpr_spinlock g_checker_mu = GPR_SPINLOCK_STATIC_INITIALIZER;
+struct shared_mutables {
+  gpr_atm min_timer;
+  /* Allow only one run_some_expired_timers at once */
+  gpr_spinlock checker_mu;
+  bool initialized;
+  /* Protects g_shard_queue */
+  gpr_mu mu;
+} GPR_ALIGN_STRUCT(GPR_CACHELINE_SIZE);
+
+static struct shared_mutables g_shared_mutables = {
+    .checker_mu = GPR_SPINLOCK_STATIC_INITIALIZER, .initialized = false,
+};
 static gpr_clock_type g_clock_type;
 static shard_type g_shards[NUM_SHARDS];
-/* Protected by g_mu */
+/* Protected by g_shared_mutables.mu */
 static shard_type *g_shard_queue[NUM_SHARDS];
-static bool g_initialized = false;
+static gpr_timespec g_start_time;
+
+GPR_TLS_DECL(g_last_seen_min_timer);
+
+static gpr_atm saturating_add(gpr_atm a, gpr_atm b) {
+  if (a > GPR_ATM_MAX - b) {
+    return GPR_ATM_MAX;
+  }
+  return a + b;
+}
+
+static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_atm now,
+                                   gpr_atm *next, grpc_error *error);
+
+static gpr_timespec dbl_to_ts(double d) {
+  gpr_timespec ts;
+  ts.tv_sec = (int64_t)d;
+  ts.tv_nsec = (int32_t)(1e9 * (d - (double)ts.tv_sec));
+  ts.clock_type = GPR_TIMESPAN;
+  return ts;
+}
+
+static gpr_atm timespec_to_atm_round_up(gpr_timespec ts) {
+  ts = gpr_time_sub(ts, g_start_time);
+  double x = GPR_MS_PER_SEC * (double)ts.tv_sec +
+             (double)ts.tv_nsec / GPR_NS_PER_MS +
+             (double)(GPR_NS_PER_SEC - 1) / (double)GPR_NS_PER_SEC;
+  if (x < 0) return 0;
+  if (x > GPR_ATM_MAX) return GPR_ATM_MAX;
+  return (gpr_atm)x;
+}
+
+static gpr_atm timespec_to_atm_round_down(gpr_timespec ts) {
+  ts = gpr_time_sub(ts, g_start_time);
+  double x =
+      GPR_MS_PER_SEC * (double)ts.tv_sec + (double)ts.tv_nsec / GPR_NS_PER_MS;
+  if (x < 0) return 0;
+  if (x > GPR_ATM_MAX) return GPR_ATM_MAX;
+  return (gpr_atm)x;
+}
 
-static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_timespec now,
-                                   gpr_timespec *next, grpc_error *error);
+static gpr_timespec atm_to_timespec(gpr_atm x) {
+  return gpr_time_add(g_start_time, dbl_to_ts((double)x / 1000.0));
+}
 
-static gpr_timespec compute_min_deadline(shard_type *shard) {
+static gpr_atm compute_min_deadline(shard_type *shard) {
   return grpc_timer_heap_is_empty(&shard->heap)
-             ? shard->queue_deadline_cap
+             ? saturating_add(shard->queue_deadline_cap, 1)
              : grpc_timer_heap_top(&shard->heap)->deadline;
 }
 
 void grpc_timer_list_init(gpr_timespec now) {
   uint32_t i;
 
-  g_initialized = true;
-  gpr_mu_init(&g_mu);
+  g_shared_mutables.initialized = true;
+  gpr_mu_init(&g_shared_mutables.mu);
   g_clock_type = now.clock_type;
+  g_start_time = now;
+  g_shared_mutables.min_timer = timespec_to_atm_round_down(now);
+  gpr_tls_init(&g_last_seen_min_timer);
+  gpr_tls_set(&g_last_seen_min_timer, 0);
+  grpc_register_tracer("timer", &grpc_timer_trace);
+  grpc_register_tracer("timer_check", &grpc_timer_check_trace);
 
   for (i = 0; i < NUM_SHARDS; i++) {
     shard_type *shard = &g_shards[i];
     gpr_mu_init(&shard->mu);
     grpc_time_averaged_stats_init(&shard->stats, 1.0 / ADD_DEADLINE_SCALE, 0.1,
                                   0.5);
-    shard->queue_deadline_cap = now;
+    shard->queue_deadline_cap = g_shared_mutables.min_timer;
     shard->shard_queue_index = i;
     grpc_timer_heap_init(&shard->heap);
     shard->list.next = shard->list.prev = &shard->list;
@@ -109,29 +170,24 @@ void grpc_timer_list_init(gpr_timespec now) {
 
 void grpc_timer_list_shutdown(grpc_exec_ctx *exec_ctx) {
   int i;
-  run_some_expired_timers(exec_ctx, gpr_inf_future(g_clock_type), NULL,
-                          GRPC_ERROR_CREATE("Timer list shutdown"));
+  run_some_expired_timers(
+      exec_ctx, GPR_ATM_MAX, NULL,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Timer list shutdown"));
   for (i = 0; i < NUM_SHARDS; i++) {
     shard_type *shard = &g_shards[i];
     gpr_mu_destroy(&shard->mu);
     grpc_timer_heap_destroy(&shard->heap);
   }
-  gpr_mu_destroy(&g_mu);
-  g_initialized = false;
+  gpr_mu_destroy(&g_shared_mutables.mu);
+  gpr_tls_destroy(&g_last_seen_min_timer);
+  g_shared_mutables.initialized = false;
 }
 
 static double ts_to_dbl(gpr_timespec ts) {
   return (double)ts.tv_sec + 1e-9 * ts.tv_nsec;
 }
 
-static gpr_timespec dbl_to_ts(double d) {
-  gpr_timespec ts;
-  ts.tv_sec = (int64_t)d;
-  ts.tv_nsec = (int32_t)(1e9 * (d - (double)ts.tv_sec));
-  ts.clock_type = GPR_TIMESPAN;
-  return ts;
-}
-
+/* returns true if the first element in the list */
 static void list_join(grpc_timer *head, grpc_timer *timer) {
   timer->next = head;
   timer->prev = head->prev;
@@ -157,15 +213,13 @@ static void swap_adjacent_shards_in_queue(uint32_t first_shard_queue_index) {
 
 static void note_deadline_change(shard_type *shard) {
   while (shard->shard_queue_index > 0 &&
-         gpr_time_cmp(
-             shard->min_deadline,
-             g_shard_queue[shard->shard_queue_index - 1]->min_deadline) < 0) {
+         shard->min_deadline <
+             g_shard_queue[shard->shard_queue_index - 1]->min_deadline) {
     swap_adjacent_shards_in_queue(shard->shard_queue_index - 1);
   }
   while (shard->shard_queue_index < NUM_SHARDS - 1 &&
-         gpr_time_cmp(
-             shard->min_deadline,
-             g_shard_queue[shard->shard_queue_index + 1]->min_deadline) > 0) {
+         shard->min_deadline >
+             g_shard_queue[shard->shard_queue_index + 1]->min_deadline) {
     swap_adjacent_shards_in_queue(shard->shard_queue_index);
   }
 }
@@ -178,13 +232,21 @@ void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
   GPR_ASSERT(deadline.clock_type == g_clock_type);
   GPR_ASSERT(now.clock_type == g_clock_type);
   timer->closure = closure;
-  timer->deadline = deadline;
+  timer->deadline = timespec_to_atm_round_up(deadline);
+
+  if (grpc_timer_trace) {
+    gpr_log(GPR_DEBUG, "TIMER %p: SET %" PRId64 ".%09d [%" PRIdPTR
+                       "] now %" PRId64 ".%09d [%" PRIdPTR "] call %p[%p]",
+            timer, deadline.tv_sec, deadline.tv_nsec, timer->deadline,
+            now.tv_sec, now.tv_nsec, timespec_to_atm_round_down(now), closure,
+            closure->cb);
+  }
 
-  if (!g_initialized) {
+  if (!g_shared_mutables.initialized) {
     timer->pending = false;
-    grpc_closure_sched(
-        exec_ctx, timer->closure,
-        GRPC_ERROR_CREATE("Attempt to create timer before initialization"));
+    grpc_closure_sched(exec_ctx, timer->closure,
+                       GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                           "Attempt to create timer before initialization"));
     return;
   }
 
@@ -200,12 +262,18 @@ void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
 
   grpc_time_averaged_stats_add_sample(&shard->stats,
                                       ts_to_dbl(gpr_time_sub(deadline, now)));
-  if (gpr_time_cmp(deadline, shard->queue_deadline_cap) < 0) {
+  if (timer->deadline < shard->queue_deadline_cap) {
     is_first_timer = grpc_timer_heap_add(&shard->heap, timer);
   } else {
     timer->heap_index = INVALID_HEAP_INDEX;
     list_join(&shard->list, timer);
   }
+  if (grpc_timer_trace) {
+    gpr_log(GPR_DEBUG, "  .. add to shard %d with queue_deadline_cap=%" PRIdPTR
+                       " => is_first_timer=%s",
+            (int)(shard - g_shards), shard->queue_deadline_cap,
+            is_first_timer ? "true" : "false");
+  }
   gpr_mu_unlock(&shard->mu);
 
   /* Deadline may have decreased, we need to adjust the master queue.  Note
@@ -220,28 +288,41 @@ void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
      In that case, the timer will simply have to wait for the next
      grpc_timer_check. */
   if (is_first_timer) {
-    gpr_mu_lock(&g_mu);
-    if (gpr_time_cmp(deadline, shard->min_deadline) < 0) {
-      gpr_timespec old_min_deadline = g_shard_queue[0]->min_deadline;
-      shard->min_deadline = deadline;
+    gpr_mu_lock(&g_shared_mutables.mu);
+    if (grpc_timer_trace) {
+      gpr_log(GPR_DEBUG, "  .. old shard min_deadline=%" PRIdPTR,
+              shard->min_deadline);
+    }
+    if (timer->deadline < shard->min_deadline) {
+      gpr_atm old_min_deadline = g_shard_queue[0]->min_deadline;
+      shard->min_deadline = timer->deadline;
       note_deadline_change(shard);
-      if (shard->shard_queue_index == 0 &&
-          gpr_time_cmp(deadline, old_min_deadline) < 0) {
+      if (shard->shard_queue_index == 0 && timer->deadline < old_min_deadline) {
+        gpr_atm_no_barrier_store(&g_shared_mutables.min_timer, timer->deadline);
         grpc_kick_poller();
       }
     }
-    gpr_mu_unlock(&g_mu);
+    gpr_mu_unlock(&g_shared_mutables.mu);
   }
 }
 
+void grpc_timer_consume_kick(void) {
+  /* force re-evaluation of last seeen min */
+  gpr_tls_set(&g_last_seen_min_timer, 0);
+}
+
 void grpc_timer_cancel(grpc_exec_ctx *exec_ctx, grpc_timer *timer) {
-  if (!g_initialized) {
+  if (!g_shared_mutables.initialized) {
     /* must have already been cancelled, also the shard mutex is invalid */
     return;
   }
 
   shard_type *shard = &g_shards[GPR_HASH_POINTER(timer, NUM_SHARDS)];
   gpr_mu_lock(&shard->mu);
+  if (grpc_timer_trace) {
+    gpr_log(GPR_DEBUG, "TIMER %p: CANCEL pending=%s", timer,
+            timer->pending ? "true" : "false");
+  }
   if (timer->pending) {
     grpc_closure_sched(exec_ctx, timer->closure, GRPC_ERROR_CANCELLED);
     timer->pending = false;
@@ -259,7 +340,7 @@ void grpc_timer_cancel(grpc_exec_ctx *exec_ctx, grpc_timer *timer) {
    for timers that fall at or under it.  Returns true if the queue is no
    longer empty.
    REQUIRES: shard->mu locked */
-static int refill_queue(shard_type *shard, gpr_timespec now) {
+static int refill_queue(shard_type *shard, gpr_atm now) {
   /* Compute the new queue window width and bound by the limits: */
   double computed_deadline_delta =
       grpc_time_averaged_stats_update_average(&shard->stats) *
@@ -270,12 +351,22 @@ static int refill_queue(shard_type *shard, gpr_timespec now) {
   grpc_timer *timer, *next;
 
   /* Compute the new cap and put all timers under it into the queue: */
-  shard->queue_deadline_cap = gpr_time_add(
-      gpr_time_max(now, shard->queue_deadline_cap), dbl_to_ts(deadline_delta));
+  shard->queue_deadline_cap =
+      saturating_add(GPR_MAX(now, shard->queue_deadline_cap),
+                     (gpr_atm)(deadline_delta * 1000.0));
+
+  if (grpc_timer_check_trace) {
+    gpr_log(GPR_DEBUG, "  .. shard[%d]->queue_deadline_cap --> %" PRIdPTR,
+            (int)(shard - g_shards), shard->queue_deadline_cap);
+  }
   for (timer = shard->list.next; timer != &shard->list; timer = next) {
     next = timer->next;
 
-    if (gpr_time_cmp(timer->deadline, shard->queue_deadline_cap) < 0) {
+    if (timer->deadline < shard->queue_deadline_cap) {
+      if (grpc_timer_check_trace) {
+        gpr_log(GPR_DEBUG, "  .. add timer with deadline %" PRIdPTR " to heap",
+                timer->deadline);
+      }
       list_remove(timer);
       grpc_timer_heap_add(&shard->heap, timer);
     }
@@ -286,15 +377,29 @@ static int refill_queue(shard_type *shard, gpr_timespec now) {
 /* This pops the next non-cancelled timer with deadline <= now from the
    queue, or returns NULL if there isn't one.
    REQUIRES: shard->mu locked */
-static grpc_timer *pop_one(shard_type *shard, gpr_timespec now) {
+static grpc_timer *pop_one(shard_type *shard, gpr_atm now) {
   grpc_timer *timer;
   for (;;) {
+    if (grpc_timer_check_trace) {
+      gpr_log(GPR_DEBUG, "  .. shard[%d]: heap_empty=%s",
+              (int)(shard - g_shards),
+              grpc_timer_heap_is_empty(&shard->heap) ? "true" : "false");
+    }
     if (grpc_timer_heap_is_empty(&shard->heap)) {
-      if (gpr_time_cmp(now, shard->queue_deadline_cap) < 0) return NULL;
+      if (now < shard->queue_deadline_cap) return NULL;
       if (!refill_queue(shard, now)) return NULL;
     }
     timer = grpc_timer_heap_top(&shard->heap);
-    if (gpr_time_cmp(timer->deadline, now) > 0) return NULL;
+    if (grpc_timer_check_trace) {
+      gpr_log(GPR_DEBUG,
+              "  .. check top timer deadline=%" PRIdPTR " now=%" PRIdPTR,
+              timer->deadline, now);
+    }
+    if (timer->deadline > now) return NULL;
+    if (grpc_timer_trace) {
+      gpr_log(GPR_DEBUG, "TIMER %p: FIRE %" PRIdPTR "ms late", timer,
+              now - timer->deadline);
+    }
     timer->pending = false;
     grpc_timer_heap_pop(&shard->heap);
     return timer;
@@ -303,7 +408,7 @@ static grpc_timer *pop_one(shard_type *shard, gpr_timespec now) {
 
 /* REQUIRES: shard->mu unlocked */
 static size_t pop_timers(grpc_exec_ctx *exec_ctx, shard_type *shard,
-                         gpr_timespec now, gpr_timespec *new_min_deadline,
+                         gpr_atm now, gpr_atm *new_min_deadline,
                          grpc_error *error) {
   size_t n = 0;
   grpc_timer *timer;
@@ -317,17 +422,29 @@ static size_t pop_timers(grpc_exec_ctx *exec_ctx, shard_type *shard,
   return n;
 }
 
-static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_timespec now,
-                                   gpr_timespec *next, grpc_error *error) {
+static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_atm now,
+                                   gpr_atm *next, grpc_error *error) {
   size_t n = 0;
 
-  /* TODO(ctiller): verify that there are any timers (atomically) here */
+  gpr_atm min_timer = gpr_atm_no_barrier_load(&g_shared_mutables.min_timer);
+  gpr_tls_set(&g_last_seen_min_timer, min_timer);
+  if (now < min_timer) {
+    if (next != NULL) *next = GPR_MIN(*next, min_timer);
+    return 0;
+  }
 
-  if (gpr_spinlock_trylock(&g_checker_mu)) {
-    gpr_mu_lock(&g_mu);
+  if (gpr_spinlock_trylock(&g_shared_mutables.checker_mu)) {
+    gpr_mu_lock(&g_shared_mutables.mu);
 
-    while (gpr_time_cmp(g_shard_queue[0]->min_deadline, now) < 0) {
-      gpr_timespec new_min_deadline;
+    if (grpc_timer_check_trace) {
+      gpr_log(GPR_DEBUG, "  .. shard[%d]->min_deadline = %" PRIdPTR,
+              (int)(g_shard_queue[0] - g_shards),
+              g_shard_queue[0]->min_deadline);
+    }
+
+    while (g_shard_queue[0]->min_deadline < now ||
+           (now != GPR_ATM_MAX && g_shard_queue[0]->min_deadline == now)) {
+      gpr_atm new_min_deadline;
 
       /* For efficiency, we pop as many available timers as we can from the
          shard.  This may violate perfect timer deadline ordering, but that
@@ -335,6 +452,14 @@ static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_timespec now,
       n +=
           pop_timers(exec_ctx, g_shard_queue[0], now, &new_min_deadline, error);
 
+      if (grpc_timer_check_trace) {
+        gpr_log(GPR_DEBUG, "  .. popped --> %" PRIdPTR
+                           ", shard[%d]->min_deadline %" PRIdPTR
+                           " --> %" PRIdPTR ", now=%" PRIdPTR,
+                n, (int)(g_shard_queue[0] - g_shards),
+                g_shard_queue[0]->min_deadline, new_min_deadline, now);
+      }
+
       /* An grpc_timer_init() on the shard could intervene here, adding a new
          timer that is earlier than new_min_deadline.  However,
          grpc_timer_init() will block on the master_lock before it can call
@@ -345,23 +470,24 @@ static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_timespec now,
     }
 
     if (next) {
-      *next = gpr_time_min(*next, g_shard_queue[0]->min_deadline);
+      *next = GPR_MIN(*next, g_shard_queue[0]->min_deadline);
     }
 
-    gpr_mu_unlock(&g_mu);
-    gpr_spinlock_unlock(&g_checker_mu);
+    gpr_atm_no_barrier_store(&g_shared_mutables.min_timer,
+                             g_shard_queue[0]->min_deadline);
+    gpr_mu_unlock(&g_shared_mutables.mu);
+    gpr_spinlock_unlock(&g_shared_mutables.checker_mu);
   } else if (next != NULL) {
     /* TODO(ctiller): this forces calling code to do an short poll, and
        then retry the timer check (because this time through the timer list was
        contended).
 
-       We could reduce the cost here dramatically by keeping a count of how many
-       currently active pollers got through the uncontended case above
+       We could reduce the cost here dramatically by keeping a count of how
+       many currently active pollers got through the uncontended case above
        successfully, and waking up other pollers IFF that count drops to zero.
 
        Once that count is in place, this entire else branch could disappear. */
-    *next = gpr_time_min(
-        *next, gpr_time_add(now, gpr_time_from_millis(1, GPR_TIMESPAN)));
+    *next = GPR_MIN(*next, now + 1);
   }
 
   GRPC_ERROR_UNREF(error);
@@ -371,12 +497,71 @@ static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_timespec now,
 
 bool grpc_timer_check(grpc_exec_ctx *exec_ctx, gpr_timespec now,
                       gpr_timespec *next) {
+  // prelude
   GPR_ASSERT(now.clock_type == g_clock_type);
-  return run_some_expired_timers(
-      exec_ctx, now, next,
+  gpr_atm now_atm = timespec_to_atm_round_down(now);
+
+  /* fetch from a thread-local first: this avoids contention on a globally
+     mutable cacheline in the common case */
+  gpr_atm min_timer = gpr_tls_get(&g_last_seen_min_timer);
+  if (now_atm < min_timer) {
+    if (next != NULL) {
+      *next =
+          atm_to_timespec(GPR_MIN(timespec_to_atm_round_up(*next), min_timer));
+    }
+    if (grpc_timer_check_trace) {
+      gpr_log(GPR_DEBUG,
+              "TIMER CHECK SKIP: now_atm=%" PRIdPTR " min_timer=%" PRIdPTR,
+              now_atm, min_timer);
+    }
+    return 0;
+  }
+
+  grpc_error *shutdown_error =
       gpr_time_cmp(now, gpr_inf_future(now.clock_type)) != 0
           ? GRPC_ERROR_NONE
-          : GRPC_ERROR_CREATE("Shutting down timer system"));
+          : GRPC_ERROR_CREATE_FROM_STATIC_STRING("Shutting down timer system");
+
+  // tracing
+  if (grpc_timer_check_trace) {
+    char *next_str;
+    if (next == NULL) {
+      next_str = gpr_strdup("NULL");
+    } else {
+      gpr_asprintf(&next_str, "%" PRId64 ".%09d [%" PRIdPTR "]", next->tv_sec,
+                   next->tv_nsec, timespec_to_atm_round_down(*next));
+    }
+    gpr_log(GPR_DEBUG, "TIMER CHECK BEGIN: now=%" PRId64 ".%09d [%" PRIdPTR
+                       "] next=%s tls_min=%" PRIdPTR " glob_min=%" PRIdPTR,
+            now.tv_sec, now.tv_nsec, now_atm, next_str,
+            gpr_tls_get(&g_last_seen_min_timer),
+            gpr_atm_no_barrier_load(&g_shared_mutables.min_timer));
+    gpr_free(next_str);
+  }
+  // actual code
+  bool r;
+  gpr_atm next_atm;
+  if (next == NULL) {
+    r = run_some_expired_timers(exec_ctx, now_atm, NULL, shutdown_error);
+  } else {
+    next_atm = timespec_to_atm_round_down(*next);
+    r = run_some_expired_timers(exec_ctx, now_atm, &next_atm, shutdown_error);
+    *next = atm_to_timespec(next_atm);
+  }
+  // tracing
+  if (grpc_timer_check_trace) {
+    char *next_str;
+    if (next == NULL) {
+      next_str = gpr_strdup("NULL");
+    } else {
+      gpr_asprintf(&next_str, "%" PRId64 ".%09d [%" PRIdPTR "]", next->tv_sec,
+                   next->tv_nsec, next_atm);
+    }
+    gpr_log(GPR_DEBUG, "TIMER CHECK END: %d timers triggered; next=%s", r,
+            next_str);
+    gpr_free(next_str);
+  }
+  return r > 0;
 }
 
 #endif /* GRPC_TIMER_USE_GENERIC */
diff --git a/src/core/lib/iomgr/timer_generic.h b/src/core/lib/iomgr/timer_generic.h
index 1608dce9fb1058bf0dadc414538c8a724568e016..c79a431aa034089a21424773df6add9cfbd58163 100644
--- a/src/core/lib/iomgr/timer_generic.h
+++ b/src/core/lib/iomgr/timer_generic.h
@@ -38,7 +38,7 @@
 #include "src/core/lib/iomgr/exec_ctx.h"
 
 struct grpc_timer {
-  gpr_timespec deadline;
+  gpr_atm deadline;
   uint32_t heap_index; /* INVALID_HEAP_INDEX if not in heap */
   bool pending;
   struct grpc_timer *next;
diff --git a/src/core/lib/iomgr/timer_heap.c b/src/core/lib/iomgr/timer_heap.c
index f736d335e6c4aa68948374d0102dc202de0ba675..03ccfe023a55707e0211b095de593da7645c6513 100644
--- a/src/core/lib/iomgr/timer_heap.c
+++ b/src/core/lib/iomgr/timer_heap.c
@@ -50,7 +50,7 @@
 static void adjust_upwards(grpc_timer **first, uint32_t i, grpc_timer *t) {
   while (i > 0) {
     uint32_t parent = (uint32_t)(((int)i - 1) / 2);
-    if (gpr_time_cmp(first[parent]->deadline, t->deadline) <= 0) break;
+    if (first[parent]->deadline <= t->deadline) break;
     first[i] = first[parent];
     first[i]->heap_index = i;
     i = parent;
@@ -68,12 +68,12 @@ static void adjust_downwards(grpc_timer **first, uint32_t i, uint32_t length,
     uint32_t left_child = 1u + 2u * i;
     if (left_child >= length) break;
     uint32_t right_child = left_child + 1;
-    uint32_t next_i = right_child < length &&
-                              gpr_time_cmp(first[left_child]->deadline,
-                                           first[right_child]->deadline) > 0
-                          ? right_child
-                          : left_child;
-    if (gpr_time_cmp(t->deadline, first[next_i]->deadline) <= 0) break;
+    uint32_t next_i =
+        right_child < length &&
+                first[left_child]->deadline > first[right_child]->deadline
+            ? right_child
+            : left_child;
+    if (t->deadline <= first[next_i]->deadline) break;
     first[i] = first[next_i];
     first[i]->heap_index = i;
     i = next_i;
@@ -97,7 +97,7 @@ static void maybe_shrink(grpc_timer_heap *heap) {
 static void note_changed_priority(grpc_timer_heap *heap, grpc_timer *timer) {
   uint32_t i = timer->heap_index;
   uint32_t parent = (uint32_t)(((int)i - 1) / 2);
-  if (gpr_time_cmp(heap->timers[parent]->deadline, timer->deadline) > 0) {
+  if (heap->timers[parent]->deadline > timer->deadline) {
     adjust_upwards(heap->timers, i, timer);
   } else {
     adjust_downwards(heap->timers, i, heap->timer_count, timer);
diff --git a/src/core/lib/iomgr/timer_uv.c b/src/core/lib/iomgr/timer_uv.c
index f28a14405dbb4e18537e53adbf302df6f1befabc..8e8a07578c6a6d693e10e48816d8401e3776174f 100644
--- a/src/core/lib/iomgr/timer_uv.c
+++ b/src/core/lib/iomgr/timer_uv.c
@@ -78,6 +78,10 @@ void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
   uv_timer->data = timer;
   timer->uv_timer = uv_timer;
   uv_timer_start(uv_timer, run_expired_timer, timeout, 0);
+  /* We assume that gRPC timers are only used alongside other active gRPC
+     objects, and that there will therefore always be something else keeping
+     the uv loop alive whenever there is a timer */
+  uv_unref((uv_handle_t *)uv_timer);
 }
 
 void grpc_timer_cancel(grpc_exec_ctx *exec_ctx, grpc_timer *timer) {
diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c
index 2a1c8d39fae1cd08fa58f6e38e1abda33a0c4630..af70746064e476203c74dec3900c8a632252c6d2 100644
--- a/src/core/lib/iomgr/udp_server.c
+++ b/src/core/lib/iomgr/udp_server.c
@@ -59,11 +59,13 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
+#include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/error.h"
 #include "src/core/lib/iomgr/ev_posix.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/sockaddr.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
+#include "src/core/lib/iomgr/socket_factory_posix.h"
 #include "src/core/lib/iomgr/socket_utils_posix.h"
 #include "src/core/lib/iomgr/unix_sockets_posix.h"
 #include "src/core/lib/support/string.h"
@@ -77,18 +79,31 @@ struct grpc_udp_listener {
   grpc_resolved_address addr;
   grpc_closure read_closure;
   grpc_closure write_closure;
+  // To be called when corresponding QuicGrpcServer closes all active
+  // connections.
+  grpc_closure orphan_fd_closure;
   grpc_closure destroyed_closure;
   grpc_udp_server_read_cb read_cb;
   grpc_udp_server_write_cb write_cb;
   grpc_udp_server_orphan_cb orphan_cb;
+  // True if orphan_cb is trigered.
+  bool orphan_notified;
 
   struct grpc_udp_listener *next;
 };
 
+struct shutdown_fd_args {
+  grpc_fd *fd;
+  gpr_mu *server_mu;
+};
+
 /* the overall server */
 struct grpc_udp_server {
   gpr_mu mu;
 
+  /* factory to use for creating and binding sockets, or NULL */
+  grpc_socket_factory *socket_factory;
+
   /* active port count: how many ports are actually still listening */
   size_t active_ports;
   /* destroyed port count: how many ports are completely destroyed */
@@ -109,13 +124,28 @@ struct grpc_udp_server {
   grpc_pollset **pollsets;
   /* number of pollsets in the pollsets array */
   size_t pollset_count;
-  /* The parent grpc server */
-  grpc_server *grpc_server;
+  /* opaque object to pass to callbacks */
+  void *user_data;
 };
 
-grpc_udp_server *grpc_udp_server_create(void) {
+static grpc_socket_factory *get_socket_factory(const grpc_channel_args *args) {
+  if (args) {
+    const grpc_arg *arg = grpc_channel_args_find(args, GRPC_ARG_SOCKET_FACTORY);
+    if (arg) {
+      GPR_ASSERT(arg->type == GRPC_ARG_POINTER);
+      return arg->value.pointer.p;
+    }
+  }
+  return NULL;
+}
+
+grpc_udp_server *grpc_udp_server_create(const grpc_channel_args *args) {
   grpc_udp_server *s = gpr_malloc(sizeof(grpc_udp_server));
   gpr_mu_init(&s->mu);
+  s->socket_factory = get_socket_factory(args);
+  if (s->socket_factory) {
+    grpc_socket_factory_ref(s->socket_factory);
+  }
   s->active_ports = 0;
   s->destroyed_ports = 0;
   s->shutdown = 0;
@@ -126,6 +156,19 @@ grpc_udp_server *grpc_udp_server_create(void) {
   return s;
 }
 
+static void shutdown_fd(grpc_exec_ctx *exec_ctx, void *args,
+                        grpc_error *error) {
+  struct shutdown_fd_args *shutdown_args = (struct shutdown_fd_args *)args;
+  gpr_mu_lock(shutdown_args->server_mu);
+  grpc_fd_shutdown(exec_ctx, shutdown_args->fd, GRPC_ERROR_REF(error));
+  gpr_mu_unlock(shutdown_args->server_mu);
+  gpr_free(shutdown_args);
+}
+
+static void dummy_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+  // No-op.
+}
+
 static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) {
   if (s->shutdown_complete != NULL) {
     grpc_closure_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE);
@@ -139,6 +182,10 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) {
     gpr_free(sp);
   }
 
+  if (s->socket_factory) {
+    grpc_socket_factory_unref(s->socket_factory);
+  }
+
   gpr_free(s);
 }
 
@@ -162,10 +209,7 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) {
   /* delete ALL the things */
   gpr_mu_lock(&s->mu);
 
-  if (!s->shutdown) {
-    gpr_mu_unlock(&s->mu);
-    return;
-  }
+  GPR_ASSERT(s->shutdown);
 
   if (s->head) {
     grpc_udp_listener *sp;
@@ -174,12 +218,16 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) {
 
       grpc_closure_init(&sp->destroyed_closure, destroyed_port, s,
                         grpc_schedule_on_exec_ctx);
-
-      /* Call the orphan_cb to signal that the FD is about to be closed and
-       * should no longer be used. */
-      GPR_ASSERT(sp->orphan_cb);
-      sp->orphan_cb(exec_ctx, sp->emfd);
-
+      if (!sp->orphan_notified) {
+        /* Call the orphan_cb to signal that the FD is about to be closed and
+         * should no longer be used. Because at this point, all listening ports
+         * have been shutdown already, no need to shutdown again.*/
+        grpc_closure_init(&sp->orphan_fd_closure, dummy_cb, sp->emfd,
+                          grpc_schedule_on_exec_ctx);
+        GPR_ASSERT(sp->orphan_cb);
+        sp->orphan_cb(exec_ctx, sp->emfd, &sp->orphan_fd_closure,
+                      sp->server->user_data);
+      }
       grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL,
                      "udp_listener_shutdown");
     }
@@ -204,9 +252,14 @@ void grpc_udp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_udp_server *s,
   if (s->active_ports) {
     for (sp = s->head; sp; sp = sp->next) {
       GPR_ASSERT(sp->orphan_cb);
-      sp->orphan_cb(exec_ctx, sp->emfd);
-      grpc_fd_shutdown(exec_ctx, sp->emfd,
-                       GRPC_ERROR_CREATE("Server destroyed"));
+      struct shutdown_fd_args *args = gpr_malloc(sizeof(*args));
+      args->fd = sp->emfd;
+      args->server_mu = &s->mu;
+      grpc_closure_init(&sp->orphan_fd_closure, shutdown_fd, args,
+                        grpc_schedule_on_exec_ctx);
+      sp->orphan_cb(exec_ctx, sp->emfd, &sp->orphan_fd_closure,
+                    sp->server->user_data);
+      sp->orphan_notified = true;
     }
     gpr_mu_unlock(&s->mu);
   } else {
@@ -215,8 +268,17 @@ void grpc_udp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_udp_server *s,
   }
 }
 
+static int bind_socket(grpc_socket_factory *socket_factory, int sockfd,
+                       const grpc_resolved_address *addr) {
+  return (socket_factory != NULL)
+             ? grpc_socket_factory_bind(socket_factory, sockfd, addr)
+             : bind(sockfd, (struct sockaddr *)addr->addr,
+                    (socklen_t)addr->len);
+}
+
 /* Prepare a recently-created socket for listening. */
-static int prepare_socket(int fd, const grpc_resolved_address *addr) {
+static int prepare_socket(grpc_socket_factory *socket_factory, int fd,
+                          const grpc_resolved_address *addr) {
   grpc_resolved_address sockname_temp;
   struct sockaddr *addr_ptr = (struct sockaddr *)addr->addr;
   /* Set send/receive socket buffers to 1 MB */
@@ -246,7 +308,7 @@ static int prepare_socket(int fd, const grpc_resolved_address *addr) {
   }
 
   GPR_ASSERT(addr->len < ~(socklen_t)0);
-  if (bind(fd, (struct sockaddr *)addr, (socklen_t)addr->len) < 0) {
+  if (bind_socket(socket_factory, fd, addr) < 0) {
     char *addr_str;
     grpc_sockaddr_to_string(&addr_str, addr, 0);
     gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno));
@@ -288,7 +350,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
 
   gpr_mu_lock(&sp->server->mu);
   if (error != GRPC_ERROR_NONE) {
-    if (0 == --sp->server->active_ports) {
+    if (0 == --sp->server->active_ports && sp->server->shutdown) {
       gpr_mu_unlock(&sp->server->mu);
       deactivated_all_ports(exec_ctx, sp->server);
     } else {
@@ -299,7 +361,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
 
   /* Tell the registered callback that data is available to read. */
   GPR_ASSERT(sp->read_cb);
-  sp->read_cb(exec_ctx, sp->emfd, sp->server->grpc_server);
+  sp->read_cb(exec_ctx, sp->emfd, sp->server->user_data);
 
   /* Re-arm the notification event so we get another chance to read. */
   grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
@@ -311,7 +373,7 @@ static void on_write(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
 
   gpr_mu_lock(&(sp->server->mu));
   if (error != GRPC_ERROR_NONE) {
-    if (0 == --sp->server->active_ports) {
+    if (0 == --sp->server->active_ports && sp->server->shutdown) {
       gpr_mu_unlock(&sp->server->mu);
       deactivated_all_ports(exec_ctx, sp->server);
     } else {
@@ -322,7 +384,7 @@ static void on_write(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
 
   /* Tell the registered callback that the socket is writeable. */
   GPR_ASSERT(sp->write_cb);
-  sp->write_cb(exec_ctx, sp->emfd);
+  sp->write_cb(exec_ctx, sp->emfd, sp->server->user_data);
 
   /* Re-arm the notification event so we get another chance to write. */
   grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure);
@@ -339,7 +401,7 @@ static int add_socket_to_server(grpc_udp_server *s, int fd,
   char *addr_str;
   char *name;
 
-  port = prepare_socket(fd, addr);
+  port = prepare_socket(s->socket_factory, fd, addr);
   if (port >= 0) {
     grpc_sockaddr_to_string(&addr_str, addr, 1);
     gpr_asprintf(&name, "udp-server-listener:%s", addr_str);
@@ -361,6 +423,7 @@ static int add_socket_to_server(grpc_udp_server *s, int fd,
     sp->read_cb = read_cb;
     sp->write_cb = write_cb;
     sp->orphan_cb = orphan_cb;
+    sp->orphan_notified = false;
     GPR_ASSERT(sp->emfd);
     gpr_mu_unlock(&s->mu);
     gpr_free(name);
@@ -417,8 +480,8 @@ int grpc_udp_server_add_port(grpc_udp_server *s,
     /* Try listening on IPv6 first. */
     addr = &wild6;
     // TODO(rjshade): Test and propagate the returned grpc_error*:
-    GRPC_ERROR_UNREF(grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP,
-                                                  &dsmode, &fd));
+    GRPC_ERROR_UNREF(grpc_create_dualstack_socket_using_factory(
+        s->socket_factory, addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode, &fd));
     allocated_port1 =
         add_socket_to_server(s, fd, addr, read_cb, write_cb, orphan_cb);
     if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
@@ -433,8 +496,8 @@ int grpc_udp_server_add_port(grpc_udp_server *s,
   }
 
   // TODO(rjshade): Test and propagate the returned grpc_error*:
-  GRPC_ERROR_UNREF(grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP,
-                                                &dsmode, &fd));
+  GRPC_ERROR_UNREF(grpc_create_dualstack_socket_using_factory(
+      s->socket_factory, addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode, &fd));
   if (fd < 0) {
     gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno));
   }
@@ -464,13 +527,13 @@ int grpc_udp_server_get_fd(grpc_udp_server *s, unsigned port_index) {
 
 void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *s,
                            grpc_pollset **pollsets, size_t pollset_count,
-                           grpc_server *server) {
+                           void *user_data) {
   size_t i;
   gpr_mu_lock(&s->mu);
   grpc_udp_listener *sp;
   GPR_ASSERT(s->active_ports == 0);
   s->pollsets = pollsets;
-  s->grpc_server = server;
+  s->user_data = user_data;
 
   sp = s->head;
   while (sp != NULL) {
@@ -485,7 +548,11 @@ void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *s,
                       grpc_schedule_on_exec_ctx);
     grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure);
 
-    s->active_ports++;
+    /* Registered for both read and write callbacks: increment active_ports
+     * twice to account for this, and delay free-ing of memory until both
+     * on_read and on_write have fired. */
+    s->active_ports += 2;
+
     sp = sp->next;
   }
 
diff --git a/src/core/lib/iomgr/udp_server.h b/src/core/lib/iomgr/udp_server.h
index ed63fa7d817b4d8eb6bd26c376d75e8f09b2cea9..8006037644d44950f9bcbf94f567db91f7ae3296 100644
--- a/src/core/lib/iomgr/udp_server.h
+++ b/src/core/lib/iomgr/udp_server.h
@@ -47,23 +47,25 @@ typedef struct grpc_udp_server grpc_udp_server;
 
 /* Called when data is available to read from the socket. */
 typedef void (*grpc_udp_server_read_cb)(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
-                                        struct grpc_server *server);
+                                        void *user_data);
 
 /* Called when the socket is writeable. */
-typedef void (*grpc_udp_server_write_cb)(grpc_exec_ctx *exec_ctx,
-                                         grpc_fd *emfd);
+typedef void (*grpc_udp_server_write_cb)(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
+                                         void *user_data);
 
 /* Called when the grpc_fd is about to be orphaned (and the FD closed). */
 typedef void (*grpc_udp_server_orphan_cb)(grpc_exec_ctx *exec_ctx,
-                                          grpc_fd *emfd);
+                                          grpc_fd *emfd,
+                                          grpc_closure *shutdown_fd_callback,
+                                          void *user_data);
 
 /* Create a server, initially not bound to any ports */
-grpc_udp_server *grpc_udp_server_create(void);
+grpc_udp_server *grpc_udp_server_create(const grpc_channel_args *args);
 
-/* Start listening to bound ports */
+/* Start listening to bound ports. user_data is passed to callbacks. */
 void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *udp_server,
                            grpc_pollset **pollsets, size_t pollset_count,
-                           struct grpc_server *server);
+                           void *user_data);
 
 int grpc_udp_server_get_fd(grpc_udp_server *s, unsigned port_index);
 
diff --git a/src/core/lib/iomgr/unix_sockets_posix.c b/src/core/lib/iomgr/unix_sockets_posix.c
index 1233cec04e53b7b0dc0defd7d6e21a056ed34be7..281865aecee6b0e849b8b2c68d435b0c210100af 100644
--- a/src/core/lib/iomgr/unix_sockets_posix.c
+++ b/src/core/lib/iomgr/unix_sockets_posix.c
@@ -60,7 +60,7 @@ grpc_error *grpc_resolve_unix_domain_address(const char *name,
     gpr_asprintf(&err_msg,
                  "Path name should not have more than %" PRIuPTR " characters.",
                  GPR_ARRAY_SIZE(un->sun_path) - 1);
-    err = GRPC_ERROR_CREATE(err_msg);
+    err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(err_msg);
     gpr_free(err_msg);
     return err;
   }
diff --git a/src/core/lib/iomgr/unix_sockets_posix_noop.c b/src/core/lib/iomgr/unix_sockets_posix_noop.c
index 1daf5152c17b50dec25553909e8df035a5a4c778..b9602cbf8b2f1e703f3cdcc0db8c5f2516068c97 100644
--- a/src/core/lib/iomgr/unix_sockets_posix_noop.c
+++ b/src/core/lib/iomgr/unix_sockets_posix_noop.c
@@ -47,7 +47,8 @@ void grpc_create_socketpair_if_unix(int sv[2]) {
 grpc_error *grpc_resolve_unix_domain_address(
     const char *name, grpc_resolved_addresses **addresses) {
   *addresses = NULL;
-  return GRPC_ERROR_CREATE("Unix domain sockets are not supported on Windows");
+  return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+      "Unix domain sockets are not supported on Windows");
 }
 
 int grpc_is_unix_socket(const grpc_resolved_address *addr) { return false; }
diff --git a/src/core/lib/iomgr/wakeup_fd_posix.h b/src/core/lib/iomgr/wakeup_fd_posix.h
index 71d32d97ba778da4b01fb5ea36ec482daec19a4b..c8dd242c753b348d8dee338c15288c695225730d 100644
--- a/src/core/lib/iomgr/wakeup_fd_posix.h
+++ b/src/core/lib/iomgr/wakeup_fd_posix.h
@@ -46,7 +46,7 @@
  *
  * Setup:
  * 1. Before calling anything, call global_init() at least once.
- * 1. Call grpc_wakeup_fd_create() to get a wakeup_fd.
+ * 1. Call grpc_wakeup_fd_init() to set up a wakeup_fd.
  * 2. Add the result of GRPC_WAKEUP_FD_FD to the set of monitored file
  *    descriptors for the poll() style API you are using. Monitor the file
  *    descriptor for readability.
diff --git a/src/core/lib/profiling/basic_timers.c b/src/core/lib/profiling/basic_timers.c
index 1f1987fb8e7d4d1ba0aaa9ea4d0f9022f44b6218..bc8e27714ca298eef3c25c2ad1bfdcc4ada0618a 100644
--- a/src/core/lib/profiling/basic_timers.c
+++ b/src/core/lib/profiling/basic_timers.c
@@ -218,7 +218,7 @@ void gpr_timers_set_log_filename(const char *filename) {
 static void init_output() {
   gpr_thd_options options = gpr_thd_options_default();
   gpr_thd_options_set_joinable(&options);
-  gpr_thd_new(&g_writing_thread, writing_thread, NULL, &options);
+  GPR_ASSERT(gpr_thd_new(&g_writing_thread, writing_thread, NULL, &options));
   atexit(finish_writing);
 }
 
diff --git a/src/core/lib/security/credentials/credentials.c b/src/core/lib/security/credentials/credentials.c
index 52b80141d11c3f53d4f9f0237e2df3208ced6cb3..d89da47fc155ccde985bd1646ceef3fffb253224 100644
--- a/src/core/lib/security/credentials/credentials.c
+++ b/src/core/lib/security/credentials/credentials.c
@@ -37,7 +37,6 @@
 #include <string.h>
 
 #include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/channel/http_client_filter.h"
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/iomgr/executor.h"
diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h
index 510b79552a31be5fa9c82a4a3edc7ba50fc371cf..89b8e3c0b3834561b01ffd8701a0b824ce680917 100644
--- a/src/core/lib/security/credentials/credentials.h
+++ b/src/core/lib/security/credentials/credentials.h
@@ -71,7 +71,7 @@ typedef enum {
 
 #define GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS 60
 
-#define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata"
+#define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata.google.internal"
 #define GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH \
   "/computeMetadata/v1/instance/service-accounts/default/token"
 
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.c b/src/core/lib/security/credentials/fake/fake_credentials.c
index 68636ba2088ecea6c54530a6bd84b74577d58301..3fdb67fb91261f47efa800f9b88a67524ef79827 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.c
+++ b/src/core/lib/security/credentials/fake/fake_credentials.c
@@ -39,11 +39,15 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
+#include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/executor.h"
 #include "src/core/lib/support/string.h"
 
 /* -- Fake transport security credentials. -- */
 
+#define GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS \
+  "grpc.fake_security.expected_targets"
+
 static grpc_security_status fake_transport_security_create_security_connector(
     grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c,
     grpc_call_credentials *call_creds, const char *target,
@@ -88,6 +92,25 @@ grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
   return c;
 }
 
+grpc_arg grpc_fake_transport_expected_targets_arg(char *expected_targets) {
+  grpc_arg arg;
+  arg.type = GRPC_ARG_STRING;
+  arg.key = GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS;
+  arg.value.string = expected_targets;
+  return arg;
+}
+
+const char *grpc_fake_transport_get_expected_targets(
+    const grpc_channel_args *args) {
+  const grpc_arg *expected_target_arg =
+      grpc_channel_args_find(args, GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS);
+  if (expected_target_arg != NULL &&
+      expected_target_arg->type == GRPC_ARG_STRING) {
+    return expected_target_arg->value.string;
+  }
+  return NULL;
+}
+
 /* -- Metadata-only test credentials. -- */
 
 static void md_only_test_destruct(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.h b/src/core/lib/security/credentials/fake/fake_credentials.h
index 0fe98417c6cb656ab3f03e936a1f08fcdb5ec2b7..a28b545a676769f27c06ea32d02287d6a5ececab 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.h
+++ b/src/core/lib/security/credentials/fake/fake_credentials.h
@@ -38,10 +38,17 @@
 
 /* -- Fake transport security credentials. -- */
 
+/* Creates a fake transport security credentials object for testing. */
+grpc_channel_credentials *grpc_fake_transport_security_credentials_create(void);
+
+/* Creates a fake server transport security credentials object for testing. */
+grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
+    void);
+
 /* Used to verify the target names given to the fake transport security
  * connector.
  *
- * Its syntax by example:
+ * The syntax of \a expected_targets by example:
  * For LB channels:
  *     "backend_target_1,backend_target_2,...;lb_target_1,lb_target_2,..."
  * For regular channels:
@@ -50,15 +57,11 @@
  * That is to say, LB channels have a heading list of LB targets separated from
  * the list of backend targets by a semicolon. For non-LB channels, only the
  * latter is present. */
-#define GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS \
-  "grpc.test_only.fake_security.expected_target"
+grpc_arg grpc_fake_transport_expected_targets_arg(char *expected_targets);
 
-/* Creates a fake transport security credentials object for testing. */
-grpc_channel_credentials *grpc_fake_transport_security_credentials_create(void);
-
-/* Creates a fake server transport security credentials object for testing. */
-grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
-    void);
+/* Return the value associated with the expected targets channel arg or NULL */
+const char *grpc_fake_transport_get_expected_targets(
+    const grpc_channel_args *args);
 
 /* --  Metadata-only Test credentials. -- */
 
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.c b/src/core/lib/security/credentials/google_default/google_default_credentials.c
index dd446213477c0ef850609d515ebba6900022155f..97501e6788ca05513e83967191bd17793549ac3a 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.c
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.c
@@ -180,7 +180,7 @@ static grpc_error *create_default_creds_from_path(
   grpc_slice creds_data = grpc_empty_slice();
   grpc_error *error = GRPC_ERROR_NONE;
   if (creds_path == NULL) {
-    error = GRPC_ERROR_CREATE("creds_path unset");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("creds_path unset");
     goto end;
   }
   error = grpc_load_file(creds_path, 0, &creds_data);
@@ -190,10 +190,9 @@ static grpc_error *create_default_creds_from_path(
   json = grpc_json_parse_string_with_len(
       (char *)GRPC_SLICE_START_PTR(creds_data), GRPC_SLICE_LENGTH(creds_data));
   if (json == NULL) {
-    char *dump = grpc_dump_slice(creds_data, GPR_DUMP_HEX | GPR_DUMP_ASCII);
-    error = grpc_error_set_str(GRPC_ERROR_CREATE("Failed to parse JSON"),
-                               GRPC_ERROR_STR_RAW_BYTES, dump);
-    gpr_free(dump);
+    error = grpc_error_set_str(
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to parse JSON"),
+        GRPC_ERROR_STR_RAW_BYTES, grpc_slice_ref_internal(creds_data));
     goto end;
   }
 
@@ -204,7 +203,7 @@ static grpc_error *create_default_creds_from_path(
         grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
             exec_ctx, key, grpc_max_auth_token_lifetime());
     if (result == NULL) {
-      error = GRPC_ERROR_CREATE(
+      error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
           "grpc_service_account_jwt_access_credentials_create_from_auth_json_"
           "key failed");
     }
@@ -217,7 +216,7 @@ static grpc_error *create_default_creds_from_path(
     result =
         grpc_refresh_token_credentials_create_from_auth_refresh_token(token);
     if (result == NULL) {
-      error = GRPC_ERROR_CREATE(
+      error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
           "grpc_refresh_token_credentials_create_from_auth_refresh_token "
           "failed");
     }
@@ -236,7 +235,8 @@ end:
 grpc_channel_credentials *grpc_google_default_credentials_create(void) {
   grpc_channel_credentials *result = NULL;
   grpc_call_credentials *call_creds = NULL;
-  grpc_error *error = GRPC_ERROR_CREATE("Failed to create Google credentials");
+  grpc_error *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+      "Failed to create Google credentials");
   grpc_error *err;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
@@ -274,7 +274,8 @@ grpc_channel_credentials *grpc_google_default_credentials_create(void) {
       call_creds = grpc_google_compute_engine_credentials_create(NULL);
       if (call_creds == NULL) {
         error = grpc_error_add_child(
-            error, GRPC_ERROR_CREATE("Failed to get credentials from network"));
+            error, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                       "Failed to get credentials from network"));
       }
     }
   }
diff --git a/src/core/lib/security/credentials/jwt/json_token.c b/src/core/lib/security/credentials/jwt/json_token.c
index 192a5f47edf3fe511bf3d0d471b3508778a0c819..aa905725fcd13788d39de9326f2173e21c29f12f 100644
--- a/src/core/lib/security/credentials/jwt/json_token.c
+++ b/src/core/lib/security/credentials/jwt/json_token.c
@@ -40,8 +40,8 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
 
-#include "src/core/lib/security/util/b64.h"
 #include "src/core/lib/security/util/json_util.h"
+#include "src/core/lib/slice/b64.h"
 #include "src/core/lib/support/string.h"
 
 #include <openssl/bio.h>
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.c b/src/core/lib/security/credentials/jwt/jwt_verifier.c
index 5c59cf0f4ad1fa76a3015e068a1635f2f89b0953..0e2a26437164217935b8c787122dd5434ba2e501 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.c
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.c
@@ -45,10 +45,10 @@
 
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/iomgr/polling_entity.h"
-#include "src/core/lib/security/util/b64.h"
+#include "src/core/lib/slice/b64.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
-#include "src/core/lib/tsi/ssl_types.h"
+#include "src/core/tsi/ssl_types.h"
 
 /* --- Utils. --- */
 
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.c b/src/core/lib/security/credentials/ssl/ssl_credentials.c
index 4b17ac80983550c971c1e4b8490daaba63b0f5c0..7c35ebe6841b856cb2ca33ba75c61f23df4ae7e5 100644
--- a/src/core/lib/security/credentials/ssl/ssl_credentials.c
+++ b/src/core/lib/security/credentials/ssl/ssl_credentials.c
@@ -36,33 +36,28 @@
 #include <string.h>
 
 #include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/channel/http_client_filter.h"
 #include "src/core/lib/surface/api_trace.h"
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
 
 //
-// Utils
+// SSL Channel Credentials.
 //
 
-static void ssl_copy_key_material(const char *input, unsigned char **output,
-                                  size_t *output_size) {
-  *output_size = strlen(input);
-  *output = gpr_malloc(*output_size);
-  memcpy(*output, input, *output_size);
+static void ssl_config_pem_key_cert_pair_destroy(
+    tsi_ssl_pem_key_cert_pair *kp) {
+  if (kp == NULL) return;
+  gpr_free((void *)kp->private_key);
+  gpr_free((void *)kp->cert_chain);
 }
 
-//
-// SSL Channel Credentials.
-//
-
 static void ssl_destruct(grpc_exec_ctx *exec_ctx,
                          grpc_channel_credentials *creds) {
   grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
-  if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs);
-  if (c->config.pem_private_key != NULL) gpr_free(c->config.pem_private_key);
-  if (c->config.pem_cert_chain != NULL) gpr_free(c->config.pem_cert_chain);
+  gpr_free(c->config.pem_root_certs);
+  ssl_config_pem_key_cert_pair_destroy(&c->config.pem_key_cert_pair);
 }
 
 static grpc_security_status ssl_create_security_connector(
@@ -103,18 +98,15 @@ static void ssl_build_config(const char *pem_root_certs,
                              grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
                              grpc_ssl_config *config) {
   if (pem_root_certs != NULL) {
-    ssl_copy_key_material(pem_root_certs, &config->pem_root_certs,
-                          &config->pem_root_certs_size);
+    config->pem_root_certs = gpr_strdup(pem_root_certs);
   }
   if (pem_key_cert_pair != NULL) {
     GPR_ASSERT(pem_key_cert_pair->private_key != NULL);
     GPR_ASSERT(pem_key_cert_pair->cert_chain != NULL);
-    ssl_copy_key_material(pem_key_cert_pair->private_key,
-                          &config->pem_private_key,
-                          &config->pem_private_key_size);
-    ssl_copy_key_material(pem_key_cert_pair->cert_chain,
-                          &config->pem_cert_chain,
-                          &config->pem_cert_chain_size);
+    config->pem_key_cert_pair.cert_chain =
+        gpr_strdup(pem_key_cert_pair->cert_chain);
+    config->pem_key_cert_pair.private_key =
+        gpr_strdup(pem_key_cert_pair->private_key);
   }
 }
 
@@ -144,22 +136,10 @@ static void ssl_server_destruct(grpc_exec_ctx *exec_ctx,
   grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
   size_t i;
   for (i = 0; i < c->config.num_key_cert_pairs; i++) {
-    if (c->config.pem_private_keys[i] != NULL) {
-      gpr_free(c->config.pem_private_keys[i]);
-    }
-    if (c->config.pem_cert_chains[i] != NULL) {
-      gpr_free(c->config.pem_cert_chains[i]);
-    }
-  }
-  if (c->config.pem_private_keys != NULL) gpr_free(c->config.pem_private_keys);
-  if (c->config.pem_private_keys_sizes != NULL) {
-    gpr_free(c->config.pem_private_keys_sizes);
-  }
-  if (c->config.pem_cert_chains != NULL) gpr_free(c->config.pem_cert_chains);
-  if (c->config.pem_cert_chains_sizes != NULL) {
-    gpr_free(c->config.pem_cert_chains_sizes);
+    ssl_config_pem_key_cert_pair_destroy(&c->config.pem_key_cert_pairs[i]);
   }
-  if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs);
+  gpr_free(c->config.pem_key_cert_pairs);
+  gpr_free(c->config.pem_root_certs);
 }
 
 static grpc_security_status ssl_server_create_security_connector(
@@ -180,30 +160,21 @@ static void ssl_build_server_config(
   size_t i;
   config->client_certificate_request = client_certificate_request;
   if (pem_root_certs != NULL) {
-    ssl_copy_key_material(pem_root_certs, &config->pem_root_certs,
-                          &config->pem_root_certs_size);
+    config->pem_root_certs = gpr_strdup(pem_root_certs);
   }
   if (num_key_cert_pairs > 0) {
     GPR_ASSERT(pem_key_cert_pairs != NULL);
-    config->pem_private_keys =
-        gpr_malloc(num_key_cert_pairs * sizeof(unsigned char *));
-    config->pem_cert_chains =
-        gpr_malloc(num_key_cert_pairs * sizeof(unsigned char *));
-    config->pem_private_keys_sizes =
-        gpr_malloc(num_key_cert_pairs * sizeof(size_t));
-    config->pem_cert_chains_sizes =
-        gpr_malloc(num_key_cert_pairs * sizeof(size_t));
+    config->pem_key_cert_pairs =
+        gpr_zalloc(num_key_cert_pairs * sizeof(tsi_ssl_pem_key_cert_pair));
   }
   config->num_key_cert_pairs = num_key_cert_pairs;
   for (i = 0; i < num_key_cert_pairs; i++) {
     GPR_ASSERT(pem_key_cert_pairs[i].private_key != NULL);
     GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != NULL);
-    ssl_copy_key_material(pem_key_cert_pairs[i].private_key,
-                          &config->pem_private_keys[i],
-                          &config->pem_private_keys_sizes[i]);
-    ssl_copy_key_material(pem_key_cert_pairs[i].cert_chain,
-                          &config->pem_cert_chains[i],
-                          &config->pem_cert_chains_sizes[i]);
+    config->pem_key_cert_pairs[i].cert_chain =
+        gpr_strdup(pem_key_cert_pairs[i].cert_chain);
+    config->pem_key_cert_pairs[i].private_key =
+        gpr_strdup(pem_key_cert_pairs[i].private_key);
   }
 }
 
diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c
index a23082a86678ad0df1a6000b6421cedde0223055..1f0daf73253e6ae7ebbaa02cd1083ce801534121 100644
--- a/src/core/lib/security/transport/client_auth_filter.c
+++ b/src/core/lib/security/transport/client_auth_filter.c
@@ -64,7 +64,7 @@ typedef struct {
      pollset_set so that work can progress when this call wants work to progress
   */
   grpc_polling_entity *pollent;
-  grpc_transport_stream_op op;
+  grpc_transport_stream_op_batch op;
   uint8_t security_context_set;
   grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT];
   grpc_auth_metadata_context auth_md_context;
@@ -95,7 +95,8 @@ static void reset_auth_metadata_context(
 static void add_error(grpc_error **combined, grpc_error *error) {
   if (error == GRPC_ERROR_NONE) return;
   if (*combined == GRPC_ERROR_NONE) {
-    *combined = GRPC_ERROR_CREATE("Client auth metadata plugin error");
+    *combined = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Client auth metadata plugin error");
   }
   *combined = grpc_error_add_child(*combined, error);
 }
@@ -107,21 +108,22 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
                                     const char *error_details) {
   grpc_call_element *elem = (grpc_call_element *)user_data;
   call_data *calld = elem->call_data;
-  grpc_transport_stream_op *op = &calld->op;
+  grpc_transport_stream_op_batch *op = &calld->op;
   grpc_metadata_batch *mdb;
   size_t i;
   reset_auth_metadata_context(&calld->auth_md_context);
   grpc_error *error = GRPC_ERROR_NONE;
   if (status != GRPC_CREDENTIALS_OK) {
     error = grpc_error_set_int(
-        GRPC_ERROR_CREATE(error_details != NULL && strlen(error_details) > 0
-                              ? error_details
-                              : "Credentials failed to get metadata."),
+        GRPC_ERROR_CREATE_FROM_COPIED_STRING(
+            error_details != NULL && strlen(error_details) > 0
+                ? error_details
+                : "Credentials failed to get metadata."),
         GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAUTHENTICATED);
   } else {
     GPR_ASSERT(num_md <= MAX_CREDENTIALS_METADATA_COUNT);
-    GPR_ASSERT(op->send_initial_metadata != NULL);
-    mdb = op->send_initial_metadata;
+    GPR_ASSERT(op->send_initial_metadata);
+    mdb = op->payload->send_initial_metadata.send_initial_metadata;
     for (i = 0; i < num_md; i++) {
       add_error(&error,
                 grpc_metadata_batch_add_tail(
@@ -134,7 +136,7 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
   if (error == GRPC_ERROR_NONE) {
     grpc_call_next_op(exec_ctx, elem, op);
   } else {
-    grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error);
+    grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, op, error);
   }
 }
 
@@ -170,11 +172,13 @@ void build_auth_metadata_context(grpc_security_connector *sc,
 
 static void send_security_metadata(grpc_exec_ctx *exec_ctx,
                                    grpc_call_element *elem,
-                                   grpc_transport_stream_op *op) {
+                                   grpc_transport_stream_op_batch *op) {
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
   grpc_client_security_context *ctx =
-      (grpc_client_security_context *)op->context[GRPC_CONTEXT_SECURITY].value;
+      (grpc_client_security_context *)op->payload
+          ->context[GRPC_CONTEXT_SECURITY]
+          .value;
   grpc_call_credentials *channel_call_creds =
       chand->security_connector->request_metadata_creds;
   int call_creds_has_md = (ctx != NULL) && (ctx->creds != NULL);
@@ -189,10 +193,10 @@ static void send_security_metadata(grpc_exec_ctx *exec_ctx,
     calld->creds = grpc_composite_call_credentials_create(channel_call_creds,
                                                           ctx->creds, NULL);
     if (calld->creds == NULL) {
-      grpc_transport_stream_op_finish_with_failure(
+      grpc_transport_stream_op_batch_finish_with_failure(
           exec_ctx, op,
           grpc_error_set_int(
-              GRPC_ERROR_CREATE(
+              GRPC_ERROR_CREATE_FROM_STATIC_STRING(
                   "Incompatible credentials set on channel and call."),
               GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAUTHENTICATED));
       return;
@@ -225,9 +229,10 @@ static void on_host_checked(grpc_exec_ctx *exec_ctx, void *user_data,
                  host);
     gpr_free(host);
     grpc_call_element_signal_error(
-        exec_ctx, elem, grpc_error_set_int(GRPC_ERROR_CREATE(error_msg),
-                                           GRPC_ERROR_INT_GRPC_STATUS,
-                                           GRPC_STATUS_UNAUTHENTICATED));
+        exec_ctx, elem,
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg),
+                           GRPC_ERROR_INT_GRPC_STATUS,
+                           GRPC_STATUS_UNAUTHENTICATED));
     gpr_free(error_msg);
   }
 }
@@ -239,7 +244,7 @@ static void on_host_checked(grpc_exec_ctx *exec_ctx, void *user_data,
    that is being sent or received. */
 static void auth_start_transport_op(grpc_exec_ctx *exec_ctx,
                                     grpc_call_element *elem,
-                                    grpc_transport_stream_op *op) {
+                                    grpc_transport_stream_op_batch *op) {
   GPR_TIMER_BEGIN("auth_start_transport_op", 0);
 
   /* grab pointers to our data from the call element */
@@ -248,23 +253,25 @@ static void auth_start_transport_op(grpc_exec_ctx *exec_ctx,
   grpc_linked_mdelem *l;
   grpc_client_security_context *sec_ctx = NULL;
 
-  if (calld->security_context_set == 0 && op->cancel_error == GRPC_ERROR_NONE) {
+  if (calld->security_context_set == 0 && !op->cancel_stream) {
     calld->security_context_set = 1;
-    GPR_ASSERT(op->context);
-    if (op->context[GRPC_CONTEXT_SECURITY].value == NULL) {
-      op->context[GRPC_CONTEXT_SECURITY].value =
+    GPR_ASSERT(op->payload->context != NULL);
+    if (op->payload->context[GRPC_CONTEXT_SECURITY].value == NULL) {
+      op->payload->context[GRPC_CONTEXT_SECURITY].value =
           grpc_client_security_context_create();
-      op->context[GRPC_CONTEXT_SECURITY].destroy =
+      op->payload->context[GRPC_CONTEXT_SECURITY].destroy =
           grpc_client_security_context_destroy;
     }
-    sec_ctx = op->context[GRPC_CONTEXT_SECURITY].value;
+    sec_ctx = op->payload->context[GRPC_CONTEXT_SECURITY].value;
     GRPC_AUTH_CONTEXT_UNREF(sec_ctx->auth_context, "client auth filter");
     sec_ctx->auth_context =
         GRPC_AUTH_CONTEXT_REF(chand->auth_context, "client_auth_filter");
   }
 
-  if (op->send_initial_metadata != NULL) {
-    for (l = op->send_initial_metadata->list.head; l != NULL; l = l->next) {
+  if (op->send_initial_metadata) {
+    for (l = op->payload->send_initial_metadata.send_initial_metadata->list
+                 .head;
+         l != NULL; l = l->next) {
       grpc_mdelem md = l->md;
       /* Pointer comparison is OK for md_elems created from the same context.
        */
@@ -318,7 +325,7 @@ static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
 /* Destructor for call_data */
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
-                              void *ignored) {
+                              grpc_closure *ignored) {
   call_data *calld = elem->call_data;
   grpc_call_credentials_unref(exec_ctx, calld->creds);
   if (calld->have_host) {
@@ -336,8 +343,16 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_channel_element_args *args) {
   grpc_security_connector *sc =
       grpc_security_connector_find_in_args(args->channel_args);
+  if (sc == NULL) {
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Security connector missing from client auth filter args");
+  }
   grpc_auth_context *auth_context =
       grpc_find_auth_context_in_args(args->channel_args);
+  if (auth_context == NULL) {
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Auth context missing from client auth filter args");
+  }
 
   /* grab pointers to our data from the channel element */
   channel_data *chand = elem->channel_data;
@@ -346,8 +361,6 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
      handle the case that there's no 'next' filter to call on the up or down
      path */
   GPR_ASSERT(!args->is_last);
-  GPR_ASSERT(sc != NULL);
-  GPR_ASSERT(auth_context != NULL);
 
   /* initialize members */
   chand->security_connector =
diff --git a/src/core/lib/security/transport/secure_endpoint.c b/src/core/lib/security/transport/secure_endpoint.c
index 7d58843d69063311f5edb3ecc62cf662de2c8cfe..0d5c7432c645d299a050fa76d61fa3e6b2bdeea9 100644
--- a/src/core/lib/security/transport/secure_endpoint.c
+++ b/src/core/lib/security/transport/secure_endpoint.c
@@ -49,7 +49,7 @@
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
-#include "src/core/lib/tsi/transport_security_interface.h"
+#include "src/core/tsi/transport_security_interface.h"
 
 #define STAGING_BUFFER_SIZE 8192
 
@@ -130,7 +130,7 @@ static void secure_endpoint_ref(secure_endpoint *ep) { gpr_ref(&ep->ref); }
 static void flush_read_staging_buffer(secure_endpoint *ep, uint8_t **cur,
                                       uint8_t **end) {
   grpc_slice_buffer_add(ep->read_buffer, ep->read_staging_buffer);
-  ep->read_staging_buffer = grpc_slice_malloc(STAGING_BUFFER_SIZE);
+  ep->read_staging_buffer = GRPC_SLICE_MALLOC(STAGING_BUFFER_SIZE);
   *cur = GRPC_SLICE_START_PTR(ep->read_staging_buffer);
   *end = GRPC_SLICE_END_PTR(ep->read_staging_buffer);
 }
@@ -162,7 +162,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *user_data,
 
   if (error != GRPC_ERROR_NONE) {
     grpc_slice_buffer_reset_and_unref_internal(exec_ctx, ep->read_buffer);
-    call_read_cb(exec_ctx, ep, GRPC_ERROR_CREATE_REFERENCING(
+    call_read_cb(exec_ctx, ep, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
                                    "Secure read failed", &error, 1));
     return;
   }
@@ -220,8 +220,10 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *user_data,
 
   if (result != TSI_OK) {
     grpc_slice_buffer_reset_and_unref_internal(exec_ctx, ep->read_buffer);
-    call_read_cb(exec_ctx, ep, grpc_set_tsi_error_result(
-                                   GRPC_ERROR_CREATE("Unwrap failed"), result));
+    call_read_cb(
+        exec_ctx, ep,
+        grpc_set_tsi_error_result(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Unwrap failed"), result));
     return;
   }
 
@@ -250,7 +252,7 @@ static void endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep,
 static void flush_write_staging_buffer(secure_endpoint *ep, uint8_t **cur,
                                        uint8_t **end) {
   grpc_slice_buffer_add(&ep->output_buffer, ep->write_staging_buffer);
-  ep->write_staging_buffer = grpc_slice_malloc(STAGING_BUFFER_SIZE);
+  ep->write_staging_buffer = GRPC_SLICE_MALLOC(STAGING_BUFFER_SIZE);
   *cur = GRPC_SLICE_START_PTR(ep->write_staging_buffer);
   *end = GRPC_SLICE_END_PTR(ep->write_staging_buffer);
 }
@@ -332,7 +334,8 @@ static void endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep,
     grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &ep->output_buffer);
     grpc_closure_sched(
         exec_ctx, cb,
-        grpc_set_tsi_error_result(GRPC_ERROR_CREATE("Wrap failed"), result));
+        grpc_set_tsi_error_result(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Wrap failed"), result));
     GPR_TIMER_END("secure_endpoint.endpoint_write", 0);
     return;
   }
@@ -412,8 +415,8 @@ grpc_endpoint *grpc_secure_endpoint_create(
     grpc_slice_buffer_add(&ep->leftover_bytes,
                           grpc_slice_ref_internal(leftover_slices[i]));
   }
-  ep->write_staging_buffer = grpc_slice_malloc(STAGING_BUFFER_SIZE);
-  ep->read_staging_buffer = grpc_slice_malloc(STAGING_BUFFER_SIZE);
+  ep->write_staging_buffer = GRPC_SLICE_MALLOC(STAGING_BUFFER_SIZE);
+  ep->read_staging_buffer = GRPC_SLICE_MALLOC(STAGING_BUFFER_SIZE);
   grpc_slice_buffer_init(&ep->output_buffer);
   grpc_slice_buffer_init(&ep->source_buffer);
   ep->read_buffer = NULL;
diff --git a/src/core/lib/security/transport/security_connector.c b/src/core/lib/security/transport/security_connector.c
index ad083a730fbe26bcc5653473645e00b3e18dc67d..30431a4e4a5247f935cfa96caf273566bc2b03bd 100644
--- a/src/core/lib/security/transport/security_connector.c
+++ b/src/core/lib/security/transport/security_connector.c
@@ -54,8 +54,8 @@
 #include "src/core/lib/security/transport/security_handshaker.h"
 #include "src/core/lib/support/env.h"
 #include "src/core/lib/support/string.h"
-#include "src/core/lib/tsi/fake_transport_security.h"
-#include "src/core/lib/tsi/ssl_transport_security.h"
+#include "src/core/tsi/fake_transport_security.h"
+#include "src/core/tsi/ssl_transport_security.h"
 
 /* -- Constants. -- */
 
@@ -78,9 +78,8 @@ void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) {
 
 /* Defines the cipher suites that we accept by default. All these cipher suites
    are compliant with HTTP2. */
-#define GRPC_SSL_CIPHER_SUITES                                            \
-  "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-" \
-  "SHA384:ECDHE-RSA-AES256-GCM-SHA384"
+#define GRPC_SSL_CIPHER_SUITES \
+  "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384"
 
 static gpr_once cipher_suites_once = GPR_ONCE_INIT;
 static const char *cipher_suites = NULL;
@@ -137,9 +136,9 @@ void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx,
                                         grpc_auth_context **auth_context,
                                         grpc_closure *on_peer_checked) {
   if (sc == NULL) {
-    grpc_closure_sched(
-        exec_ctx, on_peer_checked,
-        GRPC_ERROR_CREATE("cannot check peer -- no security connector"));
+    grpc_closure_sched(exec_ctx, on_peer_checked,
+                       GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                           "cannot check peer -- no security connector"));
     tsi_peer_destruct(&peer);
   } else {
     sc->vtable->check_peer(exec_ctx, sc, peer, auth_context, on_peer_checked);
@@ -330,7 +329,8 @@ static void fake_check_peer(grpc_exec_ctx *exec_ctx,
   grpc_error *error = GRPC_ERROR_NONE;
   *auth_context = NULL;
   if (peer.property_count != 1) {
-    error = GRPC_ERROR_CREATE("Fake peers should only have 1 property.");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Fake peers should only have 1 property.");
     goto end;
   }
   prop_name = peer.properties[0].name;
@@ -339,13 +339,14 @@ static void fake_check_peer(grpc_exec_ctx *exec_ctx,
     char *msg;
     gpr_asprintf(&msg, "Unexpected property in fake peer: %s.",
                  prop_name == NULL ? "<EMPTY>" : prop_name);
-    error = GRPC_ERROR_CREATE(msg);
+    error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     goto end;
   }
   if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE,
               peer.properties[0].value.length)) {
-    error = GRPC_ERROR_CREATE("Invalid value for cert type property.");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Invalid value for cert type property.");
     goto end;
   }
   *auth_context = grpc_auth_context_create(NULL);
@@ -421,12 +422,8 @@ grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
   c->base.check_call_host = fake_channel_check_call_host;
   c->base.add_handshakers = fake_channel_add_handshakers;
   c->target = gpr_strdup(target);
-  const grpc_arg *expected_target_arg =
-      grpc_channel_args_find(args, GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS);
-  if (expected_target_arg != NULL) {
-    GPR_ASSERT(expected_target_arg->type == GRPC_ARG_STRING);
-    c->expected_targets = gpr_strdup(expected_target_arg->value.string);
-  }
+  const char *expected_targets = grpc_fake_transport_get_expected_targets(args);
+  c->expected_targets = gpr_strdup(expected_targets);
   c->is_lb_channel = (grpc_lb_targets_info_find_in_args(args) != NULL);
   return &c->base;
 }
@@ -446,14 +443,14 @@ grpc_server_security_connector *grpc_fake_server_security_connector_create(
 
 typedef struct {
   grpc_channel_security_connector base;
-  tsi_ssl_handshaker_factory *handshaker_factory;
+  tsi_ssl_client_handshaker_factory *handshaker_factory;
   char *target_name;
   char *overridden_target_name;
 } grpc_ssl_channel_security_connector;
 
 typedef struct {
   grpc_server_security_connector base;
-  tsi_ssl_handshaker_factory *handshaker_factory;
+  tsi_ssl_server_handshaker_factory *handshaker_factory;
 } grpc_ssl_server_security_connector;
 
 static void ssl_channel_destroy(grpc_exec_ctx *exec_ctx,
@@ -462,7 +459,7 @@ static void ssl_channel_destroy(grpc_exec_ctx *exec_ctx,
       (grpc_ssl_channel_security_connector *)sc;
   grpc_call_credentials_unref(exec_ctx, c->base.request_metadata_creds);
   if (c->handshaker_factory != NULL) {
-    tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
+    tsi_ssl_client_handshaker_factory_destroy(c->handshaker_factory);
   }
   if (c->target_name != NULL) gpr_free(c->target_name);
   if (c->overridden_target_name != NULL) gpr_free(c->overridden_target_name);
@@ -474,26 +471,11 @@ static void ssl_server_destroy(grpc_exec_ctx *exec_ctx,
   grpc_ssl_server_security_connector *c =
       (grpc_ssl_server_security_connector *)sc;
   if (c->handshaker_factory != NULL) {
-    tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
+    tsi_ssl_server_handshaker_factory_destroy(c->handshaker_factory);
   }
   gpr_free(sc);
 }
 
-static grpc_security_status ssl_create_handshaker(
-    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;
-  result = tsi_ssl_handshaker_factory_create_handshaker(
-      handshaker_factory, is_client ? peer_name : NULL, handshaker);
-  if (result != TSI_OK) {
-    gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
-            tsi_result_to_string(result));
-    return GRPC_SECURITY_ERROR;
-  }
-  return GRPC_SECURITY_OK;
-}
-
 static void ssl_channel_add_handshakers(grpc_exec_ctx *exec_ctx,
                                         grpc_channel_security_connector *sc,
                                         grpc_handshake_manager *handshake_mgr) {
@@ -501,11 +483,17 @@ static void ssl_channel_add_handshakers(grpc_exec_ctx *exec_ctx,
       (grpc_ssl_channel_security_connector *)sc;
   // Instantiate TSI handshaker.
   tsi_handshaker *tsi_hs = NULL;
-  ssl_create_handshaker(c->handshaker_factory, true /* is_client */,
-                        c->overridden_target_name != NULL
-                            ? c->overridden_target_name
-                            : c->target_name,
-                        &tsi_hs);
+  tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
+      c->handshaker_factory,
+      c->overridden_target_name != NULL ? c->overridden_target_name
+                                        : c->target_name,
+      &tsi_hs);
+  if (result != TSI_OK) {
+    gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
+            tsi_result_to_string(result));
+    return;
+  }
+
   // Create handshakers.
   grpc_handshake_manager_add(handshake_mgr, grpc_security_handshaker_create(
                                                 exec_ctx, tsi_hs, &sc->base));
@@ -518,8 +506,14 @@ static void ssl_server_add_handshakers(grpc_exec_ctx *exec_ctx,
       (grpc_ssl_server_security_connector *)sc;
   // Instantiate TSI handshaker.
   tsi_handshaker *tsi_hs = NULL;
-  ssl_create_handshaker(c->handshaker_factory, false /* is_client */,
-                        NULL /* peer_name */, &tsi_hs);
+  tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker(
+      c->handshaker_factory, &tsi_hs);
+  if (result != TSI_OK) {
+    gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
+            tsi_result_to_string(result));
+    return;
+  }
+
   // Create handshakers.
   grpc_handshake_manager_add(handshake_mgr, grpc_security_handshaker_create(
                                                 exec_ctx, tsi_hs, &sc->base));
@@ -586,18 +580,19 @@ static grpc_error *ssl_check_peer(grpc_security_connector *sc,
   const tsi_peer_property *p =
       tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL);
   if (p == NULL) {
-    return GRPC_ERROR_CREATE(
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
         "Cannot check peer: missing selected ALPN property.");
   }
   if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) {
-    return GRPC_ERROR_CREATE("Cannot check peer: invalid ALPN value.");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Cannot check peer: invalid ALPN value.");
   }
 
   /* Check the peer name if specified. */
   if (peer_name != NULL && !ssl_host_matches_name(peer, peer_name)) {
     char *msg;
     gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name);
-    grpc_error *error = GRPC_ERROR_CREATE(msg);
+    grpc_error *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return error;
   }
@@ -699,6 +694,7 @@ static grpc_security_connector_vtable ssl_channel_vtable = {
 static grpc_security_connector_vtable ssl_server_vtable = {
     ssl_server_destroy, ssl_server_check_peer};
 
+/* returns a NULL terminated slice. */
 static grpc_slice compute_default_pem_root_certs_once(void) {
   grpc_slice result = grpc_empty_slice();
 
@@ -707,7 +703,7 @@ static grpc_slice compute_default_pem_root_certs_once(void) {
       gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR);
   if (default_root_certs_path != NULL) {
     GRPC_LOG_IF_ERROR("load_file",
-                      grpc_load_file(default_root_certs_path, 0, &result));
+                      grpc_load_file(default_root_certs_path, 1, &result));
     gpr_free(default_root_certs_path);
   }
 
@@ -718,15 +714,18 @@ static grpc_slice compute_default_pem_root_certs_once(void) {
     ovrd_res = ssl_roots_override_cb(&pem_root_certs);
     if (ovrd_res == GRPC_SSL_ROOTS_OVERRIDE_OK) {
       GPR_ASSERT(pem_root_certs != NULL);
-      result = grpc_slice_new(pem_root_certs, strlen(pem_root_certs), gpr_free);
+      result = grpc_slice_from_copied_buffer(
+          pem_root_certs,
+          strlen(pem_root_certs) + 1);  // NULL terminator.
     }
+    gpr_free(pem_root_certs);
   }
 
   /* Fall back to installed certs if needed. */
   if (GRPC_SLICE_IS_EMPTY(result) &&
       ovrd_res != GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY) {
     GRPC_LOG_IF_ERROR("load_file",
-                      grpc_load_file(installed_roots_path, 0, &result));
+                      grpc_load_file(installed_roots_path, 1, &result));
   }
   return result;
 }
@@ -766,13 +765,14 @@ get_tsi_client_certificate_request_type(
   }
 }
 
-size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs) {
+const char *grpc_get_default_ssl_roots(void) {
   /* TODO(jboeuf@google.com): Maybe revisit the approach which consists in
      loading all the roots once for the lifetime of the process. */
   static gpr_once once = GPR_ONCE_INIT;
   gpr_once_init(&once, init_default_pem_root_certs);
-  *pem_root_certs = GRPC_SLICE_START_PTR(default_pem_root_certs);
-  return GRPC_SLICE_LENGTH(default_pem_root_certs);
+  return GRPC_SLICE_IS_EMPTY(default_pem_root_certs)
+             ? NULL
+             : (const char *)GRPC_SLICE_START_PTR(default_pem_root_certs);
 }
 
 grpc_security_status grpc_ssl_channel_security_connector_create(
@@ -780,22 +780,16 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
     const grpc_ssl_config *config, const char *target_name,
     const char *overridden_target_name, grpc_channel_security_connector **sc) {
   size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
-  const unsigned char **alpn_protocol_strings =
+  const char **alpn_protocol_strings =
       gpr_malloc(sizeof(const char *) * num_alpn_protocols);
-  unsigned char *alpn_protocol_string_lengths =
-      gpr_malloc(sizeof(unsigned char) * num_alpn_protocols);
   tsi_result result = TSI_OK;
   grpc_ssl_channel_security_connector *c;
   size_t i;
-  const unsigned char *pem_root_certs;
-  size_t pem_root_certs_size;
+  const char *pem_root_certs;
   char *port;
 
   for (i = 0; i < num_alpn_protocols; i++) {
-    alpn_protocol_strings[i] =
-        (const unsigned char *)grpc_chttp2_get_alpn_version_index(i);
-    alpn_protocol_string_lengths[i] =
-        (unsigned char)strlen(grpc_chttp2_get_alpn_version_index(i));
+    alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i);
   }
 
   if (config == NULL || target_name == NULL) {
@@ -803,14 +797,13 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
     goto error;
   }
   if (config->pem_root_certs == NULL) {
-    pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs);
-    if (pem_root_certs == NULL || pem_root_certs_size == 0) {
+    pem_root_certs = grpc_get_default_ssl_roots();
+    if (pem_root_certs == NULL) {
       gpr_log(GPR_ERROR, "Could not get default pem root certs.");
       goto error;
     }
   } else {
     pem_root_certs = config->pem_root_certs;
-    pem_root_certs_size = config->pem_root_certs_size;
   }
 
   c = gpr_zalloc(sizeof(grpc_ssl_channel_security_connector));
@@ -827,11 +820,12 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
   if (overridden_target_name != NULL) {
     c->overridden_target_name = gpr_strdup(overridden_target_name);
   }
+
+  bool has_key_cert_pair = config->pem_key_cert_pair.private_key != NULL &&
+                           config->pem_key_cert_pair.cert_chain != NULL;
   result = tsi_create_ssl_client_handshaker_factory(
-      config->pem_private_key, config->pem_private_key_size,
-      config->pem_cert_chain, config->pem_cert_chain_size, pem_root_certs,
-      pem_root_certs_size, ssl_cipher_suites(), alpn_protocol_strings,
-      alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols,
+      has_key_cert_pair ? &config->pem_key_cert_pair : NULL, pem_root_certs,
+      ssl_cipher_suites(), alpn_protocol_strings, (uint16_t)num_alpn_protocols,
       &c->handshaker_factory);
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
@@ -842,12 +836,10 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
   }
   *sc = &c->base;
   gpr_free((void *)alpn_protocol_strings);
-  gpr_free(alpn_protocol_string_lengths);
   return GRPC_SECURITY_OK;
 
 error:
   gpr_free((void *)alpn_protocol_strings);
-  gpr_free(alpn_protocol_string_lengths);
   return GRPC_SECURITY_ERROR;
 }
 
@@ -855,19 +847,14 @@ grpc_security_status grpc_ssl_server_security_connector_create(
     grpc_exec_ctx *exec_ctx, 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 =
+  const char **alpn_protocol_strings =
       gpr_malloc(sizeof(const char *) * num_alpn_protocols);
-  unsigned char *alpn_protocol_string_lengths =
-      gpr_malloc(sizeof(unsigned char) * num_alpn_protocols);
   tsi_result result = TSI_OK;
   grpc_ssl_server_security_connector *c;
   size_t i;
 
   for (i = 0; i < num_alpn_protocols; i++) {
-    alpn_protocol_strings[i] =
-        (const unsigned char *)grpc_chttp2_get_alpn_version_index(i);
-    alpn_protocol_string_lengths[i] =
-        (unsigned char)strlen(grpc_chttp2_get_alpn_version_index(i));
+    alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i);
   }
 
   if (config == NULL || config->num_key_cert_pairs == 0) {
@@ -880,15 +867,11 @@ grpc_security_status grpc_ssl_server_security_connector_create(
   c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
   c->base.base.vtable = &ssl_server_vtable;
   result = tsi_create_ssl_server_handshaker_factory_ex(
-      (const unsigned char **)config->pem_private_keys,
-      config->pem_private_keys_sizes,
-      (const unsigned char **)config->pem_cert_chains,
-      config->pem_cert_chains_sizes, config->num_key_cert_pairs,
-      config->pem_root_certs, config->pem_root_certs_size,
-      get_tsi_client_certificate_request_type(
-          config->client_certificate_request),
-      ssl_cipher_suites(), alpn_protocol_strings, alpn_protocol_string_lengths,
-      (uint16_t)num_alpn_protocols, &c->handshaker_factory);
+      config->pem_key_cert_pairs, config->num_key_cert_pairs,
+      config->pem_root_certs, get_tsi_client_certificate_request_type(
+                                  config->client_certificate_request),
+      ssl_cipher_suites(), alpn_protocol_strings, (uint16_t)num_alpn_protocols,
+      &c->handshaker_factory);
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
             tsi_result_to_string(result));
@@ -899,11 +882,9 @@ grpc_security_status grpc_ssl_server_security_connector_create(
   c->base.add_handshakers = ssl_server_add_handshakers;
   *sc = &c->base;
   gpr_free((void *)alpn_protocol_strings);
-  gpr_free(alpn_protocol_string_lengths);
   return GRPC_SECURITY_OK;
 
 error:
   gpr_free((void *)alpn_protocol_strings);
-  gpr_free(alpn_protocol_string_lengths);
   return GRPC_SECURITY_ERROR;
 }
diff --git a/src/core/lib/security/transport/security_connector.h b/src/core/lib/security/transport/security_connector.h
index 3df2fecd393c84c543b39491fc9c1d94957d526d..d74f6739c03c19718e6ac8df2a92e6079e347f6e 100644
--- a/src/core/lib/security/transport/security_connector.h
+++ b/src/core/lib/security/transport/security_connector.h
@@ -34,12 +34,15 @@
 #ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_CONNECTOR_H
 #define GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_CONNECTOR_H
 
+#include <stdbool.h>
+
 #include <grpc/grpc_security.h>
 
 #include "src/core/lib/channel/handshaker.h"
 #include "src/core/lib/iomgr/endpoint.h"
 #include "src/core/lib/iomgr/tcp_server.h"
-#include "src/core/lib/tsi/transport_security_interface.h"
+#include "src/core/tsi/ssl_transport_security.h"
+#include "src/core/tsi/transport_security_interface.h"
 
 /* --- status enum. --- */
 
@@ -184,13 +187,10 @@ grpc_server_security_connector *grpc_fake_server_security_connector_create(
     void);
 
 /* Config for ssl clients. */
+
 typedef struct {
-  unsigned char *pem_private_key;
-  size_t pem_private_key_size;
-  unsigned char *pem_cert_chain;
-  size_t pem_cert_chain_size;
-  unsigned char *pem_root_certs;
-  size_t pem_root_certs_size;
+  tsi_ssl_pem_key_cert_pair pem_key_cert_pair;
+  char *pem_root_certs;
 } grpc_ssl_config;
 
 /* Creates an SSL channel_security_connector.
@@ -211,21 +211,17 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
     const grpc_ssl_config *config, const char *target_name,
     const char *overridden_target_name, grpc_channel_security_connector **sc);
 
-/* Gets the default ssl roots. */
-size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs);
+/* Gets the default ssl roots. Returns NULL if not found. */
+const char *grpc_get_default_ssl_roots(void);
 
 /* Exposed for TESTING ONLY!. */
 grpc_slice grpc_get_default_ssl_roots_for_testing(void);
 
 /* Config for ssl servers. */
 typedef struct {
-  unsigned char **pem_private_keys;
-  size_t *pem_private_keys_sizes;
-  unsigned char **pem_cert_chains;
-  size_t *pem_cert_chains_sizes;
+  tsi_ssl_pem_key_cert_pair *pem_key_cert_pairs;
   size_t num_key_cert_pairs;
-  unsigned char *pem_root_certs;
-  size_t pem_root_certs_size;
+  char *pem_root_certs;
   grpc_ssl_client_certificate_request_type client_certificate_request;
 } grpc_ssl_server_config;
 
diff --git a/src/core/lib/security/transport/security_handshaker.c b/src/core/lib/security/transport/security_handshaker.c
index 7065d261ba2112c3eb931df9223750273fde1235..509b4b556d6eb784a28aa820d1ee402997cd9615 100644
--- a/src/core/lib/security/transport/security_handshaker.c
+++ b/src/core/lib/security/transport/security_handshaker.c
@@ -120,7 +120,7 @@ static void security_handshake_failed_locked(grpc_exec_ctx *exec_ctx,
   if (error == GRPC_ERROR_NONE) {
     // If we were shut down after the handshake succeeded but before an
     // endpoint callback was invoked, we need to generate our own error.
-    error = GRPC_ERROR_CREATE("Handshaker shutdown");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshaker shutdown");
   }
   const char *msg = grpc_error_string(error);
   gpr_log(GPR_DEBUG, "Security handshake failed: %s", msg);
@@ -156,7 +156,8 @@ static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *arg,
       tsi_handshaker_create_frame_protector(h->handshaker, NULL, &protector);
   if (result != TSI_OK) {
     error = grpc_set_tsi_error_result(
-        GRPC_ERROR_CREATE("Frame protector creation failed"), result);
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Frame protector creation failed"),
+        result);
     security_handshake_failed_locked(exec_ctx, h, error);
     goto done;
   }
@@ -191,7 +192,7 @@ static grpc_error *check_peer_locked(grpc_exec_ctx *exec_ctx,
   tsi_result result = tsi_handshaker_extract_peer(h->handshaker, &peer);
   if (result != TSI_OK) {
     return grpc_set_tsi_error_result(
-        GRPC_ERROR_CREATE("Peer extraction failed"), result);
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Peer extraction failed"), result);
   }
   grpc_security_connector_check_peer(exec_ctx, h->connector, peer,
                                      &h->auth_context, &h->on_peer_checked);
@@ -215,8 +216,8 @@ static grpc_error *send_handshake_bytes_to_peer_locked(grpc_exec_ctx *exec_ctx,
     }
   } while (result == TSI_INCOMPLETE_DATA);
   if (result != TSI_OK) {
-    return grpc_set_tsi_error_result(GRPC_ERROR_CREATE("Handshake failed"),
-                                     result);
+    return grpc_set_tsi_error_result(
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake failed"), result);
   }
   // Send data.
   grpc_slice to_send =
@@ -234,8 +235,8 @@ static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
   gpr_mu_lock(&h->mu);
   if (error != GRPC_ERROR_NONE || h->shutdown) {
     security_handshake_failed_locked(
-        exec_ctx, h,
-        GRPC_ERROR_CREATE_REFERENCING("Handshake read failed", &error, 1));
+        exec_ctx, h, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                         "Handshake read failed", &error, 1));
     gpr_mu_unlock(&h->mu);
     security_handshaker_unref(exec_ctx, h);
     return;
@@ -270,8 +271,9 @@ static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
   }
   if (result != TSI_OK) {
     security_handshake_failed_locked(
-        exec_ctx, h, grpc_set_tsi_error_result(
-                         GRPC_ERROR_CREATE("Handshake failed"), result));
+        exec_ctx, h,
+        grpc_set_tsi_error_result(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake failed"), result));
     gpr_mu_unlock(&h->mu);
     security_handshaker_unref(exec_ctx, h);
     return;
@@ -285,12 +287,11 @@ static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
   if (num_left_overs > 0) {
     /* Put the leftovers in our buffer (ownership transfered). */
     if (has_left_overs_in_current_slice) {
-      grpc_slice_buffer_add(
-          &h->left_overs,
-          grpc_slice_split_tail(&h->args->read_buffer->slices[i],
-                                consumed_slice_size));
+      grpc_slice tail = grpc_slice_split_tail(&h->args->read_buffer->slices[i],
+                                              consumed_slice_size);
+      grpc_slice_buffer_add(&h->left_overs, tail);
       /* split_tail above increments refcount. */
-      grpc_slice_unref_internal(exec_ctx, h->args->read_buffer->slices[i]);
+      grpc_slice_unref_internal(exec_ctx, tail);
     }
     grpc_slice_buffer_addn(
         &h->left_overs, &h->args->read_buffer->slices[i + 1],
@@ -314,8 +315,8 @@ static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx, void *arg,
   gpr_mu_lock(&h->mu);
   if (error != GRPC_ERROR_NONE || h->shutdown) {
     security_handshake_failed_locked(
-        exec_ctx, h,
-        GRPC_ERROR_CREATE_REFERENCING("Handshake write failed", &error, 1));
+        exec_ctx, h, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                         "Handshake write failed", &error, 1));
     gpr_mu_unlock(&h->mu);
     security_handshaker_unref(exec_ctx, h);
     return;
@@ -429,7 +430,8 @@ static void fail_handshaker_do_handshake(grpc_exec_ctx *exec_ctx,
                                          grpc_closure *on_handshake_done,
                                          grpc_handshaker_args *args) {
   grpc_closure_sched(exec_ctx, on_handshake_done,
-                     GRPC_ERROR_CREATE("Failed to create security handshaker"));
+                     GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                         "Failed to create security handshaker"));
 }
 
 static const grpc_handshaker_vtable fail_handshaker_vtable = {
diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c
index 14619d97caf1ff8d7ab3f0ac6ef18700de9f1437..1aca76f9e85b3d555c21a9f8a3ec6b8da49c592e 100644
--- a/src/core/lib/security/transport/server_auth_filter.c
+++ b/src/core/lib/security/transport/server_auth_filter.c
@@ -49,7 +49,7 @@ typedef struct call_data {
      up-call on transport_op, and remember to call our on_done_recv member after
      handling it. */
   grpc_closure auth_on_recv;
-  grpc_transport_stream_op *transport_op;
+  grpc_transport_stream_op_batch *transport_op;
   grpc_metadata_array md;
   const grpc_metadata *consumed_md;
   size_t num_consumed_md;
@@ -138,15 +138,15 @@ static void on_md_processing_done(
     error_details = error_details != NULL
                         ? error_details
                         : "Authentication metadata processing failed.";
-    calld->transport_op->send_initial_metadata = NULL;
-    if (calld->transport_op->send_message != NULL) {
-      grpc_byte_stream_destroy(&exec_ctx, calld->transport_op->send_message);
-      calld->transport_op->send_message = NULL;
+    if (calld->transport_op->send_message) {
+      grpc_byte_stream_destroy(
+          &exec_ctx, calld->transport_op->payload->send_message.send_message);
+      calld->transport_op->payload->send_message.send_message = NULL;
     }
-    calld->transport_op->send_trailing_metadata = NULL;
-    grpc_closure_sched(&exec_ctx, calld->on_done_recv,
-                       grpc_error_set_int(GRPC_ERROR_CREATE(error_details),
-                                          GRPC_ERROR_INT_GRPC_STATUS, status));
+    grpc_closure_sched(
+        &exec_ctx, calld->on_done_recv,
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_details),
+                           GRPC_ERROR_INT_GRPC_STATUS, status));
   }
 
   grpc_exec_ctx_finish(&exec_ctx);
@@ -158,7 +158,7 @@ static void auth_on_recv(grpc_exec_ctx *exec_ctx, void *user_data,
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
   if (error == GRPC_ERROR_NONE) {
-    if (chand->creds->processor.process != NULL) {
+    if (chand->creds != NULL && chand->creds->processor.process != NULL) {
       calld->md = metadata_batch_to_md_array(calld->recv_initial_metadata);
       chand->creds->processor.process(
           chand->creds->processor.state, calld->auth_context,
@@ -170,14 +170,17 @@ static void auth_on_recv(grpc_exec_ctx *exec_ctx, void *user_data,
 }
 
 static void set_recv_ops_md_callbacks(grpc_call_element *elem,
-                                      grpc_transport_stream_op *op) {
+                                      grpc_transport_stream_op_batch *op) {
   call_data *calld = elem->call_data;
 
-  if (op->recv_initial_metadata != NULL) {
+  if (op->recv_initial_metadata) {
     /* substitute our callback for the higher callback */
-    calld->recv_initial_metadata = op->recv_initial_metadata;
-    calld->on_done_recv = op->recv_initial_metadata_ready;
-    op->recv_initial_metadata_ready = &calld->auth_on_recv;
+    calld->recv_initial_metadata =
+        op->payload->recv_initial_metadata.recv_initial_metadata;
+    calld->on_done_recv =
+        op->payload->recv_initial_metadata.recv_initial_metadata_ready;
+    op->payload->recv_initial_metadata.recv_initial_metadata_ready =
+        &calld->auth_on_recv;
     calld->transport_op = op;
   }
 }
@@ -189,7 +192,7 @@ static void set_recv_ops_md_callbacks(grpc_call_element *elem,
    that is being sent or received. */
 static void auth_start_transport_op(grpc_exec_ctx *exec_ctx,
                                     grpc_call_element *elem,
-                                    grpc_transport_stream_op *op) {
+                                    grpc_transport_stream_op_batch *op) {
   set_recv_ops_md_callbacks(elem, op);
   grpc_call_next_op(exec_ctx, elem, op);
 }
@@ -227,7 +230,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
 /* Destructor for call_data */
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
-                              void *ignored) {}
+                              grpc_closure *ignored) {}
 
 /* Constructor for channel_data */
 static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
@@ -242,7 +245,6 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
 
   GPR_ASSERT(!args->is_last);
   GPR_ASSERT(auth_context != NULL);
-  GPR_ASSERT(creds != NULL);
 
   /* initialize members */
   chand->auth_context =
diff --git a/src/core/lib/security/transport/tsi_error.c b/src/core/lib/security/transport/tsi_error.c
index afc17335672280282507d0485205903593a4e9be..eae0a676b0e780bb5f7ca5b7da662096ad96b047 100644
--- a/src/core/lib/security/transport/tsi_error.c
+++ b/src/core/lib/security/transport/tsi_error.c
@@ -34,7 +34,9 @@
 #include "src/core/lib/security/transport/tsi_error.h"
 
 grpc_error *grpc_set_tsi_error_result(grpc_error *error, tsi_result result) {
-  return grpc_error_set_int(grpc_error_set_str(error, GRPC_ERROR_STR_TSI_ERROR,
-                                               tsi_result_to_string(result)),
-                            GRPC_ERROR_INT_TSI_CODE, result);
+  return grpc_error_set_int(
+      grpc_error_set_str(
+          error, GRPC_ERROR_STR_TSI_ERROR,
+          grpc_slice_from_static_string(tsi_result_to_string(result))),
+      GRPC_ERROR_INT_TSI_CODE, result);
 }
diff --git a/src/core/lib/security/transport/tsi_error.h b/src/core/lib/security/transport/tsi_error.h
index 636fbb89cf5d7f9b6a8a9ad0c9fea5de995b144d..b84693b5de2102dcb566c898db638df2d6a0c0d8 100644
--- a/src/core/lib/security/transport/tsi_error.h
+++ b/src/core/lib/security/transport/tsi_error.h
@@ -35,7 +35,7 @@
 #define GRPC_CORE_LIB_SECURITY_TRANSPORT_TSI_ERROR_H
 
 #include "src/core/lib/iomgr/error.h"
-#include "src/core/lib/tsi/transport_security_interface.h"
+#include "src/core/tsi/transport_security_interface.h"
 
 grpc_error *grpc_set_tsi_error_result(grpc_error *error, tsi_result result);
 
diff --git a/src/core/lib/security/util/b64.c b/src/core/lib/slice/b64.c
similarity index 92%
rename from src/core/lib/security/util/b64.c
rename to src/core/lib/slice/b64.c
index 09c821313162069aaaccaede30609d0d9447e5b6..d9091646e06fd78c51b2144da05cd3bd54a2cb82 100644
--- a/src/core/lib/security/util/b64.c
+++ b/src/core/lib/slice/b64.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/lib/security/util/b64.h"
+#include "src/core/lib/slice/b64.h"
 
 #include <stdint.h>
 #include <string.h>
@@ -71,15 +71,31 @@ static const char base64_url_safe_chars[] =
 
 char *grpc_base64_encode(const void *vdata, size_t data_size, int url_safe,
                          int multiline) {
-  const unsigned char *data = vdata;
-  const char *base64_chars =
-      url_safe ? base64_url_safe_chars : base64_url_unsafe_chars;
+  size_t result_projected_size =
+      grpc_base64_estimate_encoded_size(data_size, url_safe, multiline);
+  char *result = gpr_malloc(result_projected_size);
+  grpc_base64_encode_core(result, vdata, data_size, url_safe, multiline);
+  return result;
+}
+
+size_t grpc_base64_estimate_encoded_size(size_t data_size, int url_safe,
+                                         int multiline) {
   size_t result_projected_size =
       4 * ((data_size + 3) / 3) +
       2 * (multiline ? (data_size / (3 * GRPC_BASE64_MULTILINE_NUM_BLOCKS))
                      : 0) +
       1;
-  char *result = gpr_malloc(result_projected_size);
+  return result_projected_size;
+}
+
+void grpc_base64_encode_core(char *result, const void *vdata, size_t data_size,
+                             int url_safe, int multiline) {
+  const unsigned char *data = vdata;
+  const char *base64_chars =
+      url_safe ? base64_url_safe_chars : base64_url_unsafe_chars;
+  const size_t result_projected_size =
+      grpc_base64_estimate_encoded_size(data_size, url_safe, multiline);
+
   char *current = result;
   size_t num_blocks = 0;
   size_t i = 0;
@@ -119,7 +135,6 @@ char *grpc_base64_encode(const void *vdata, size_t data_size, int url_safe,
   GPR_ASSERT(current >= result);
   GPR_ASSERT((uintptr_t)(current - result) < result_projected_size);
   result[current - result] = '\0';
-  return result;
 }
 
 grpc_slice grpc_base64_decode(grpc_exec_ctx *exec_ctx, const char *b64,
@@ -187,7 +202,7 @@ static int decode_group(const unsigned char *codes, size_t num_codes,
 
 grpc_slice grpc_base64_decode_with_len(grpc_exec_ctx *exec_ctx, const char *b64,
                                        size_t b64_len, int url_safe) {
-  grpc_slice result = grpc_slice_malloc(b64_len);
+  grpc_slice result = GRPC_SLICE_MALLOC(b64_len);
   unsigned char *current = GRPC_SLICE_START_PTR(result);
   size_t result_size = 0;
   unsigned char codes[4];
diff --git a/src/core/lib/security/util/b64.h b/src/core/lib/slice/b64.h
similarity index 74%
rename from src/core/lib/security/util/b64.h
rename to src/core/lib/slice/b64.h
index d42a136f61a2a85e4e02b3c316feb6caf3a4ca45..5cc821f4bf350c3fd624b6febcc36fe011204927 100644
--- a/src/core/lib/security/util/b64.h
+++ b/src/core/lib/slice/b64.h
@@ -31,16 +31,28 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SECURITY_UTIL_B64_H
-#define GRPC_CORE_LIB_SECURITY_UTIL_B64_H
+#ifndef GRPC_CORE_LIB_SLICE_B64_H
+#define GRPC_CORE_LIB_SLICE_B64_H
 
 #include <grpc/slice.h>
 
 /* Encodes data using base64. It is the caller's responsability to free
-   the returned char * using gpr_free. Returns NULL on NULL input. */
+   the returned char * using gpr_free. Returns NULL on NULL input.
+   TODO(makdharma) : change the flags to bool from int */
 char *grpc_base64_encode(const void *data, size_t data_size, int url_safe,
                          int multiline);
 
+/* estimate the upper bound on size of base64 encoded data. The actual size
+ * is guaranteed to be less than or equal to the size returned here. */
+size_t grpc_base64_estimate_encoded_size(size_t data_size, int url_safe,
+                                         int multiline);
+
+/* Encodes data using base64 and write it to memory pointed to by result. It is
+ * the caller's responsiblity to allocate enough memory in |result| to fit the
+ * encoded data. */
+void grpc_base64_encode_core(char *result, const void *vdata, size_t data_size,
+                             int url_safe, int multiline);
+
 /* Decodes data according to the base64 specification. Returns an empty
    slice in case of failure. */
 grpc_slice grpc_base64_decode(grpc_exec_ctx *exec_ctx, const char *b64,
@@ -50,4 +62,4 @@ grpc_slice grpc_base64_decode(grpc_exec_ctx *exec_ctx, const char *b64,
 grpc_slice grpc_base64_decode_with_len(grpc_exec_ctx *exec_ctx, const char *b64,
                                        size_t b64_len, int url_safe);
 
-#endif /* GRPC_CORE_LIB_SECURITY_UTIL_B64_H */
+#endif /* GRPC_CORE_LIB_SLICE_B64_H */
diff --git a/src/core/lib/slice/percent_encoding.c b/src/core/lib/slice/percent_encoding.c
index c76c58d371e95e379a2cb50625eefcd81df7b971..a77c69763f112d7de9e084286e64c84556d5320f 100644
--- a/src/core/lib/slice/percent_encoding.c
+++ b/src/core/lib/slice/percent_encoding.c
@@ -71,7 +71,7 @@ grpc_slice grpc_percent_encode_slice(grpc_slice slice,
     return grpc_slice_ref_internal(slice);
   }
   // second pass: actually encode
-  grpc_slice out = grpc_slice_malloc(output_length);
+  grpc_slice out = GRPC_SLICE_MALLOC(output_length);
   uint8_t *q = GRPC_SLICE_START_PTR(out);
   for (p = slice_start; p < slice_end; p++) {
     if (is_unreserved_character(*p, unreserved_bytes)) {
@@ -125,7 +125,7 @@ bool grpc_strict_percent_decode_slice(grpc_slice slice_in,
     return true;
   }
   p = GRPC_SLICE_START_PTR(slice_in);
-  *slice_out = grpc_slice_malloc(out_length);
+  *slice_out = GRPC_SLICE_MALLOC(out_length);
   uint8_t *q = GRPC_SLICE_START_PTR(*slice_out);
   while (p != in_end) {
     if (*p == '%') {
@@ -163,7 +163,7 @@ grpc_slice grpc_permissive_percent_decode_slice(grpc_slice slice_in) {
     return grpc_slice_ref_internal(slice_in);
   }
   p = GRPC_SLICE_START_PTR(slice_in);
-  grpc_slice out = grpc_slice_malloc(out_length);
+  grpc_slice out = GRPC_SLICE_MALLOC(out_length);
   uint8_t *q = GRPC_SLICE_START_PTR(out);
   while (p != in_end) {
     if (*p == '%') {
diff --git a/src/core/lib/slice/slice.c b/src/core/lib/slice/slice.c
index 1cddf062cd435875f161b006b989f6eae42ca5ea..b90738fd1aaf9ba15aec78886b2a9a9db87c69bc 100644
--- a/src/core/lib/slice/slice.c
+++ b/src/core/lib/slice/slice.c
@@ -55,6 +55,13 @@ grpc_slice grpc_empty_slice(void) {
   return out;
 }
 
+grpc_slice grpc_slice_copy(grpc_slice s) {
+  grpc_slice out = GRPC_SLICE_MALLOC(GRPC_SLICE_LENGTH(s));
+  memcpy(GRPC_SLICE_START_PTR(out), GRPC_SLICE_START_PTR(s),
+         GRPC_SLICE_LENGTH(s));
+  return out;
+}
+
 grpc_slice grpc_slice_ref_internal(grpc_slice slice) {
   if (slice.refcount) {
     slice.refcount->vtable->ref(slice.refcount);
@@ -197,7 +204,8 @@ grpc_slice grpc_slice_new_with_len(void *p, size_t len,
 }
 
 grpc_slice grpc_slice_from_copied_buffer(const char *source, size_t length) {
-  grpc_slice slice = grpc_slice_malloc(length);
+  if (length == 0) return grpc_empty_slice();
+  grpc_slice slice = GRPC_SLICE_MALLOC(length);
   memcpy(GRPC_SLICE_START_PTR(slice), source, length);
   return slice;
 }
@@ -227,35 +235,42 @@ static const grpc_slice_refcount_vtable malloc_vtable = {
     malloc_ref, malloc_unref, grpc_slice_default_eq_impl,
     grpc_slice_default_hash_impl};
 
+grpc_slice grpc_slice_malloc_large(size_t length) {
+  grpc_slice slice;
+
+  /* Memory layout used by the slice created here:
+
+     +-----------+----------------------------------------------------------+
+     | refcount  | bytes                                                    |
+     +-----------+----------------------------------------------------------+
+
+     refcount is a malloc_refcount
+     bytes is an array of bytes of the requested length
+     Both parts are placed in the same allocation returned from gpr_malloc */
+  malloc_refcount *rc = gpr_malloc(sizeof(malloc_refcount) + length);
+
+  /* Initial refcount on rc is 1 - and it's up to the caller to release
+     this reference. */
+  gpr_ref_init(&rc->refs, 1);
+
+  rc->base.vtable = &malloc_vtable;
+  rc->base.sub_refcount = &rc->base;
+
+  /* Build up the slice to be returned. */
+  /* The slices refcount points back to the allocated block. */
+  slice.refcount = &rc->base;
+  /* The data bytes are placed immediately after the refcount struct */
+  slice.data.refcounted.bytes = (uint8_t *)(rc + 1);
+  /* And the length of the block is set to the requested length */
+  slice.data.refcounted.length = length;
+  return slice;
+}
+
 grpc_slice grpc_slice_malloc(size_t length) {
   grpc_slice slice;
 
   if (length > sizeof(slice.data.inlined.bytes)) {
-    /* Memory layout used by the slice created here:
-
-       +-----------+----------------------------------------------------------+
-       | refcount  | bytes                                                    |
-       +-----------+----------------------------------------------------------+
-
-       refcount is a malloc_refcount
-       bytes is an array of bytes of the requested length
-       Both parts are placed in the same allocation returned from gpr_malloc */
-    malloc_refcount *rc = gpr_malloc(sizeof(malloc_refcount) + length);
-
-    /* Initial refcount on rc is 1 - and it's up to the caller to release
-       this reference. */
-    gpr_ref_init(&rc->refs, 1);
-
-    rc->base.vtable = &malloc_vtable;
-    rc->base.sub_refcount = &rc->base;
-
-    /* Build up the slice to be returned. */
-    /* The slices refcount points back to the allocated block. */
-    slice.refcount = &rc->base;
-    /* The data bytes are placed immediately after the refcount struct */
-    slice.data.refcounted.bytes = (uint8_t *)(rc + 1);
-    /* And the length of the block is set to the requested length */
-    slice.data.refcounted.length = length;
+    return grpc_slice_malloc_large(length);
   } else {
     /* small slice: just inline the data */
     slice.refcount = NULL;
@@ -305,7 +320,8 @@ grpc_slice grpc_slice_sub(grpc_slice source, size_t begin, size_t end) {
   return subset;
 }
 
-grpc_slice grpc_slice_split_tail(grpc_slice *source, size_t split) {
+grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice *source, size_t split,
+                                           grpc_slice_ref_whom ref_whom) {
   grpc_slice tail;
 
   if (source->refcount == NULL) {
@@ -319,28 +335,46 @@ grpc_slice grpc_slice_split_tail(grpc_slice *source, size_t split) {
   } else {
     size_t tail_length = source->data.refcounted.length - split;
     GPR_ASSERT(source->data.refcounted.length >= split);
-    if (tail_length < sizeof(tail.data.inlined.bytes)) {
+    if (tail_length < sizeof(tail.data.inlined.bytes) &&
+        ref_whom != GRPC_SLICE_REF_TAIL) {
       /* Copy out the bytes - it'll be cheaper than refcounting */
       tail.refcount = NULL;
       tail.data.inlined.length = (uint8_t)tail_length;
       memcpy(tail.data.inlined.bytes, source->data.refcounted.bytes + split,
              tail_length);
+      source->refcount = source->refcount->sub_refcount;
     } else {
       /* Build the result */
-      tail.refcount = source->refcount->sub_refcount;
-      /* Bump the refcount */
-      tail.refcount->vtable->ref(tail.refcount);
+      switch (ref_whom) {
+        case GRPC_SLICE_REF_TAIL:
+          tail.refcount = source->refcount->sub_refcount;
+          source->refcount = &noop_refcount;
+          break;
+        case GRPC_SLICE_REF_HEAD:
+          tail.refcount = &noop_refcount;
+          source->refcount = source->refcount->sub_refcount;
+          break;
+        case GRPC_SLICE_REF_BOTH:
+          tail.refcount = source->refcount->sub_refcount;
+          source->refcount = source->refcount->sub_refcount;
+          /* Bump the refcount */
+          tail.refcount->vtable->ref(tail.refcount);
+          break;
+      }
       /* Point into the source array */
       tail.data.refcounted.bytes = source->data.refcounted.bytes + split;
       tail.data.refcounted.length = tail_length;
     }
-    source->refcount = source->refcount->sub_refcount;
     source->data.refcounted.length = split;
   }
 
   return tail;
 }
 
+grpc_slice grpc_slice_split_tail(grpc_slice *source, size_t split) {
+  return grpc_slice_split_tail_maybe_ref(source, split, GRPC_SLICE_REF_BOTH);
+}
+
 grpc_slice grpc_slice_split_head(grpc_slice *source, size_t split) {
   grpc_slice head;
 
@@ -382,8 +416,9 @@ grpc_slice grpc_slice_split_head(grpc_slice *source, size_t split) {
 }
 
 int grpc_slice_default_eq_impl(grpc_slice a, grpc_slice b) {
-  return GRPC_SLICE_LENGTH(a) == GRPC_SLICE_LENGTH(b) &&
-         0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b),
+  if (GRPC_SLICE_LENGTH(a) != GRPC_SLICE_LENGTH(b)) return false;
+  if (GRPC_SLICE_LENGTH(a) == 0) return true;
+  return 0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b),
                      GRPC_SLICE_LENGTH(a));
 }
 
@@ -457,7 +492,7 @@ int grpc_slice_slice(grpc_slice haystack, grpc_slice needle) {
 }
 
 grpc_slice grpc_slice_dup(grpc_slice a) {
-  grpc_slice copy = grpc_slice_malloc(GRPC_SLICE_LENGTH(a));
+  grpc_slice copy = GRPC_SLICE_MALLOC(GRPC_SLICE_LENGTH(a));
   memcpy(GRPC_SLICE_START_PTR(copy), GRPC_SLICE_START_PTR(a),
          GRPC_SLICE_LENGTH(a));
   return copy;
diff --git a/src/core/lib/slice/slice_buffer.c b/src/core/lib/slice/slice_buffer.c
index 9176dc8a4208a1c70ac3bc138cf966f278332afd..e8d41ca0f7d8203a3dd7e07b9a2664dac4d783be 100644
--- a/src/core/lib/slice/slice_buffer.c
+++ b/src/core/lib/slice/slice_buffer.c
@@ -46,27 +46,29 @@
 #define GROW(x) (3 * (x) / 2)
 
 static void maybe_embiggen(grpc_slice_buffer *sb) {
-  if (sb->base_slices != sb->slices) {
-    memmove(sb->base_slices, sb->slices, sb->count * sizeof(grpc_slice));
-    sb->slices = sb->base_slices;
-  }
-
   /* How far away from sb->base_slices is sb->slices pointer */
   size_t slice_offset = (size_t)(sb->slices - sb->base_slices);
   size_t slice_count = sb->count + slice_offset;
 
   if (slice_count == sb->capacity) {
-    sb->capacity = GROW(sb->capacity);
-    GPR_ASSERT(sb->capacity > slice_count);
-    if (sb->base_slices == sb->inlined) {
-      sb->base_slices = gpr_malloc(sb->capacity * sizeof(grpc_slice));
-      memcpy(sb->base_slices, sb->inlined, slice_count * sizeof(grpc_slice));
+    if (sb->base_slices != sb->slices) {
+      /* Make room by moving elements if there's still space unused */
+      memmove(sb->base_slices, sb->slices, sb->count * sizeof(grpc_slice));
+      sb->slices = sb->base_slices;
     } else {
-      sb->base_slices =
-          gpr_realloc(sb->base_slices, sb->capacity * sizeof(grpc_slice));
-    }
+      /* Allocate more memory if no more space is available */
+      sb->capacity = GROW(sb->capacity);
+      GPR_ASSERT(sb->capacity > slice_count);
+      if (sb->base_slices == sb->inlined) {
+        sb->base_slices = gpr_malloc(sb->capacity * sizeof(grpc_slice));
+        memcpy(sb->base_slices, sb->inlined, slice_count * sizeof(grpc_slice));
+      } else {
+        sb->base_slices =
+            gpr_realloc(sb->base_slices, sb->capacity * sizeof(grpc_slice));
+      }
 
-    sb->slices = sb->base_slices + slice_offset;
+      sb->slices = sb->base_slices + slice_offset;
+    }
   }
 }
 
@@ -251,16 +253,18 @@ void grpc_slice_buffer_move_into(grpc_slice_buffer *src,
   src->length = 0;
 }
 
-void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
-                                  grpc_slice_buffer *dst) {
-  size_t output_len = dst->length + n;
-  size_t new_input_len = src->length - n;
+static void slice_buffer_move_first_maybe_ref(grpc_slice_buffer *src, size_t n,
+                                              grpc_slice_buffer *dst,
+                                              bool incref) {
   GPR_ASSERT(src->length >= n);
   if (src->length == n) {
     grpc_slice_buffer_move_into(src, dst);
     return;
   }
 
+  size_t output_len = dst->length + n;
+  size_t new_input_len = src->length - n;
+
   while (src->count > 0) {
     grpc_slice slice = grpc_slice_buffer_take_first(src);
     size_t slice_len = GRPC_SLICE_LENGTH(slice);
@@ -270,11 +274,18 @@ void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
     } else if (n == slice_len) {
       grpc_slice_buffer_add(dst, slice);
       break;
-    } else { /* n < slice_len */
-      grpc_slice_buffer_undo_take_first(src, grpc_slice_split_tail(&slice, n));
+    } else if (incref) { /* n < slice_len */
+      grpc_slice_buffer_undo_take_first(
+          src, grpc_slice_split_tail_maybe_ref(&slice, n, GRPC_SLICE_REF_BOTH));
       GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == n);
       grpc_slice_buffer_add(dst, slice);
       break;
+    } else { /* n < slice_len */
+      grpc_slice_buffer_undo_take_first(
+          src, grpc_slice_split_tail_maybe_ref(&slice, n, GRPC_SLICE_REF_TAIL));
+      GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == n);
+      grpc_slice_buffer_add_indexed(dst, slice);
+      break;
     }
   }
   GPR_ASSERT(dst->length == output_len);
@@ -282,6 +293,16 @@ void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
   GPR_ASSERT(src->count > 0);
 }
 
+void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
+                                  grpc_slice_buffer *dst) {
+  slice_buffer_move_first_maybe_ref(src, n, dst, true);
+}
+
+void grpc_slice_buffer_move_first_no_ref(grpc_slice_buffer *src, size_t n,
+                                         grpc_slice_buffer *dst) {
+  slice_buffer_move_first_maybe_ref(src, n, dst, false);
+}
+
 void grpc_slice_buffer_move_first_into_buffer(grpc_exec_ctx *exec_ctx,
                                               grpc_slice_buffer *src, size_t n,
                                               void *dst) {
diff --git a/src/core/lib/slice/slice_hash_table.c b/src/core/lib/slice/slice_hash_table.c
index 219567f36f8049aed864ed9f9dc35557a9f4ab1e..444f22aa196c974f5b9baa0ad4289c57bd6654a7 100644
--- a/src/core/lib/slice/slice_hash_table.c
+++ b/src/core/lib/slice/slice_hash_table.c
@@ -42,56 +42,47 @@
 
 struct grpc_slice_hash_table {
   gpr_refcount refs;
+  void (*destroy_value)(grpc_exec_ctx* exec_ctx, void* value);
   size_t size;
+  size_t max_num_probes;
   grpc_slice_hash_table_entry* entries;
 };
 
 static bool is_empty(grpc_slice_hash_table_entry* entry) {
-  return entry->vtable == NULL;
+  return entry->value == NULL;
 }
 
-// Helper function for insert and get operations that performs quadratic
-// probing (https://en.wikipedia.org/wiki/Quadratic_probing).
-static size_t grpc_slice_hash_table_find_index(
-    const grpc_slice_hash_table* table, const grpc_slice key, bool find_empty) {
-  size_t hash = grpc_slice_hash(key);
-  for (size_t i = 0; i < table->size; ++i) {
-    const size_t idx = (hash + i * i) % table->size;
+static void grpc_slice_hash_table_add(grpc_slice_hash_table* table,
+                                      grpc_slice key, void* value) {
+  GPR_ASSERT(value != NULL);
+  const size_t hash = grpc_slice_hash(key);
+  for (size_t offset = 0; offset < table->size; ++offset) {
+    const size_t idx = (hash + offset) % table->size;
     if (is_empty(&table->entries[idx])) {
-      return find_empty ? idx : table->size;
-    }
-    if (grpc_slice_eq(table->entries[idx].key, key)) {
-      return idx;
+      table->entries[idx].key = key;
+      table->entries[idx].value = value;
+      // Keep track of the maximum number of probes needed, since this
+      // provides an upper bound for lookups.
+      if (offset > table->max_num_probes) table->max_num_probes = offset;
+      return;
     }
   }
-  return table->size;  // Not found.
-}
-
-static void grpc_slice_hash_table_add(
-    grpc_slice_hash_table* table, grpc_slice key, void* value,
-    const grpc_slice_hash_table_vtable* vtable) {
-  GPR_ASSERT(value != NULL);
-  const size_t idx =
-      grpc_slice_hash_table_find_index(table, key, true /* find_empty */);
-  GPR_ASSERT(idx != table->size);  // Table should never be full.
-  grpc_slice_hash_table_entry* entry = &table->entries[idx];
-  entry->key = grpc_slice_ref_internal(key);
-  entry->value = vtable->copy_value(value);
-  entry->vtable = vtable;
+  GPR_ASSERT(false);  // Table should never be full.
 }
 
 grpc_slice_hash_table* grpc_slice_hash_table_create(
-    size_t num_entries, grpc_slice_hash_table_entry* entries) {
+    size_t num_entries, grpc_slice_hash_table_entry* entries,
+    void (*destroy_value)(grpc_exec_ctx* exec_ctx, void* value)) {
   grpc_slice_hash_table* table = gpr_zalloc(sizeof(*table));
   gpr_ref_init(&table->refs, 1);
-  // Quadratic probing gets best performance when the table is no more
-  // than half full.
+  table->destroy_value = destroy_value;
+  // Keep load factor low to improve performance of lookups.
   table->size = num_entries * 2;
   const size_t entry_size = sizeof(grpc_slice_hash_table_entry) * table->size;
   table->entries = gpr_zalloc(entry_size);
   for (size_t i = 0; i < num_entries; ++i) {
     grpc_slice_hash_table_entry* entry = &entries[i];
-    grpc_slice_hash_table_add(table, entry->key, entry->value, entry->vtable);
+    grpc_slice_hash_table_add(table, entry->key, entry->value);
   }
   return table;
 }
@@ -108,7 +99,7 @@ void grpc_slice_hash_table_unref(grpc_exec_ctx* exec_ctx,
       grpc_slice_hash_table_entry* entry = &table->entries[i];
       if (!is_empty(entry)) {
         grpc_slice_unref_internal(exec_ctx, entry->key);
-        entry->vtable->destroy_value(exec_ctx, entry->value);
+        table->destroy_value(exec_ctx, entry->value);
       }
     }
     gpr_free(table->entries);
@@ -118,8 +109,15 @@ void grpc_slice_hash_table_unref(grpc_exec_ctx* exec_ctx,
 
 void* grpc_slice_hash_table_get(const grpc_slice_hash_table* table,
                                 const grpc_slice key) {
-  const size_t idx =
-      grpc_slice_hash_table_find_index(table, key, false /* find_empty */);
-  if (idx == table->size) return NULL;  // Not found.
-  return table->entries[idx].value;
+  const size_t hash = grpc_slice_hash(key);
+  // We cap the number of probes at the max number recorded when
+  // populating the table.
+  for (size_t offset = 0; offset <= table->max_num_probes; ++offset) {
+    const size_t idx = (hash + offset) % table->size;
+    if (is_empty(&table->entries[idx])) break;
+    if (grpc_slice_eq(table->entries[idx].key, key)) {
+      return table->entries[idx].value;
+    }
+  }
+  return NULL;  // Not found.
 }
diff --git a/src/core/lib/slice/slice_hash_table.h b/src/core/lib/slice/slice_hash_table.h
index d0c27122d7f2b6efd538df1d7016738319918a88..1e61c5eb11624b8880b6343e6e9bc61c1b412637 100644
--- a/src/core/lib/slice/slice_hash_table.h
+++ b/src/core/lib/slice/slice_hash_table.h
@@ -37,33 +37,28 @@
 /** Hash table implementation.
  *
  * This implementation uses open addressing
- * (https://en.wikipedia.org/wiki/Open_addressing) with quadratic
- * probing (https://en.wikipedia.org/wiki/Quadratic_probing).
+ * (https://en.wikipedia.org/wiki/Open_addressing) with linear
+ * probing (https://en.wikipedia.org/wiki/Linear_probing).
  *
  * The keys are \a grpc_slice objects.  The values are arbitrary pointers
- * with a common vtable.
+ * with a common destroy function.
  *
  * Hash tables are intentionally immutable, to avoid the need for locking.
  */
 
 typedef struct grpc_slice_hash_table grpc_slice_hash_table;
 
-typedef struct grpc_slice_hash_table_vtable {
-  void (*destroy_value)(grpc_exec_ctx *exec_ctx, void *value);
-  void *(*copy_value)(void *value);
-} grpc_slice_hash_table_vtable;
-
 typedef struct grpc_slice_hash_table_entry {
   grpc_slice key;
   void *value; /* Must not be NULL. */
-  const grpc_slice_hash_table_vtable *vtable;
 } grpc_slice_hash_table_entry;
 
 /** Creates a new hash table of containing \a entries, which is an array
-    of length \a num_entries.
-    Creates its own copy of all keys and values from \a entries. */
+    of length \a num_entries.  Takes ownership of all keys and values in
+    \a entries.  Values will be cleaned up via \a destroy_value(). */
 grpc_slice_hash_table *grpc_slice_hash_table_create(
-    size_t num_entries, grpc_slice_hash_table_entry *entries);
+    size_t num_entries, grpc_slice_hash_table_entry *entries,
+    void (*destroy_value)(grpc_exec_ctx *exec_ctx, void *value));
 
 grpc_slice_hash_table *grpc_slice_hash_table_ref(grpc_slice_hash_table *table);
 void grpc_slice_hash_table_unref(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/lib/support/arena.c b/src/core/lib/support/arena.c
new file mode 100644
index 0000000000000000000000000000000000000000..7bcb983f245afa8cd447a8e47ef204ec4b114304
--- /dev/null
+++ b/src/core/lib/support/arena.c
@@ -0,0 +1,98 @@
+/*
+ *
+ * Copyright 2017, 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/lib/support/arena.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/atm.h>
+#include <grpc/support/log.h>
+#include <grpc/support/useful.h>
+
+#define ROUND_UP_TO_ALIGNMENT_SIZE(x) \
+  (((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u))
+
+typedef struct zone {
+  size_t size_begin;
+  size_t size_end;
+  gpr_atm next_atm;
+} zone;
+
+struct gpr_arena {
+  gpr_atm size_so_far;
+  zone initial_zone;
+};
+
+gpr_arena *gpr_arena_create(size_t initial_size) {
+  initial_size = ROUND_UP_TO_ALIGNMENT_SIZE(initial_size);
+  gpr_arena *a = gpr_zalloc(sizeof(gpr_arena) + initial_size);
+  a->initial_zone.size_end = initial_size;
+  return a;
+}
+
+size_t gpr_arena_destroy(gpr_arena *arena) {
+  gpr_atm size = gpr_atm_no_barrier_load(&arena->size_so_far);
+  zone *z = (zone *)gpr_atm_no_barrier_load(&arena->initial_zone.next_atm);
+  gpr_free(arena);
+  while (z) {
+    zone *next_z = (zone *)gpr_atm_no_barrier_load(&z->next_atm);
+    gpr_free(z);
+    z = next_z;
+  }
+  return (size_t)size;
+}
+
+void *gpr_arena_alloc(gpr_arena *arena, size_t size) {
+  size = ROUND_UP_TO_ALIGNMENT_SIZE(size);
+  size_t start =
+      (size_t)gpr_atm_no_barrier_fetch_add(&arena->size_so_far, size);
+  zone *z = &arena->initial_zone;
+  while (start > z->size_end) {
+    zone *next_z = (zone *)gpr_atm_acq_load(&z->next_atm);
+    if (next_z == NULL) {
+      size_t next_z_size = (size_t)gpr_atm_no_barrier_load(&arena->size_so_far);
+      next_z = gpr_zalloc(sizeof(zone) + next_z_size);
+      next_z->size_begin = z->size_end;
+      next_z->size_end = z->size_end + next_z_size;
+      if (!gpr_atm_rel_cas(&z->next_atm, (gpr_atm)NULL, (gpr_atm)next_z)) {
+        gpr_free(next_z);
+        next_z = (zone *)gpr_atm_acq_load(&z->next_atm);
+      }
+    }
+    z = next_z;
+  }
+  if (start + size > z->size_end) {
+    return gpr_arena_alloc(arena, size);
+  }
+  GPR_ASSERT(start >= z->size_begin);
+  GPR_ASSERT(start + size <= z->size_end);
+  return ((char *)(z + 1)) + start - z->size_begin;
+}
diff --git a/src/core/lib/support/arena.h b/src/core/lib/support/arena.h
new file mode 100644
index 0000000000000000000000000000000000000000..c28033ffc356fa637df7dea2564393f798daca63
--- /dev/null
+++ b/src/core/lib/support/arena.h
@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright 2017, 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.
+ *
+ */
+
+// \file Arena based allocator
+// Allows very fast allocation of memory, but that memory cannot be freed until
+// the arena as a whole is freed
+// Tracks the total memory allocated against it, so that future arenas can
+// pre-allocate the right amount of memory
+
+#ifndef GRPC_CORE_LIB_SUPPORT_ARENA_H
+#define GRPC_CORE_LIB_SUPPORT_ARENA_H
+
+#include <stddef.h>
+
+typedef struct gpr_arena gpr_arena;
+
+// Create an arena, with \a initial_size bytes in the first allocated buffer
+gpr_arena *gpr_arena_create(size_t initial_size);
+// Allocate \a size bytes from the arena
+void *gpr_arena_alloc(gpr_arena *arena, size_t size);
+// Destroy an arena, returning the total number of bytes allocated
+size_t gpr_arena_destroy(gpr_arena *arena);
+
+#endif /* GRPC_CORE_LIB_SUPPORT_ARENA_H */
diff --git a/src/core/lib/support/atm.c b/src/core/lib/support/atm.c
new file mode 100644
index 0000000000000000000000000000000000000000..06e8432caf887d6cb9bc06084dccab6c484c84cd
--- /dev/null
+++ b/src/core/lib/support/atm.c
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright 2017, 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/support/atm.h>
+#include <grpc/support/useful.h>
+
+gpr_atm gpr_atm_no_barrier_clamped_add(gpr_atm *value, gpr_atm delta,
+                                       gpr_atm min, gpr_atm max) {
+  gpr_atm current;
+  gpr_atm new;
+  do {
+    current = gpr_atm_no_barrier_load(value);
+    new = GPR_CLAMP(current + delta, min, max);
+    if (new == current) break;
+  } while (!gpr_atm_no_barrier_cas(value, current, new));
+  return new;
+}
diff --git a/src/core/lib/support/atomic.h b/src/core/lib/support/atomic.h
new file mode 100644
index 0000000000000000000000000000000000000000..2226189b6813335518febac60bd712348d939abf
--- /dev/null
+++ b/src/core/lib/support/atomic.h
@@ -0,0 +1,45 @@
+/*
+ *
+ * Copyright 2017, 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_CORE_LIB_SUPPORT_ATOMIC_H
+#define GRPC_CORE_LIB_SUPPORT_ATOMIC_H
+
+#include <grpc/support/port_platform.h>
+
+#ifdef GPR_HAS_CXX11_ATOMIC
+#include "src/core/lib/support/atomic_with_std.h"
+#else
+#include "src/core/lib/support/atomic_with_atm.h"
+#endif
+
+#endif /* GRPC_CORE_LIB_SUPPORT_ATOMIC_H */
diff --git a/src/core/lib/support/atomic_with_atm.h b/src/core/lib/support/atomic_with_atm.h
new file mode 100644
index 0000000000000000000000000000000000000000..55727f1dee2c87919d4e6f2fc2c3c34814de57f2
--- /dev/null
+++ b/src/core/lib/support/atomic_with_atm.h
@@ -0,0 +1,70 @@
+/*
+ *
+ * Copyright 2017, 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_CORE_LIB_SUPPORT_ATOMIC_WITH_ATM_H
+#define GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_ATM_H
+
+#include <grpc/support/atm.h>
+
+namespace grpc_core {
+
+enum MemoryOrderRelaxed { memory_order_relaxed };
+
+template <class T>
+class atomic;
+
+template <>
+class atomic<bool> {
+ public:
+  atomic() { gpr_atm_no_barrier_store(&x_, static_cast<gpr_atm>(false)); }
+  explicit atomic(bool x) {
+    gpr_atm_no_barrier_store(&x_, static_cast<gpr_atm>(x));
+  }
+
+  bool compare_exchange_strong(bool& expected, bool update, MemoryOrderRelaxed,
+                               MemoryOrderRelaxed) {
+    if (!gpr_atm_no_barrier_cas(&x_, static_cast<gpr_atm>(expected),
+                                static_cast<gpr_atm>(update))) {
+      expected = gpr_atm_no_barrier_load(&x_) != 0;
+      return false;
+    }
+    return true;
+  }
+
+ private:
+  gpr_atm x_;
+};
+
+}  // namespace grpc_core
+
+#endif /* GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_ATM_H */
diff --git a/include/grpc++/impl/codegen/status_helper.h b/src/core/lib/support/atomic_with_std.h
similarity index 82%
rename from include/grpc++/impl/codegen/status_helper.h
rename to src/core/lib/support/atomic_with_std.h
index bfe45d9e5b1ccc0d26d598927aaa4b8d419050a8..7e9c19efe8aec7e9b2cf9cddd4959b75aacc9b83 100644
--- a/include/grpc++/impl/codegen/status_helper.h
+++ b/src/core/lib/support/atomic_with_std.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2016, Google Inc.
+ * Copyright 2017, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,17 +31,18 @@
  *
  */
 
-#ifndef GRPCXX_IMPL_CODEGEN_STATUS_HELPER_H
-#define GRPCXX_IMPL_CODEGEN_STATUS_HELPER_H
+#ifndef GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_STD_H
+#define GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_STD_H
 
-#include <grpc++/impl/codegen/status.h>
+#include <atomic>
 
-namespace grpc {
+namespace grpc_core {
 
-inline StatusCode GetCanonicalCode(const Status& status) {
-  return status.error_code();
-}
+template <class T>
+using atomic = std::atomic<T>;
 
-}  // namespace grpc
+typedef std::memory_order memory_order;
 
-#endif  // GRPCXX_IMPL_CODEGEN_STATUS_HELPER_H
+}  // namespace grpc_core
+
+#endif /* GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_STD_H */
diff --git a/src/core/lib/support/avl.c b/src/core/lib/support/avl.c
index acf8fd5a552e224e3178d95ad9eab74b18d4c32b..ffa10c1e4fc0e6aed34f89f1a45aa8bd1929ff0b 100644
--- a/src/core/lib/support/avl.c
+++ b/src/core/lib/support/avl.c
@@ -205,8 +205,8 @@ static gpr_avl_node *rebalance(const gpr_avl_vtable *vtable, void *key,
   }
 }
 
-static gpr_avl_node *add(const gpr_avl_vtable *vtable, gpr_avl_node *node,
-                         void *key, void *value) {
+static gpr_avl_node *add_key(const gpr_avl_vtable *vtable, gpr_avl_node *node,
+                             void *key, void *value) {
   long cmp;
   if (node == NULL) {
     return new_node(key, value, NULL, NULL);
@@ -217,17 +217,17 @@ static gpr_avl_node *add(const gpr_avl_vtable *vtable, gpr_avl_node *node,
   } else if (cmp > 0) {
     return rebalance(
         vtable, vtable->copy_key(node->key), vtable->copy_value(node->value),
-        add(vtable, node->left, key, value), ref_node(node->right));
+        add_key(vtable, node->left, key, value), ref_node(node->right));
   } else {
     return rebalance(vtable, vtable->copy_key(node->key),
                      vtable->copy_value(node->value), ref_node(node->left),
-                     add(vtable, node->right, key, value));
+                     add_key(vtable, node->right, key, value));
   }
 }
 
 gpr_avl gpr_avl_add(gpr_avl avl, void *key, void *value) {
   gpr_avl_node *old_root = avl.root;
-  avl.root = add(avl.vtable, avl.root, key, value);
+  avl.root = add_key(avl.vtable, avl.root, key, value);
   assert_invariants(avl.root);
   unref_node(avl.vtable, old_root);
   return avl;
@@ -247,8 +247,8 @@ static gpr_avl_node *in_order_tail(gpr_avl_node *node) {
   return node;
 }
 
-static gpr_avl_node *remove(const gpr_avl_vtable *vtable, gpr_avl_node *node,
-                            void *key) {
+static gpr_avl_node *remove_key(const gpr_avl_vtable *vtable,
+                                gpr_avl_node *node, void *key) {
   long cmp;
   if (node == NULL) {
     return NULL;
@@ -263,27 +263,27 @@ static gpr_avl_node *remove(const gpr_avl_vtable *vtable, gpr_avl_node *node,
       gpr_avl_node *h = in_order_head(node->right);
       return rebalance(vtable, vtable->copy_key(h->key),
                        vtable->copy_value(h->value), ref_node(node->left),
-                       remove(vtable, node->right, h->key));
+                       remove_key(vtable, node->right, h->key));
     } else {
       gpr_avl_node *h = in_order_tail(node->left);
       return rebalance(
           vtable, vtable->copy_key(h->key), vtable->copy_value(h->value),
-          remove(vtable, node->left, h->key), ref_node(node->right));
+          remove_key(vtable, node->left, h->key), ref_node(node->right));
     }
   } else if (cmp > 0) {
-    return rebalance(vtable, vtable->copy_key(node->key),
-                     vtable->copy_value(node->value),
-                     remove(vtable, node->left, key), ref_node(node->right));
+    return rebalance(
+        vtable, vtable->copy_key(node->key), vtable->copy_value(node->value),
+        remove_key(vtable, node->left, key), ref_node(node->right));
   } else {
     return rebalance(vtable, vtable->copy_key(node->key),
                      vtable->copy_value(node->value), ref_node(node->left),
-                     remove(vtable, node->right, key));
+                     remove_key(vtable, node->right, key));
   }
 }
 
 gpr_avl gpr_avl_remove(gpr_avl avl, void *key) {
   gpr_avl_node *old_root = avl.root;
-  avl.root = remove(avl.vtable, avl.root, key);
+  avl.root = remove_key(avl.vtable, avl.root, key);
   assert_invariants(avl.root);
   unref_node(avl.vtable, old_root);
   return avl;
diff --git a/src/core/lib/support/cpu_linux.c b/src/core/lib/support/cpu_linux.c
index d6f7e7d3da6ff355394dbcd055cfeb3a5ec03ae4..b826dde16013da9642fb421061fde793c4257947 100644
--- a/src/core/lib/support/cpu_linux.c
+++ b/src/core/lib/support/cpu_linux.c
@@ -67,12 +67,17 @@ unsigned gpr_cpu_num_cores(void) {
 }
 
 unsigned gpr_cpu_current_cpu(void) {
+#ifdef GPR_MUSL_LIBC_COMPAT
+  // sched_getcpu() is undefined on musl
+  return 0;
+#else
   int cpu = sched_getcpu();
   if (cpu < 0) {
     gpr_log(GPR_ERROR, "Error determining current CPU: %s\n", strerror(errno));
     return 0;
   }
   return (unsigned)cpu;
+#endif
 }
 
 #endif /* GPR_CPU_LINUX */
diff --git a/src/core/lib/support/memory.h b/src/core/lib/support/memory.h
new file mode 100644
index 0000000000000000000000000000000000000000..6eff94eff78326f5dd0c81af89ec1ac43cd336ad
--- /dev/null
+++ b/src/core/lib/support/memory.h
@@ -0,0 +1,74 @@
+/*
+ *
+ * Copyright 2017, 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_CORE_LIB_SUPPORT_MEMORY_H
+#define GRPC_CORE_LIB_SUPPORT_MEMORY_H
+
+#include <grpc/support/alloc.h>
+
+#include <memory>
+#include <utility>
+
+namespace grpc_core {
+
+// Alternative to new, since we cannot use it (for fear of libstdc++)
+template <typename T, typename... Args>
+inline T* New(Args&&... args) {
+  void* p = gpr_malloc(sizeof(T));
+  return new (p) T(std::forward<Args>(args)...);
+}
+
+// Alternative to delete, since we cannot use it (for fear of libstdc++)
+template <typename T>
+inline void Delete(T* p) {
+  p->~T();
+  gpr_free(p);
+}
+
+template <typename T>
+class DefaultDelete {
+ public:
+  void operator()(T* p) { Delete(p); }
+};
+
+template <typename T, typename Deleter = DefaultDelete<T>>
+using UniquePtr = std::unique_ptr<T, Deleter>;
+
+template <typename T, typename... Args>
+inline UniquePtr<T> MakeUnique(Args&&... args) {
+  return UniquePtr<T>(New<T>(std::forward<Args>(args)...));
+}
+
+}  // namespace grpc_core
+
+#endif /* GRPC_CORE_LIB_SUPPORT_MEMORY_H */
diff --git a/src/core/lib/support/stack_lockfree.c b/src/core/lib/support/stack_lockfree.c
index 9d7c9e5a3816fe8b3916ae39f623585ea8a13b0e..dfbd3fb1251f751e3562759086857cc7f5a4bd1c 100644
--- a/src/core/lib/support/stack_lockfree.c
+++ b/src/core/lib/support/stack_lockfree.c
@@ -72,28 +72,20 @@ typedef union lockfree_node {
 struct gpr_stack_lockfree {
   lockfree_node *entries;
   lockfree_node head; /* An atomic entry describing curr head */
-
-#ifndef NDEBUG
-  /* Bitmap of pushed entries to check for double-push or pop */
-  gpr_atm pushed[(INVALID_ENTRY_INDEX + 1) / (8 * sizeof(gpr_atm))];
-#endif
 };
 
 gpr_stack_lockfree *gpr_stack_lockfree_create(size_t entries) {
   gpr_stack_lockfree *stack;
-  stack = gpr_malloc(sizeof(*stack));
+  stack = (gpr_stack_lockfree *)gpr_malloc(sizeof(*stack));
   /* Since we only allocate 16 bits to represent an entry number,
    * make sure that we are within the desired range */
   /* Reserve the highest entry number as a dummy */
   GPR_ASSERT(entries < INVALID_ENTRY_INDEX);
-  stack->entries = gpr_malloc_aligned(entries * sizeof(stack->entries[0]),
-                                      ENTRY_ALIGNMENT_BITS);
+  stack->entries = (lockfree_node *)gpr_malloc_aligned(
+      entries * sizeof(stack->entries[0]), ENTRY_ALIGNMENT_BITS);
   /* Clear out all entries */
   memset(stack->entries, 0, entries * sizeof(stack->entries[0]));
   memset(&stack->head, 0, sizeof(stack->head));
-#ifndef NDEBUG
-  memset(&stack->pushed, 0, sizeof(stack->pushed));
-#endif
 
   GPR_ASSERT(sizeof(stack->entries->atm) == sizeof(stack->entries->contents));
 
@@ -130,19 +122,6 @@ int gpr_stack_lockfree_push(gpr_stack_lockfree *stack, int entry) {
   newhead.contents.aba_ctr = ++curent.contents.aba_ctr;
   gpr_atm_no_barrier_store(&stack->entries[entry].atm, curent.atm);
 
-#ifndef NDEBUG
-  /* Check for double push */
-  {
-    int pushed_index = entry / (int)(8 * sizeof(gpr_atm));
-    int pushed_bit = entry % (int)(8 * sizeof(gpr_atm));
-    gpr_atm old_val;
-
-    old_val = gpr_atm_no_barrier_fetch_add(&stack->pushed[pushed_index],
-                                           ((gpr_atm)1 << pushed_bit));
-    GPR_ASSERT((old_val & (((gpr_atm)1) << pushed_bit)) == 0);
-  }
-#endif
-
   do {
     /* Atomically get the existing head value for use */
     head.atm = gpr_atm_no_barrier_load(&(stack->head.atm));
@@ -168,18 +147,6 @@ int gpr_stack_lockfree_pop(gpr_stack_lockfree *stack) {
         gpr_atm_no_barrier_load(&(stack->entries[head.contents.index].atm));
 
   } while (!gpr_atm_no_barrier_cas(&(stack->head.atm), head.atm, newhead.atm));
-#ifndef NDEBUG
-  /* Check for valid pop */
-  {
-    int pushed_index = head.contents.index / (8 * sizeof(gpr_atm));
-    int pushed_bit = head.contents.index % (8 * sizeof(gpr_atm));
-    gpr_atm old_val;
-
-    old_val = gpr_atm_no_barrier_fetch_add(&stack->pushed[pushed_index],
-                                           -((gpr_atm)1 << pushed_bit));
-    GPR_ASSERT((old_val & (((gpr_atm)1) << pushed_bit)) != 0);
-  }
-#endif
 
   return head.contents.index;
 }
diff --git a/src/core/lib/support/sync.c b/src/core/lib/support/sync.c
index 44b83f8175aafb4f1935a9b52b22cc1729a63594..b52f004f743746a0f7833db31605562e88f1a8bc 100644
--- a/src/core/lib/support/sync.c
+++ b/src/core/lib/support/sync.c
@@ -37,6 +37,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 
+#include <assert.h>
+
 /* Number of mutexes to allocate for events, to avoid lock contention.
    Should be a prime. */
 enum { event_sync_partitions = 31 };
@@ -99,8 +101,12 @@ void gpr_ref_init(gpr_refcount *r, int n) { gpr_atm_rel_store(&r->count, n); }
 void gpr_ref(gpr_refcount *r) { gpr_atm_no_barrier_fetch_add(&r->count, 1); }
 
 void gpr_ref_non_zero(gpr_refcount *r) {
+#ifndef NDEBUG
   gpr_atm prior = gpr_atm_no_barrier_fetch_add(&r->count, 1);
-  GPR_ASSERT(prior > 0);
+  assert(prior > 0);
+#else
+  gpr_ref(r);
+#endif
 }
 
 void gpr_refn(gpr_refcount *r, int n) {
@@ -113,6 +119,10 @@ int gpr_unref(gpr_refcount *r) {
   return prior == 1;
 }
 
+int gpr_ref_is_unique(gpr_refcount *r) {
+  return gpr_atm_acq_load(&r->count) == 1;
+}
+
 void gpr_stats_init(gpr_stats_counter *c, intptr_t n) {
   gpr_atm_rel_store(&c->value, n);
 }
diff --git a/src/core/lib/support/time.c b/src/core/lib/support/time.c
index 5a7d043aed8f352fb0b10b6b42cd561a4bc44357..c5f94d46f7bf2268fdbbbdeca2767266e822b2bc 100644
--- a/src/core/lib/support/time.c
+++ b/src/core/lib/support/time.c
@@ -42,7 +42,7 @@
 int gpr_time_cmp(gpr_timespec a, gpr_timespec b) {
   int cmp = (a.tv_sec > b.tv_sec) - (a.tv_sec < b.tv_sec);
   GPR_ASSERT(a.clock_type == b.clock_type);
-  if (cmp == 0) {
+  if (cmp == 0 && a.tv_sec != INT64_MAX && a.tv_sec != INT64_MIN) {
     cmp = (a.tv_nsec > b.tv_nsec) - (a.tv_nsec < b.tv_nsec);
   }
   return cmp;
@@ -244,15 +244,9 @@ gpr_timespec gpr_convert_clock_type(gpr_timespec t, gpr_clock_type clock_type) {
     return t;
   }
 
-  if (t.tv_nsec == 0) {
-    if (t.tv_sec == INT64_MAX) {
-      t.clock_type = clock_type;
-      return t;
-    }
-    if (t.tv_sec == INT64_MIN) {
-      t.clock_type = clock_type;
-      return t;
-    }
+  if (t.tv_sec == INT64_MAX || t.tv_sec == INT64_MIN) {
+    t.clock_type = clock_type;
+    return t;
   }
 
   if (clock_type == GPR_TIMESPAN) {
diff --git a/src/core/lib/support/time_posix.c b/src/core/lib/support/time_posix.c
index a69c501e9fbaa339fbf13f5fda6e2a90c92b65bc..9bfec7782a2cf8f687455dd14d9d16c6befbcb00 100644
--- a/src/core/lib/support/time_posix.c
+++ b/src/core/lib/support/time_posix.c
@@ -42,6 +42,7 @@
 #ifdef __linux__
 #include <sys/syscall.h>
 #endif
+#include <grpc/support/atm.h>
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include "src/core/lib/support/block_annotate.h"
@@ -144,7 +145,14 @@ static gpr_timespec now_impl(gpr_clock_type clock) {
 
 gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type) = now_impl;
 
+#ifdef GPR_LOW_LEVEL_COUNTERS
+gpr_atm gpr_now_call_count;
+#endif
+
 gpr_timespec gpr_now(gpr_clock_type clock_type) {
+#ifdef GPR_LOW_LEVEL_COUNTERS
+  __atomic_fetch_add(&gpr_now_call_count, 1, __ATOMIC_RELAXED);
+#endif
   return gpr_now_impl(clock_type);
 }
 
diff --git a/src/core/lib/support/tmpfile_posix.c b/src/core/lib/support/tmpfile_posix.c
index 0cd4bb6fc3cedcf2aad4548b10aa1c69627c65cd..5771c158e07bd92c5e5d3dbda10a08634318f74e 100644
--- a/src/core/lib/support/tmpfile_posix.c
+++ b/src/core/lib/support/tmpfile_posix.c
@@ -50,34 +50,34 @@
 
 FILE *gpr_tmpfile(const char *prefix, char **tmp_filename) {
   FILE *result = NULL;
-  char *template;
+  char *filename_template;
   int fd;
 
   if (tmp_filename != NULL) *tmp_filename = NULL;
 
-  gpr_asprintf(&template, "/tmp/%s_XXXXXX", prefix);
-  GPR_ASSERT(template != NULL);
+  gpr_asprintf(&filename_template, "/tmp/%s_XXXXXX", prefix);
+  GPR_ASSERT(filename_template != NULL);
 
-  fd = mkstemp(template);
+  fd = mkstemp(filename_template);
   if (fd == -1) {
-    gpr_log(GPR_ERROR, "mkstemp failed for template %s with error %s.",
-            template, strerror(errno));
+    gpr_log(GPR_ERROR, "mkstemp failed for filename_template %s with error %s.",
+            filename_template, strerror(errno));
     goto end;
   }
   result = fdopen(fd, "w+");
   if (result == NULL) {
     gpr_log(GPR_ERROR, "Could not open file %s from fd %d (error = %s).",
-            template, fd, strerror(errno));
-    unlink(template);
+            filename_template, fd, strerror(errno));
+    unlink(filename_template);
     close(fd);
     goto end;
   }
 
 end:
   if (result != NULL && tmp_filename != NULL) {
-    *tmp_filename = template;
+    *tmp_filename = filename_template;
   } else {
-    gpr_free(template);
+    gpr_free(filename_template);
   }
   return result;
 }
diff --git a/src/core/lib/support/wrap_memcpy.c b/src/core/lib/support/wrap_memcpy.c
index 15c289f7b8bb410b1b48296f6495e7081d5115b0..deb8d6b198a00253ee38ef6628dc42a49c705dda 100644
--- a/src/core/lib/support/wrap_memcpy.c
+++ b/src/core/lib/support/wrap_memcpy.c
@@ -31,6 +31,8 @@
  *
  */
 
+#include <grpc/support/port_platform.h>
+
 #include <string.h>
 
 /* Provide a wrapped memcpy for targets that need to be backwards
@@ -40,7 +42,7 @@
  */
 
 #ifdef __linux__
-#ifdef __x86_64__
+#if defined(__x86_64__) && !defined(GPR_MUSL_LIBC_COMPAT)
 __asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
 void *__wrap_memcpy(void *destination, const void *source, size_t num) {
   return memcpy(destination, source, num);
diff --git a/src/core/lib/surface/byte_buffer_reader.c b/src/core/lib/surface/byte_buffer_reader.c
index 1a6ccdaddb6144d31bfcb4d3be9381eae897da48..539b0142783fb8876485b15925fb018239e514fb 100644
--- a/src/core/lib/surface/byte_buffer_reader.c
+++ b/src/core/lib/surface/byte_buffer_reader.c
@@ -124,7 +124,7 @@ grpc_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader) {
   grpc_slice in_slice;
   size_t bytes_read = 0;
   const size_t input_size = grpc_byte_buffer_length(reader->buffer_out);
-  grpc_slice out_slice = grpc_slice_malloc(input_size);
+  grpc_slice out_slice = GRPC_SLICE_MALLOC(input_size);
   uint8_t *const outbuf = GRPC_SLICE_START_PTR(out_slice); /* just an alias */
 
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index cc57654ea418a04a848ee5a93f9104a6bbe40593..752580658305e180642a5cdffdc363edf5b9f5de 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -51,6 +51,7 @@
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
+#include "src/core/lib/support/arena.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/call.h"
@@ -116,40 +117,61 @@ static received_status unpack_received_status(gpr_atm atm) {
 
 typedef struct batch_control {
   grpc_call *call;
-  grpc_cq_completion cq_completion;
+  /* Share memory for cq_completion and notify_tag as they are never needed
+     simultaneously. Each byte used in this data structure count as six bytes
+     per call, so any savings we can make are worthwhile,
+
+     We use notify_tag to determine whether or not to send notification to the
+     completion queue. Once we've made that determination, we can reuse the
+     memory for cq_completion. */
+  union {
+    grpc_cq_completion cq_completion;
+    struct {
+      /* Any given op indicates completion by either (a) calling a closure or
+         (b) sending a notification on the call's completion queue.  If
+         \a is_closure is true, \a tag indicates a closure to be invoked;
+         otherwise, \a tag indicates the tag to be used in the notification to
+         be sent to the completion queue. */
+      void *tag;
+      bool is_closure;
+    } notify_tag;
+  } completion_data;
   grpc_closure finish_batch;
-  void *notify_tag;
   gpr_refcount steps_to_complete;
 
   grpc_error *errors[MAX_ERRORS_PER_BATCH];
   gpr_atm num_errors;
 
-  uint8_t send_initial_metadata;
-  uint8_t send_message;
-  uint8_t send_final_op;
-  uint8_t recv_initial_metadata;
-  uint8_t recv_message;
-  uint8_t recv_final_op;
-  uint8_t is_notify_tag_closure;
-
-  /* TODO(ctiller): now that this is inlined, figure out how much of the above
-                    state can be eliminated */
-  grpc_transport_stream_op op;
+  grpc_transport_stream_op_batch op;
 } batch_control;
 
+typedef struct {
+  gpr_mu child_list_mu;
+  grpc_call *first_child;
+} parent_call;
+
+typedef struct {
+  grpc_call *parent;
+  /** siblings: children of the same parent form a list, and this list is
+     protected under
+      parent->mu */
+  grpc_call *sibling_next;
+  grpc_call *sibling_prev;
+} child_call;
+
 struct grpc_call {
+  gpr_refcount ext_ref;
+  gpr_arena *arena;
   grpc_completion_queue *cq;
   grpc_polling_entity pollent;
   grpc_channel *channel;
-  grpc_call *parent;
-  grpc_call *first_child;
   gpr_timespec start_time;
-  /* TODO(ctiller): share with cq if possible? */
-  gpr_mu mu;
+  /* parent_call* */ gpr_atm parent_call_atm;
+  child_call *child_call;
 
   /* client or server call */
   bool is_client;
-  /** has grpc_call_destroy been called */
+  /** has grpc_call_unref been called */
   bool destroy_called;
   /** flag indicating that cancellation is inherited */
   bool cancellation_is_inherited;
@@ -160,12 +182,14 @@ struct grpc_call {
   bool received_initial_metadata;
   bool receiving_message;
   bool requested_final_op;
-  bool received_final_op;
+  gpr_atm any_ops_sent_atm;
+  gpr_atm received_final_op_atm;
 
   /* have we received initial metadata */
   bool has_initial_md_been_received;
 
-  batch_control active_batches[MAX_CONCURRENT_BATCHES];
+  batch_control *active_batches[MAX_CONCURRENT_BATCHES];
+  grpc_transport_stream_op_batch_payload stream_op_payload;
 
   /* first idx: is_receiving, second idx: is_trailing */
   grpc_metadata_batch metadata_batch[2][2];
@@ -195,12 +219,6 @@ struct grpc_call {
   int send_extra_metadata_count;
   gpr_timespec send_deadline;
 
-  /** siblings: children of the same parent form a list, and this list is
-     protected under
-      parent->mu */
-  grpc_call *sibling_next;
-  grpc_call *sibling_prev;
-
   grpc_slice_buffer_stream sending_stream;
 
   grpc_byte_stream *receiving_stream;
@@ -211,6 +229,8 @@ struct grpc_call {
   grpc_closure receiving_initial_metadata_ready;
   uint32_t test_only_last_message_flags;
 
+  grpc_closure release_call;
+
   union {
     struct {
       grpc_status_code *status;
@@ -225,6 +245,7 @@ struct grpc_call {
 };
 
 int grpc_call_error_trace = 0;
+int grpc_compression_trace = 0;
 
 #define CALL_STACK_FROM_CALL(call) ((grpc_call_stack *)((call) + 1))
 #define CALL_FROM_CALL_STACK(call_stack) (((grpc_call *)(call_stack)) - 1)
@@ -234,7 +255,7 @@ int grpc_call_error_trace = 0;
   CALL_FROM_CALL_STACK(grpc_call_stack_from_top_element(top_elem))
 
 static void execute_op(grpc_exec_ctx *exec_ctx, grpc_call *call,
-                       grpc_transport_stream_op *op);
+                       grpc_transport_stream_op_batch *op);
 static void cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
                                status_source source, grpc_status_code status,
                                const char *description);
@@ -259,10 +280,31 @@ static void add_batch_error(grpc_exec_ctx *exec_ctx, batch_control *bctl,
 static void add_init_error(grpc_error **composite, grpc_error *new) {
   if (new == GRPC_ERROR_NONE) return;
   if (*composite == GRPC_ERROR_NONE)
-    *composite = GRPC_ERROR_CREATE("Call creation failed");
+    *composite = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Call creation failed");
   *composite = grpc_error_add_child(*composite, new);
 }
 
+void *grpc_call_arena_alloc(grpc_call *call, size_t size) {
+  return gpr_arena_alloc(call->arena, size);
+}
+
+static parent_call *get_or_create_parent_call(grpc_call *call) {
+  parent_call *p = (parent_call *)gpr_atm_acq_load(&call->parent_call_atm);
+  if (p == NULL) {
+    p = gpr_arena_alloc(call->arena, sizeof(*p));
+    gpr_mu_init(&p->child_list_mu);
+    if (!gpr_atm_rel_cas(&call->parent_call_atm, (gpr_atm)NULL, (gpr_atm)p)) {
+      gpr_mu_destroy(&p->child_list_mu);
+      p = (parent_call *)gpr_atm_acq_load(&call->parent_call_atm);
+    }
+  }
+  return p;
+}
+
+static parent_call *get_parent_call(grpc_call *call) {
+  return (parent_call *)gpr_atm_acq_load(&call->parent_call_atm);
+}
+
 grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
                              const grpc_call_create_args *args,
                              grpc_call **out_call) {
@@ -272,16 +314,20 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
       grpc_channel_get_channel_stack(args->channel);
   grpc_call *call;
   GPR_TIMER_BEGIN("grpc_call_create", 0);
-  call = gpr_zalloc(sizeof(grpc_call) + channel_stack->call_stack_size);
+  gpr_arena *arena =
+      gpr_arena_create(grpc_channel_get_call_size_estimate(args->channel));
+  call = gpr_arena_alloc(arena,
+                         sizeof(grpc_call) + channel_stack->call_stack_size);
+  gpr_ref_init(&call->ext_ref, 1);
+  call->arena = arena;
   *out_call = call;
-  gpr_mu_init(&call->mu);
   call->channel = args->channel;
   call->cq = args->cq;
-  call->parent = args->parent_call;
   call->start_time = gpr_now(GPR_CLOCK_MONOTONIC);
   /* Always support no compression */
   GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE);
   call->is_client = args->server_transport_data == NULL;
+  call->stream_op_payload.context = call->context;
   grpc_slice path = grpc_empty_slice();
   if (call->is_client) {
     GPR_ASSERT(args->add_initial_metadata_count <
@@ -307,12 +353,20 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
   gpr_timespec send_deadline =
       gpr_convert_clock_type(args->send_deadline, GPR_CLOCK_MONOTONIC);
 
+  bool immediately_cancel = false;
+
   if (args->parent_call != NULL) {
+    child_call *cc = call->child_call =
+        gpr_arena_alloc(arena, sizeof(child_call));
+    call->child_call->parent = args->parent_call;
+
     GRPC_CALL_INTERNAL_REF(args->parent_call, "child");
     GPR_ASSERT(call->is_client);
     GPR_ASSERT(!args->parent_call->is_client);
 
-    gpr_mu_lock(&args->parent_call->mu);
+    parent_call *pc = get_or_create_parent_call(args->parent_call);
+
+    gpr_mu_lock(&pc->child_list_mu);
 
     if (args->propagation_mask & GRPC_PROPAGATE_DEADLINE) {
       send_deadline = gpr_time_min(
@@ -326,48 +380,60 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
      * call. */
     if (args->propagation_mask & GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT) {
       if (0 == (args->propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT)) {
-        add_init_error(&error,
-                       GRPC_ERROR_CREATE("Census tracing propagation requested "
-                                         "without Census context propagation"));
+        add_init_error(&error, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                   "Census tracing propagation requested "
+                                   "without Census context propagation"));
       }
       grpc_call_context_set(
           call, GRPC_CONTEXT_TRACING,
           args->parent_call->context[GRPC_CONTEXT_TRACING].value, NULL);
     } else if (args->propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT) {
-      add_init_error(&error,
-                     GRPC_ERROR_CREATE("Census context propagation requested "
-                                       "without Census tracing propagation"));
+      add_init_error(&error, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                 "Census context propagation requested "
+                                 "without Census tracing propagation"));
     }
     if (args->propagation_mask & GRPC_PROPAGATE_CANCELLATION) {
       call->cancellation_is_inherited = 1;
+      if (gpr_atm_acq_load(&args->parent_call->received_final_op_atm)) {
+        immediately_cancel = true;
+      }
     }
 
-    if (args->parent_call->first_child == NULL) {
-      args->parent_call->first_child = call;
-      call->sibling_next = call->sibling_prev = call;
+    if (pc->first_child == NULL) {
+      pc->first_child = call;
+      cc->sibling_next = cc->sibling_prev = call;
     } else {
-      call->sibling_next = args->parent_call->first_child;
-      call->sibling_prev = args->parent_call->first_child->sibling_prev;
-      call->sibling_next->sibling_prev = call->sibling_prev->sibling_next =
-          call;
+      cc->sibling_next = pc->first_child;
+      cc->sibling_prev = pc->first_child->child_call->sibling_prev;
+      cc->sibling_next->child_call->sibling_prev =
+          cc->sibling_prev->child_call->sibling_next = call;
     }
 
-    gpr_mu_unlock(&args->parent_call->mu);
+    gpr_mu_unlock(&pc->child_list_mu);
   }
 
   call->send_deadline = send_deadline;
 
   GRPC_CHANNEL_INTERNAL_REF(args->channel, "call");
-  /* initial refcount dropped by grpc_call_destroy */
+  /* initial refcount dropped by grpc_call_unref */
+  grpc_call_element_args call_args = {
+      .call_stack = CALL_STACK_FROM_CALL(call),
+      .server_transport_data = args->server_transport_data,
+      .context = call->context,
+      .path = path,
+      .start_time = call->start_time,
+      .deadline = send_deadline,
+      .arena = call->arena};
   add_init_error(&error, grpc_call_stack_init(exec_ctx, channel_stack, 1,
-                                              destroy_call, call, call->context,
-                                              args->server_transport_data, path,
-                                              call->start_time, send_deadline,
-                                              CALL_STACK_FROM_CALL(call)));
+                                              destroy_call, call, &call_args));
   if (error != GRPC_ERROR_NONE) {
     cancel_with_error(exec_ctx, call, STATUS_FROM_SURFACE,
                       GRPC_ERROR_REF(error));
   }
+  if (immediately_cancel) {
+    cancel_with_error(exec_ctx, call, STATUS_FROM_API_OVERRIDE,
+                      GRPC_ERROR_CANCELLED);
+  }
   if (args->cq != NULL) {
     GPR_ASSERT(
         args->pollset_set_alternative == NULL &&
@@ -420,6 +486,14 @@ void grpc_call_internal_unref(grpc_exec_ctx *exec_ctx, grpc_call *c REF_ARG) {
   GRPC_CALL_STACK_UNREF(exec_ctx, CALL_STACK_FROM_CALL(c), REF_REASON);
 }
 
+static void release_call(grpc_exec_ctx *exec_ctx, void *call,
+                         grpc_error *error) {
+  grpc_call *c = call;
+  grpc_channel *channel = c->channel;
+  grpc_channel_update_call_size_estimate(channel, gpr_arena_destroy(c->arena));
+  GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel, "call");
+}
+
 static void set_status_value_directly(grpc_status_code status, void *dest);
 static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
                          grpc_error *error) {
@@ -434,7 +508,10 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
   if (c->receiving_stream != NULL) {
     grpc_byte_stream_destroy(exec_ctx, c->receiving_stream);
   }
-  gpr_mu_destroy(&c->mu);
+  parent_call *pc = get_parent_call(c);
+  if (pc != NULL) {
+    gpr_mu_destroy(&pc->child_list_mu);
+  }
   for (ii = 0; ii < c->send_extra_metadata_count; ii++) {
     GRPC_MDELEM_UNREF(exec_ctx, c->send_extra_metadata[ii].md);
   }
@@ -446,7 +523,6 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
   if (c->cq) {
     GRPC_CQ_INTERNAL_UNREF(c->cq, "bind");
   }
-  grpc_channel *channel = c->channel;
 
   get_final_status(call, set_status_value_directly, &c->final_info.final_status,
                    NULL);
@@ -455,48 +531,52 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
 
   for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
     GRPC_ERROR_UNREF(
-        unpack_received_status(gpr_atm_no_barrier_load(&c->status[i])).error);
+        unpack_received_status(gpr_atm_acq_load(&c->status[i])).error);
   }
 
-  grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c), &c->final_info, c);
-  GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel, "call");
+  grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c), &c->final_info,
+                          grpc_closure_init(&c->release_call, release_call, c,
+                                            grpc_schedule_on_exec_ctx));
   GPR_TIMER_END("destroy_call", 0);
 }
 
-void grpc_call_destroy(grpc_call *c) {
-  int cancel;
-  grpc_call *parent = c->parent;
+void grpc_call_ref(grpc_call *c) { gpr_ref(&c->ext_ref); }
+
+void grpc_call_unref(grpc_call *c) {
+  if (!gpr_unref(&c->ext_ref)) return;
+
+  child_call *cc = c->child_call;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
-  GPR_TIMER_BEGIN("grpc_call_destroy", 0);
-  GRPC_API_TRACE("grpc_call_destroy(c=%p)", 1, (c));
+  GPR_TIMER_BEGIN("grpc_call_unref", 0);
+  GRPC_API_TRACE("grpc_call_unref(c=%p)", 1, (c));
 
-  if (parent) {
-    gpr_mu_lock(&parent->mu);
-    if (c == parent->first_child) {
-      parent->first_child = c->sibling_next;
-      if (c == parent->first_child) {
-        parent->first_child = NULL;
+  if (cc) {
+    parent_call *pc = get_parent_call(cc->parent);
+    gpr_mu_lock(&pc->child_list_mu);
+    if (c == pc->first_child) {
+      pc->first_child = cc->sibling_next;
+      if (c == pc->first_child) {
+        pc->first_child = NULL;
       }
-      c->sibling_prev->sibling_next = c->sibling_next;
-      c->sibling_next->sibling_prev = c->sibling_prev;
     }
-    gpr_mu_unlock(&parent->mu);
-    GRPC_CALL_INTERNAL_UNREF(&exec_ctx, parent, "child");
+    cc->sibling_prev->child_call->sibling_next = cc->sibling_next;
+    cc->sibling_next->child_call->sibling_prev = cc->sibling_prev;
+    gpr_mu_unlock(&pc->child_list_mu);
+    GRPC_CALL_INTERNAL_UNREF(&exec_ctx, cc->parent, "child");
   }
 
-  gpr_mu_lock(&c->mu);
   GPR_ASSERT(!c->destroy_called);
   c->destroy_called = 1;
-  cancel = !c->received_final_op;
-  gpr_mu_unlock(&c->mu);
+  bool cancel = gpr_atm_acq_load(&c->any_ops_sent_atm) != 0 &&
+                gpr_atm_acq_load(&c->received_final_op_atm) == 0;
   if (cancel) {
     cancel_with_error(&exec_ctx, c, STATUS_FROM_API_OVERRIDE,
                       GRPC_ERROR_CANCELLED);
   }
   GRPC_CALL_INTERNAL_UNREF(&exec_ctx, c, "destroy");
   grpc_exec_ctx_finish(&exec_ctx);
-  GPR_TIMER_END("grpc_call_destroy", 0);
+  GPR_TIMER_END("grpc_call_unref", 0);
 }
 
 grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved) {
@@ -510,13 +590,12 @@ grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved) {
 }
 
 static void execute_op(grpc_exec_ctx *exec_ctx, grpc_call *call,
-                       grpc_transport_stream_op *op) {
+                       grpc_transport_stream_op_batch *op) {
   grpc_call_element *elem;
 
   GPR_TIMER_BEGIN("execute_op", 0);
   elem = CALL_ELEM_FROM_CALL(call, 0);
-  op->context = call->context;
-  elem->filter->start_transport_stream_op(exec_ctx, elem, op);
+  elem->filter->start_transport_stream_op_batch(exec_ctx, elem, op);
   GPR_TIMER_END("execute_op", 0);
 }
 
@@ -554,60 +633,34 @@ grpc_call_error grpc_call_cancel_with_status(grpc_call *c,
       "c=%p, status=%d, description=%s, reserved=%p)",
       4, (c, (int)status, description, reserved));
   GPR_ASSERT(reserved == NULL);
-  gpr_mu_lock(&c->mu);
   cancel_with_status(&exec_ctx, c, STATUS_FROM_API_OVERRIDE, status,
                      description);
-  gpr_mu_unlock(&c->mu);
   grpc_exec_ctx_finish(&exec_ctx);
   return GRPC_CALL_OK;
 }
 
-typedef struct termination_closure {
-  grpc_closure closure;
-  grpc_call *call;
-  grpc_transport_stream_op op;
-} termination_closure;
-
-static void done_termination(grpc_exec_ctx *exec_ctx, void *tcp,
-                             grpc_error *error) {
-  termination_closure *tc = tcp;
-  GRPC_CALL_INTERNAL_UNREF(exec_ctx, tc->call, "termination");
-  gpr_free(tc);
-}
-
-static void send_termination(grpc_exec_ctx *exec_ctx, void *tcp,
+static void done_termination(grpc_exec_ctx *exec_ctx, void *call,
                              grpc_error *error) {
-  termination_closure *tc = tcp;
-  memset(&tc->op, 0, sizeof(tc->op));
-  tc->op.cancel_error = GRPC_ERROR_REF(error);
-  /* reuse closure to catch completion */
-  tc->op.on_complete = grpc_closure_init(&tc->closure, done_termination, tc,
-                                         grpc_schedule_on_exec_ctx);
-  execute_op(exec_ctx, tc->call, &tc->op);
-}
-
-static void terminate_with_error(grpc_exec_ctx *exec_ctx, grpc_call *c,
-                                 grpc_error *error) {
-  termination_closure *tc = gpr_malloc(sizeof(*tc));
-  memset(tc, 0, sizeof(*tc));
-  tc->call = c;
-  GRPC_CALL_INTERNAL_REF(tc->call, "termination");
-  grpc_closure_sched(exec_ctx, grpc_closure_init(&tc->closure, send_termination,
-                                                 tc, grpc_schedule_on_exec_ctx),
-                     error);
+  GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "termination");
 }
 
 static void cancel_with_error(grpc_exec_ctx *exec_ctx, grpc_call *c,
                               status_source source, grpc_error *error) {
+  GRPC_CALL_INTERNAL_REF(c, "termination");
   set_status_from_error(exec_ctx, c, source, GRPC_ERROR_REF(error));
-  terminate_with_error(exec_ctx, c, error);
+  grpc_transport_stream_op_batch *op = grpc_make_transport_stream_op(
+      grpc_closure_create(done_termination, c, grpc_schedule_on_exec_ctx));
+  op->cancel_stream = true;
+  op->payload->cancel_stream.cancel_error = error;
+  execute_op(exec_ctx, c, op);
 }
 
 static grpc_error *error_from_status(grpc_status_code status,
                                      const char *description) {
   return grpc_error_set_int(
-      grpc_error_set_str(GRPC_ERROR_CREATE(description),
-                         GRPC_ERROR_STR_GRPC_MESSAGE, description),
+      grpc_error_set_str(GRPC_ERROR_CREATE_FROM_COPIED_STRING(description),
+                         GRPC_ERROR_STR_GRPC_MESSAGE,
+                         grpc_slice_from_copied_string(description)),
       GRPC_ERROR_INT_GRPC_STATUS, status);
 }
 
@@ -627,16 +680,15 @@ static bool get_final_status_from(
     void (*set_value)(grpc_status_code code, void *user_data),
     void *set_value_user_data, grpc_slice *details) {
   grpc_status_code code;
-  const char *msg = NULL;
-  grpc_error_get_status(error, call->send_deadline, &code, &msg, NULL);
+  grpc_slice slice = grpc_empty_slice();
+  grpc_error_get_status(error, call->send_deadline, &code, &slice, NULL);
   if (code == GRPC_STATUS_OK && !allow_ok_status) {
     return false;
   }
 
   set_value(code, set_value_user_data);
   if (details != NULL) {
-    *details =
-        msg == NULL ? grpc_empty_slice() : grpc_slice_from_copied_string(msg);
+    *details = grpc_slice_ref_internal(slice);
   }
   return true;
 }
@@ -714,9 +766,7 @@ static void set_incoming_compression_algorithm(
 grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm(
     grpc_call *call) {
   grpc_compression_algorithm algorithm;
-  gpr_mu_lock(&call->mu);
   algorithm = call->incoming_compression_algorithm;
-  gpr_mu_unlock(&call->mu);
   return algorithm;
 }
 
@@ -728,9 +778,7 @@ static grpc_compression_algorithm compression_algorithm_for_level_locked(
 
 uint32_t grpc_call_test_only_get_message_flags(grpc_call *call) {
   uint32_t flags;
-  gpr_mu_lock(&call->mu);
   flags = call->test_only_last_message_flags;
-  gpr_mu_unlock(&call->mu);
   return flags;
 }
 
@@ -784,9 +832,7 @@ static void set_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx,
 
 uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) {
   uint32_t encodings_accepted_by_peer;
-  gpr_mu_lock(&call->mu);
   encodings_accepted_by_peer = call->encodings_accepted_by_peer;
-  gpr_mu_unlock(&call->mu);
   return encodings_accepted_by_peer;
 }
 
@@ -905,18 +951,19 @@ static void recv_common_filter(grpc_exec_ctx *exec_ctx, grpc_call *call,
     grpc_error *error =
         status_code == GRPC_STATUS_OK
             ? GRPC_ERROR_NONE
-            : grpc_error_set_int(GRPC_ERROR_CREATE("Error received from peer"),
+            : grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                     "Error received from peer"),
                                  GRPC_ERROR_INT_GRPC_STATUS,
                                  (intptr_t)status_code);
 
     if (b->idx.named.grpc_message != NULL) {
-      char *msg =
-          grpc_slice_to_c_string(GRPC_MDVALUE(b->idx.named.grpc_message->md));
-      error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, msg);
-      gpr_free(msg);
+      error = grpc_error_set_str(
+          error, GRPC_ERROR_STR_GRPC_MESSAGE,
+          grpc_slice_ref_internal(GRPC_MDVALUE(b->idx.named.grpc_message->md)));
       grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.grpc_message);
     } else if (error != GRPC_ERROR_NONE) {
-      error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, "");
+      error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE,
+                                 grpc_empty_slice());
     }
 
     set_status_from_error(exec_ctx, call, STATUS_FROM_WIRE, error);
@@ -1033,16 +1080,17 @@ static batch_control *allocate_batch_control(grpc_call *call,
                                              const grpc_op *ops,
                                              size_t num_ops) {
   int slot = batch_slot_for_op(ops[0].op);
-  for (size_t i = 1; i < num_ops; i++) {
-    int op_slot = batch_slot_for_op(ops[i].op);
-    slot = GPR_MIN(slot, op_slot);
+  batch_control **pslot = &call->active_batches[slot];
+  if (*pslot == NULL) {
+    *pslot = gpr_arena_alloc(call->arena, sizeof(batch_control));
   }
-  batch_control *bctl = &call->active_batches[slot];
+  batch_control *bctl = *pslot;
   if (bctl->call != NULL) {
     return NULL;
   }
   memset(bctl, 0, sizeof(*bctl));
   bctl->call = call;
+  bctl->op.payload = &call->stream_op_payload;
   return bctl;
 }
 
@@ -1055,7 +1103,7 @@ static void finish_batch_completion(grpc_exec_ctx *exec_ctx, void *user_data,
 }
 
 static grpc_error *consolidate_batch_errors(batch_control *bctl) {
-  size_t n = (size_t)gpr_atm_no_barrier_load(&bctl->num_errors);
+  size_t n = (size_t)gpr_atm_acq_load(&bctl->num_errors);
   if (n == 0) {
     return GRPC_ERROR_NONE;
   } else if (n == 1) {
@@ -1065,8 +1113,8 @@ static grpc_error *consolidate_batch_errors(batch_control *bctl) {
     bctl->errors[0] = NULL;
     return e;
   } else {
-    grpc_error *error =
-        GRPC_ERROR_CREATE_REFERENCING("Call batch failed", bctl->errors, n);
+    grpc_error *error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+        "Call batch failed", bctl->errors, n);
     for (size_t i = 0; i < n; i++) {
       GRPC_ERROR_UNREF(bctl->errors[i]);
       bctl->errors[i] = NULL;
@@ -1077,44 +1125,48 @@ static grpc_error *consolidate_batch_errors(batch_control *bctl) {
 
 static void post_batch_completion(grpc_exec_ctx *exec_ctx,
                                   batch_control *bctl) {
-  grpc_call *child_call;
   grpc_call *next_child_call;
   grpc_call *call = bctl->call;
   grpc_error *error = consolidate_batch_errors(bctl);
 
-  gpr_mu_lock(&call->mu);
-
-  if (bctl->send_initial_metadata) {
+  if (bctl->op.send_initial_metadata) {
     grpc_metadata_batch_destroy(
         exec_ctx,
         &call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */]);
   }
-  if (bctl->send_message) {
+  if (bctl->op.send_message) {
     call->sending_message = false;
   }
-  if (bctl->send_final_op) {
+  if (bctl->op.send_trailing_metadata) {
     grpc_metadata_batch_destroy(
         exec_ctx,
         &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */]);
   }
-  if (bctl->recv_final_op) {
+  if (bctl->op.recv_trailing_metadata) {
     grpc_metadata_batch *md =
         &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
     recv_trailing_filter(exec_ctx, call, md);
 
-    call->received_final_op = true;
     /* propagate cancellation to any interested children */
-    child_call = call->first_child;
-    if (child_call != NULL) {
-      do {
-        next_child_call = child_call->sibling_next;
-        if (child_call->cancellation_is_inherited) {
-          GRPC_CALL_INTERNAL_REF(child_call, "propagate_cancel");
-          grpc_call_cancel(child_call, NULL);
-          GRPC_CALL_INTERNAL_UNREF(exec_ctx, child_call, "propagate_cancel");
-        }
-        child_call = next_child_call;
-      } while (child_call != call->first_child);
+    gpr_atm_rel_store(&call->received_final_op_atm, 1);
+    parent_call *pc = get_parent_call(call);
+    if (pc != NULL) {
+      grpc_call *child;
+      gpr_mu_lock(&pc->child_list_mu);
+      child = pc->first_child;
+      if (child != NULL) {
+        do {
+          next_child_call = child->child_call->sibling_next;
+          if (child->cancellation_is_inherited) {
+            GRPC_CALL_INTERNAL_REF(child, "propagate_cancel");
+            cancel_with_error(exec_ctx, child, STATUS_FROM_API_OVERRIDE,
+                              GRPC_ERROR_CANCELLED);
+            GRPC_CALL_INTERNAL_UNREF(exec_ctx, child, "propagate_cancel");
+          }
+          child = next_child_call;
+        } while (child != pc->first_child);
+      }
+      gpr_mu_unlock(&pc->child_list_mu);
     }
 
     if (call->is_client) {
@@ -1129,17 +1181,17 @@ static void post_batch_completion(grpc_exec_ctx *exec_ctx,
     GRPC_ERROR_UNREF(error);
     error = GRPC_ERROR_NONE;
   }
-  gpr_mu_unlock(&call->mu);
 
-  if (bctl->is_notify_tag_closure) {
+  if (bctl->completion_data.notify_tag.is_closure) {
     /* unrefs bctl->error */
     bctl->call = NULL;
-    grpc_closure_run(exec_ctx, bctl->notify_tag, error);
+    grpc_closure_run(exec_ctx, bctl->completion_data.notify_tag.tag, error);
     GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "completion");
   } else {
     /* unrefs bctl->error */
-    grpc_cq_end_op(exec_ctx, bctl->call->cq, bctl->notify_tag, error,
-                   finish_batch_completion, bctl, &bctl->cq_completion);
+    grpc_cq_end_op(
+        exec_ctx, bctl->call->cq, bctl->completion_data.notify_tag.tag, error,
+        finish_batch_completion, bctl, &bctl->completion_data.cq_completion);
   }
 }
 
@@ -1151,6 +1203,7 @@ static void finish_batch_step(grpc_exec_ctx *exec_ctx, batch_control *bctl) {
 
 static void continue_receiving_slices(grpc_exec_ctx *exec_ctx,
                                       batch_control *bctl) {
+  grpc_error *error;
   grpc_call *call = bctl->call;
   for (;;) {
     size_t remaining = call->receiving_stream->length -
@@ -1162,11 +1215,22 @@ static void continue_receiving_slices(grpc_exec_ctx *exec_ctx,
       finish_batch_step(exec_ctx, bctl);
       return;
     }
-    if (grpc_byte_stream_next(exec_ctx, call->receiving_stream,
-                              &call->receiving_slice, remaining,
+    if (grpc_byte_stream_next(exec_ctx, call->receiving_stream, remaining,
                               &call->receiving_slice_ready)) {
-      grpc_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer,
-                            call->receiving_slice);
+      error = grpc_byte_stream_pull(exec_ctx, call->receiving_stream,
+                                    &call->receiving_slice);
+      if (error == GRPC_ERROR_NONE) {
+        grpc_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer,
+                              call->receiving_slice);
+      } else {
+        grpc_byte_stream_destroy(exec_ctx, call->receiving_stream);
+        call->receiving_stream = NULL;
+        grpc_byte_buffer_destroy(*call->receiving_buffer);
+        *call->receiving_buffer = NULL;
+        call->receiving_message = 0;
+        finish_batch_step(exec_ctx, bctl);
+        return;
+      }
     } else {
       return;
     }
@@ -1177,12 +1241,24 @@ static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
                                   grpc_error *error) {
   batch_control *bctl = bctlp;
   grpc_call *call = bctl->call;
+  grpc_byte_stream *bs = call->receiving_stream;
+  bool release_error = false;
 
   if (error == GRPC_ERROR_NONE) {
-    grpc_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer,
-                          call->receiving_slice);
-    continue_receiving_slices(exec_ctx, bctl);
-  } else {
+    grpc_slice slice;
+    error = grpc_byte_stream_pull(exec_ctx, bs, &slice);
+    if (error == GRPC_ERROR_NONE) {
+      grpc_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer,
+                            slice);
+      continue_receiving_slices(exec_ctx, bctl);
+    } else {
+      /* Error returned by grpc_byte_stream_pull needs to be released manually
+       */
+      release_error = true;
+    }
+  }
+
+  if (error != GRPC_ERROR_NONE) {
     if (grpc_trace_operation_failures) {
       GRPC_LOG_IF_ERROR("receiving_slice_ready", GRPC_ERROR_REF(error));
     }
@@ -1190,7 +1266,11 @@ static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
     call->receiving_stream = NULL;
     grpc_byte_buffer_destroy(*call->receiving_buffer);
     *call->receiving_buffer = NULL;
+    call->receiving_message = 0;
     finish_batch_step(exec_ctx, bctl);
+    if (release_error) {
+      GRPC_ERROR_UNREF(error);
+    }
   }
 }
 
@@ -1220,7 +1300,6 @@ static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
                                    grpc_error *error) {
   batch_control *bctl = bctlp;
   grpc_call *call = bctl->call;
-  gpr_mu_lock(&bctl->call->mu);
   if (error != GRPC_ERROR_NONE) {
     if (call->receiving_stream != NULL) {
       grpc_byte_stream_destroy(exec_ctx, call->receiving_stream);
@@ -1232,11 +1311,9 @@ static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
   }
   if (call->has_initial_md_been_received || error != GRPC_ERROR_NONE ||
       call->receiving_stream == NULL) {
-    gpr_mu_unlock(&bctl->call->mu);
     process_data_after_md(exec_ctx, bctlp);
   } else {
     call->saved_receiving_stream_ready_bctlp = bctlp;
-    gpr_mu_unlock(&bctl->call->mu);
   }
 }
 
@@ -1295,7 +1372,7 @@ static void validate_filtered_metadata(grpc_exec_ctx *exec_ctx,
 static void add_batch_error(grpc_exec_ctx *exec_ctx, batch_control *bctl,
                             grpc_error *error, bool has_cancelled) {
   if (error == GRPC_ERROR_NONE) return;
-  int idx = (int)gpr_atm_no_barrier_fetch_add(&bctl->num_errors, 1);
+  int idx = (int)gpr_atm_full_fetch_add(&bctl->num_errors, 1);
   if (idx == 0 && !has_cancelled) {
     cancel_with_error(exec_ctx, bctl->call, STATUS_FROM_CORE,
                       GRPC_ERROR_REF(error));
@@ -1308,8 +1385,6 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx,
   batch_control *bctl = bctlp;
   grpc_call *call = bctl->call;
 
-  gpr_mu_lock(&call->mu);
-
   add_batch_error(exec_ctx, bctl, GRPC_ERROR_REF(error), false);
   if (error == GRPC_ERROR_NONE) {
     grpc_metadata_batch *md =
@@ -1335,11 +1410,9 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx,
         receiving_stream_ready, call->saved_receiving_stream_ready_bctlp,
         grpc_schedule_on_exec_ctx);
     call->saved_receiving_stream_ready_bctlp = NULL;
-    grpc_closure_sched(exec_ctx, saved_rsr_closure, GRPC_ERROR_REF(error));
+    grpc_closure_run(exec_ctx, saved_rsr_closure, GRPC_ERROR_REF(error));
   }
 
-  gpr_mu_unlock(&call->mu);
-
   finish_batch_step(exec_ctx, bctl);
 }
 
@@ -1389,12 +1462,13 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
   if (bctl == NULL) {
     return GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
   }
-  bctl->notify_tag = notify_tag;
-  bctl->is_notify_tag_closure = (uint8_t)(is_notify_tag_closure != 0);
+  bctl->completion_data.notify_tag.tag = notify_tag;
+  bctl->completion_data.notify_tag.is_closure =
+      (uint8_t)(is_notify_tag_closure != 0);
 
-  gpr_mu_lock(&call->mu);
-  grpc_transport_stream_op *stream_op = &bctl->op;
-  memset(stream_op, 0, sizeof(*stream_op));
+  grpc_transport_stream_op_batch *stream_op = &bctl->op;
+  grpc_transport_stream_op_batch_payload *stream_op_payload =
+      &call->stream_op_payload;
   stream_op->covered_by_poller = true;
 
   /* rewrite batch ops into a transport op */
@@ -1448,8 +1522,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
           error = GRPC_CALL_ERROR_INVALID_METADATA;
           goto done_with_error;
         }
-        bctl->send_initial_metadata = 1;
-        call->sent_initial_metadata = 1;
+        stream_op->send_initial_metadata = true;
+        call->sent_initial_metadata = true;
         if (!prepare_application_metadata(
                 exec_ctx, call, (int)op->data.send_initial_metadata.count,
                 op->data.send_initial_metadata.metadata, 0, call->is_client,
@@ -1459,9 +1533,10 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
         }
         /* TODO(ctiller): just make these the same variable? */
         call->metadata_batch[0][0].deadline = call->send_deadline;
-        stream_op->send_initial_metadata =
+        stream_op_payload->send_initial_metadata.send_initial_metadata =
             &call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */];
-        stream_op->send_initial_metadata_flags = op->flags;
+        stream_op_payload->send_initial_metadata.send_initial_metadata_flags =
+            op->flags;
         break;
       case GRPC_OP_SEND_MESSAGE:
         if (!are_write_flags_valid(op->flags)) {
@@ -1476,8 +1551,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
           error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
           goto done_with_error;
         }
-        bctl->send_message = 1;
-        call->sending_message = 1;
+        stream_op->send_message = true;
+        call->sending_message = true;
         grpc_slice_buffer_stream_init(
             &call->sending_stream,
             &op->data.send_message.send_message->data.raw.slice_buffer,
@@ -1489,7 +1564,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
             GRPC_COMPRESS_NONE) {
           call->sending_stream.base.flags |= GRPC_WRITE_INTERNAL_COMPRESS;
         }
-        stream_op->send_message = &call->sending_stream.base;
+        stream_op_payload->send_message.send_message =
+            &call->sending_stream.base;
         break;
       case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
         /* Flag validation: currently allow no flags */
@@ -1505,9 +1581,9 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
           error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
           goto done_with_error;
         }
-        bctl->send_final_op = 1;
-        call->sent_final_op = 1;
-        stream_op->send_trailing_metadata =
+        stream_op->send_trailing_metadata = true;
+        call->sent_final_op = true;
+        stream_op_payload->send_trailing_metadata.send_trailing_metadata =
             &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */];
         break;
       case GRPC_OP_SEND_STATUS_FROM_SERVER:
@@ -1529,8 +1605,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
           error = GRPC_CALL_ERROR_INVALID_METADATA;
           goto done_with_error;
         }
-        bctl->send_final_op = 1;
-        call->sent_final_op = 1;
+        stream_op->send_trailing_metadata = true;
+        call->sent_final_op = true;
         GPR_ASSERT(call->send_extra_metadata_count == 0);
         call->send_extra_metadata_count = 1;
         call->send_extra_metadata[0].md = grpc_channel_get_reffed_status_elem(
@@ -1538,7 +1614,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
         {
           grpc_error *override_error = GRPC_ERROR_NONE;
           if (op->data.send_status_from_server.status != GRPC_STATUS_OK) {
-            override_error = GRPC_ERROR_CREATE("Error from server send status");
+            override_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                "Error from server send status");
           }
           if (op->data.send_status_from_server.status_details != NULL) {
             call->send_extra_metadata[1].md = grpc_mdelem_from_slices(
@@ -1548,8 +1625,9 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
             call->send_extra_metadata_count++;
             char *msg = grpc_slice_to_c_string(
                 GRPC_MDVALUE(call->send_extra_metadata[1].md));
-            override_error = grpc_error_set_str(
-                override_error, GRPC_ERROR_STR_GRPC_MESSAGE, msg);
+            override_error =
+                grpc_error_set_str(override_error, GRPC_ERROR_STR_GRPC_MESSAGE,
+                                   grpc_slice_from_copied_string(msg));
             gpr_free(msg);
           }
           set_status_from_error(exec_ctx, call, STATUS_FROM_API_OVERRIDE,
@@ -1567,7 +1645,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
           error = GRPC_CALL_ERROR_INVALID_METADATA;
           goto done_with_error;
         }
-        stream_op->send_trailing_metadata =
+        stream_op_payload->send_trailing_metadata.send_trailing_metadata =
             &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */];
         break;
       case GRPC_OP_RECV_INITIAL_METADATA:
@@ -1584,16 +1662,16 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
            from server.c. In that case, it's coming from accept_stream, and in
            that case we're not necessarily covered by a poller. */
         stream_op->covered_by_poller = call->is_client;
-        call->received_initial_metadata = 1;
+        call->received_initial_metadata = true;
         call->buffered_metadata[0] =
             op->data.recv_initial_metadata.recv_initial_metadata;
         grpc_closure_init(&call->receiving_initial_metadata_ready,
                           receiving_initial_metadata_ready, bctl,
                           grpc_schedule_on_exec_ctx);
-        bctl->recv_initial_metadata = 1;
-        stream_op->recv_initial_metadata =
+        stream_op->recv_initial_metadata = true;
+        stream_op_payload->recv_initial_metadata.recv_initial_metadata =
             &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */];
-        stream_op->recv_initial_metadata_ready =
+        stream_op_payload->recv_initial_metadata.recv_initial_metadata_ready =
             &call->receiving_initial_metadata_ready;
         num_completion_callbacks_needed++;
         break;
@@ -1607,13 +1685,14 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
           error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
           goto done_with_error;
         }
-        call->receiving_message = 1;
-        bctl->recv_message = 1;
+        call->receiving_message = true;
+        stream_op->recv_message = true;
         call->receiving_buffer = op->data.recv_message.recv_message;
-        stream_op->recv_message = &call->receiving_stream;
+        stream_op_payload->recv_message.recv_message = &call->receiving_stream;
         grpc_closure_init(&call->receiving_stream_ready, receiving_stream_ready,
                           bctl, grpc_schedule_on_exec_ctx);
-        stream_op->recv_message_ready = &call->receiving_stream_ready;
+        stream_op_payload->recv_message.recv_message_ready =
+            &call->receiving_stream_ready;
         num_completion_callbacks_needed++;
         break;
       case GRPC_OP_RECV_STATUS_ON_CLIENT:
@@ -1630,16 +1709,17 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
           error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
           goto done_with_error;
         }
-        call->requested_final_op = 1;
+        call->requested_final_op = true;
         call->buffered_metadata[1] =
             op->data.recv_status_on_client.trailing_metadata;
         call->final_op.client.status = op->data.recv_status_on_client.status;
         call->final_op.client.status_details =
             op->data.recv_status_on_client.status_details;
-        bctl->recv_final_op = 1;
-        stream_op->recv_trailing_metadata =
+        stream_op->recv_trailing_metadata = true;
+        stream_op->collect_stats = true;
+        stream_op_payload->recv_trailing_metadata.recv_trailing_metadata =
             &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
-        stream_op->collect_stats =
+        stream_op_payload->collect_stats.collect_stats =
             &call->final_info.stats.transport_stream_stats;
         break;
       case GRPC_OP_RECV_CLOSE_ON_SERVER:
@@ -1656,13 +1736,14 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
           error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
           goto done_with_error;
         }
-        call->requested_final_op = 1;
+        call->requested_final_op = true;
         call->final_op.server.cancelled =
             op->data.recv_close_on_server.cancelled;
-        bctl->recv_final_op = 1;
-        stream_op->recv_trailing_metadata =
+        stream_op->recv_trailing_metadata = true;
+        stream_op->collect_stats = true;
+        stream_op_payload->recv_trailing_metadata.recv_trailing_metadata =
             &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
-        stream_op->collect_stats =
+        stream_op_payload->collect_stats.collect_stats =
             &call->final_info.stats.transport_stream_stats;
         break;
     }
@@ -1674,11 +1755,10 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
   }
   gpr_ref_init(&bctl->steps_to_complete, num_completion_callbacks_needed);
 
-  stream_op->context = call->context;
   grpc_closure_init(&bctl->finish_batch, finish_batch, bctl,
                     grpc_schedule_on_exec_ctx);
   stream_op->on_complete = &bctl->finish_batch;
-  gpr_mu_unlock(&call->mu);
+  gpr_atm_rel_store(&call->any_ops_sent_atm, 1);
 
   execute_op(exec_ctx, call, stream_op);
 
@@ -1688,28 +1768,27 @@ done:
 
 done_with_error:
   /* reverse any mutations that occured */
-  if (bctl->send_initial_metadata) {
-    call->sent_initial_metadata = 0;
+  if (stream_op->send_initial_metadata) {
+    call->sent_initial_metadata = false;
     grpc_metadata_batch_clear(exec_ctx, &call->metadata_batch[0][0]);
   }
-  if (bctl->send_message) {
-    call->sending_message = 0;
+  if (stream_op->send_message) {
+    call->sending_message = false;
     grpc_byte_stream_destroy(exec_ctx, &call->sending_stream.base);
   }
-  if (bctl->send_final_op) {
-    call->sent_final_op = 0;
+  if (stream_op->send_trailing_metadata) {
+    call->sent_final_op = false;
     grpc_metadata_batch_clear(exec_ctx, &call->metadata_batch[0][1]);
   }
-  if (bctl->recv_initial_metadata) {
-    call->received_initial_metadata = 0;
+  if (stream_op->recv_initial_metadata) {
+    call->received_initial_metadata = false;
   }
-  if (bctl->recv_message) {
-    call->receiving_message = 0;
+  if (stream_op->recv_message) {
+    call->receiving_message = false;
   }
-  if (bctl->recv_final_op) {
-    call->requested_final_op = 0;
+  if (stream_op->recv_trailing_metadata) {
+    call->requested_final_op = false;
   }
-  gpr_mu_unlock(&call->mu);
   goto done;
 }
 
@@ -1758,10 +1837,8 @@ uint8_t grpc_call_is_client(grpc_call *call) { return call->is_client; }
 
 grpc_compression_algorithm grpc_call_compression_for_level(
     grpc_call *call, grpc_compression_level level) {
-  gpr_mu_lock(&call->mu);
   grpc_compression_algorithm algo =
       compression_algorithm_for_level_locked(call, level);
-  gpr_mu_unlock(&call->mu);
   return algo;
 }
 
diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c
index d6acd392c1a5f55f43fbe1f8a797833fcc3dcec8..b3ba826bbc59efb3928b917981bdb310e5c9427b 100644
--- a/src/core/lib/surface/channel.c
+++ b/src/core/lib/surface/channel.c
@@ -68,6 +68,8 @@ struct grpc_channel {
   grpc_compression_options compression_options;
   grpc_mdelem default_authority;
 
+  gpr_atm call_size_estimate;
+
   gpr_mu registered_call_mu;
   registered_call *registered_calls;
 
@@ -83,19 +85,10 @@ struct grpc_channel {
 static void destroy_channel(grpc_exec_ctx *exec_ctx, void *arg,
                             grpc_error *error);
 
-grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
-                                  const grpc_channel_args *input_args,
-                                  grpc_channel_stack_type channel_stack_type,
-                                  grpc_transport *optional_transport) {
-  grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create();
-  grpc_channel_stack_builder_set_channel_arguments(exec_ctx, builder,
-                                                   input_args);
-  grpc_channel_stack_builder_set_target(builder, target);
-  grpc_channel_stack_builder_set_transport(builder, optional_transport);
-  if (!grpc_channel_init_create_stack(exec_ctx, builder, channel_stack_type)) {
-    grpc_channel_stack_builder_destroy(exec_ctx, builder);
-    return NULL;
-  }
+grpc_channel *grpc_channel_create_with_builder(
+    grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder,
+    grpc_channel_stack_type channel_stack_type) {
+  char *target = gpr_strdup(grpc_channel_stack_builder_get_target(builder));
   grpc_channel_args *args = grpc_channel_args_copy(
       grpc_channel_stack_builder_get_channel_arguments(builder));
   grpc_channel *channel;
@@ -106,15 +99,20 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
     gpr_log(GPR_ERROR, "channel stack builder failed: %s",
             grpc_error_string(error));
     GRPC_ERROR_UNREF(error);
+    gpr_free(target);
     goto done;
   }
 
   memset(channel, 0, sizeof(*channel));
-  channel->target = gpr_strdup(target);
+  channel->target = target;
   channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type);
   gpr_mu_init(&channel->registered_call_mu);
   channel->registered_calls = NULL;
 
+  gpr_atm_no_barrier_store(
+      &channel->call_size_estimate,
+      (gpr_atm)CHANNEL_STACK_FROM_CHANNEL(channel)->call_stack_size);
+
   grpc_compression_options_init(&channel->compression_options);
   for (size_t i = 0; i < args->num_args; i++) {
     if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) {
@@ -152,17 +150,20 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
     } else if (0 == strcmp(args->args[i].key,
                            GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL)) {
       channel->compression_options.default_level.is_set = true;
-      GPR_ASSERT(args->args[i].value.integer >= 0 &&
-                 args->args[i].value.integer < GRPC_COMPRESS_LEVEL_COUNT);
       channel->compression_options.default_level.level =
-          (grpc_compression_level)args->args[i].value.integer;
+          (grpc_compression_level)grpc_channel_arg_get_integer(
+              &args->args[i],
+              (grpc_integer_options){GRPC_COMPRESS_LEVEL_NONE,
+                                     GRPC_COMPRESS_LEVEL_NONE,
+                                     GRPC_COMPRESS_LEVEL_COUNT - 1});
     } else if (0 == strcmp(args->args[i].key,
                            GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM)) {
       channel->compression_options.default_algorithm.is_set = true;
-      GPR_ASSERT(args->args[i].value.integer >= 0 &&
-                 args->args[i].value.integer < GRPC_COMPRESS_ALGORITHMS_COUNT);
       channel->compression_options.default_algorithm.algorithm =
-          (grpc_compression_algorithm)args->args[i].value.integer;
+          (grpc_compression_algorithm)grpc_channel_arg_get_integer(
+              &args->args[i],
+              (grpc_integer_options){GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
+                                     GRPC_COMPRESS_ALGORITHMS_COUNT - 1});
     } else if (0 ==
                strcmp(args->args[i].key,
                       GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET)) {
@@ -177,6 +178,55 @@ done:
   return channel;
 }
 
+grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
+                                  const grpc_channel_args *input_args,
+                                  grpc_channel_stack_type channel_stack_type,
+                                  grpc_transport *optional_transport) {
+  grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create();
+  grpc_channel_stack_builder_set_channel_arguments(exec_ctx, builder,
+                                                   input_args);
+  grpc_channel_stack_builder_set_target(builder, target);
+  grpc_channel_stack_builder_set_transport(builder, optional_transport);
+  if (!grpc_channel_init_create_stack(exec_ctx, builder, channel_stack_type)) {
+    grpc_channel_stack_builder_destroy(exec_ctx, builder);
+    return NULL;
+  }
+  return grpc_channel_create_with_builder(exec_ctx, builder,
+                                          channel_stack_type);
+}
+
+size_t grpc_channel_get_call_size_estimate(grpc_channel *channel) {
+#define ROUND_UP_SIZE 256
+  /* We round up our current estimate to the NEXT value of ROUND_UP_SIZE.
+     This ensures:
+      1. a consistent size allocation when our estimate is drifting slowly
+         (which is common) - which tends to help most allocators reuse memory
+      2. a small amount of allowed growth over the estimate without hitting
+         the arena size doubling case, reducing overall memory usage */
+  return ((size_t)gpr_atm_no_barrier_load(&channel->call_size_estimate) +
+          2 * ROUND_UP_SIZE) &
+         ~(size_t)(ROUND_UP_SIZE - 1);
+}
+
+void grpc_channel_update_call_size_estimate(grpc_channel *channel,
+                                            size_t size) {
+  size_t cur = (size_t)gpr_atm_no_barrier_load(&channel->call_size_estimate);
+  if (cur < size) {
+    /* size grew: update estimate */
+    gpr_atm_no_barrier_cas(&channel->call_size_estimate, (gpr_atm)cur,
+                           (gpr_atm)size);
+    /* if we lose: never mind, something else will likely update soon enough */
+  } else if (cur == size) {
+    /* no change: holding pattern */
+  } else if (cur > 0) {
+    /* size shrank: decrease estimate */
+    gpr_atm_no_barrier_cas(
+        &channel->call_size_estimate, (gpr_atm)cur,
+        (gpr_atm)(GPR_MIN(cur - 1, (255 * cur + size) / 256)));
+    /* if we lose: never mind, something else will likely update soon enough */
+  }
+}
+
 char *grpc_channel_get_target(grpc_channel *channel) {
   GRPC_API_TRACE("grpc_channel_get_target(channel=%p)", 1, (channel));
   return gpr_strdup(channel->target);
@@ -348,7 +398,8 @@ void grpc_channel_destroy(grpc_channel *channel) {
   grpc_channel_element *elem;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   GRPC_API_TRACE("grpc_channel_destroy(channel=%p)", 1, (channel));
-  op->disconnect_with_error = GRPC_ERROR_CREATE("Channel Destroyed");
+  op->disconnect_with_error =
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel Destroyed");
   elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CHANNEL(channel), 0);
   elem->filter->start_transport_op(&exec_ctx, elem, op);
 
diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h
index 3a441d7added2b3b3d395d37af1597d5a8024244..0f203a3e5942bc830dc37dcde58665f07b6cfcec 100644
--- a/src/core/lib/surface/channel.h
+++ b/src/core/lib/surface/channel.h
@@ -35,6 +35,7 @@
 #define GRPC_CORE_LIB_SURFACE_CHANNEL_H
 
 #include "src/core/lib/channel/channel_stack.h"
+#include "src/core/lib/channel/channel_stack_builder.h"
 #include "src/core/lib/surface/channel_stack_type.h"
 
 grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
@@ -42,6 +43,10 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
                                   grpc_channel_stack_type channel_stack_type,
                                   grpc_transport *optional_transport);
 
+grpc_channel *grpc_channel_create_with_builder(
+    grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder,
+    grpc_channel_stack_type channel_stack_type);
+
 /** Create a call given a grpc_channel, in order to call \a method.
     Progress is tied to activity on \a pollset_set. The returned call object is
     meant to be used with \a grpc_call_start_batch_and_execute, which relies on
@@ -66,6 +71,9 @@ grpc_mdelem grpc_channel_get_reffed_status_elem(grpc_exec_ctx *exec_ctx,
                                                 grpc_channel *channel,
                                                 int status_code);
 
+size_t grpc_channel_get_call_size_estimate(grpc_channel *channel);
+void grpc_channel_update_call_size_estimate(grpc_channel *channel, size_t size);
+
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG
 void grpc_channel_internal_ref(grpc_channel *channel, const char *reason);
 void grpc_channel_internal_unref(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
diff --git a/src/core/lib/surface/channel_init.c b/src/core/lib/surface/channel_init.c
index 7acb444d9b1792728eeeb47664325a2cb1cc2341..20f5753004994cb378d232b8d699d83e3c6468a9 100644
--- a/src/core/lib/surface/channel_init.c
+++ b/src/core/lib/surface/channel_init.c
@@ -104,30 +104,13 @@ void grpc_channel_init_shutdown(void) {
   }
 }
 
-static const char *name_for_type(grpc_channel_stack_type type) {
-  switch (type) {
-    case GRPC_CLIENT_CHANNEL:
-      return "CLIENT_CHANNEL";
-    case GRPC_CLIENT_SUBCHANNEL:
-      return "CLIENT_SUBCHANNEL";
-    case GRPC_SERVER_CHANNEL:
-      return "SERVER_CHANNEL";
-    case GRPC_CLIENT_LAME_CHANNEL:
-      return "CLIENT_LAME_CHANNEL";
-    case GRPC_CLIENT_DIRECT_CHANNEL:
-      return "CLIENT_DIRECT_CHANNEL";
-    case GRPC_NUM_CHANNEL_STACK_TYPES:
-      break;
-  }
-  GPR_UNREACHABLE_CODE(return "UNKNOWN");
-}
-
 bool grpc_channel_init_create_stack(grpc_exec_ctx *exec_ctx,
                                     grpc_channel_stack_builder *builder,
                                     grpc_channel_stack_type type) {
   GPR_ASSERT(g_finalized);
 
-  grpc_channel_stack_builder_set_name(builder, name_for_type(type));
+  grpc_channel_stack_builder_set_name(builder,
+                                      grpc_channel_stack_type_string(type));
 
   for (size_t i = 0; i < g_slots[type].num_slots; i++) {
     const stage_slot *slot = &g_slots[type].slots[i];
diff --git a/src/core/lib/surface/channel_stack_type.c b/src/core/lib/surface/channel_stack_type.c
index c35d603ca3aaadcb9492456d89865810cb7e47f9..ed3b53fb36ed8a2beadd35cf59b522eeccdcf7a5 100644
--- a/src/core/lib/surface/channel_stack_type.c
+++ b/src/core/lib/surface/channel_stack_type.c
@@ -52,3 +52,21 @@ bool grpc_channel_stack_type_is_client(grpc_channel_stack_type type) {
   }
   GPR_UNREACHABLE_CODE(return true;);
 }
+
+const char *grpc_channel_stack_type_string(grpc_channel_stack_type type) {
+  switch (type) {
+    case GRPC_CLIENT_CHANNEL:
+      return "CLIENT_CHANNEL";
+    case GRPC_CLIENT_SUBCHANNEL:
+      return "CLIENT_SUBCHANNEL";
+    case GRPC_SERVER_CHANNEL:
+      return "SERVER_CHANNEL";
+    case GRPC_CLIENT_LAME_CHANNEL:
+      return "CLIENT_LAME_CHANNEL";
+    case GRPC_CLIENT_DIRECT_CHANNEL:
+      return "CLIENT_DIRECT_CHANNEL";
+    case GRPC_NUM_CHANNEL_STACK_TYPES:
+      break;
+  }
+  GPR_UNREACHABLE_CODE(return "UNKNOWN");
+}
diff --git a/src/core/lib/surface/channel_stack_type.h b/src/core/lib/surface/channel_stack_type.h
index 4eea4f1b0167d64833c42afa5ba6d7120b06e044..ccf4e53d277a9b4990511dce9726f3dfc8838b3e 100644
--- a/src/core/lib/surface/channel_stack_type.h
+++ b/src/core/lib/surface/channel_stack_type.h
@@ -55,4 +55,6 @@ typedef enum {
 
 bool grpc_channel_stack_type_is_client(grpc_channel_stack_type type);
 
+const char *grpc_channel_stack_type_string(grpc_channel_stack_type type);
+
 #endif /* GRPC_CORE_LIB_SURFACE_CHANNEL_STACK_TYPE_H */
diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c
index b4594817e45f034fd3953becbebf7a3b0ef97613..eae3f103b1200263183f3bb99266787e1eb8d352 100644
--- a/src/core/lib/surface/completion_queue.c
+++ b/src/core/lib/surface/completion_queue.c
@@ -60,10 +60,155 @@ typedef struct {
   void *tag;
 } plucker;
 
+typedef struct {
+  bool can_get_pollset;
+  bool can_listen;
+  size_t (*size)(void);
+  void (*init)(grpc_pollset *pollset, gpr_mu **mu);
+  grpc_error *(*kick)(grpc_pollset *pollset,
+                      grpc_pollset_worker *specific_worker);
+  grpc_error *(*work)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
+                      grpc_pollset_worker **worker, gpr_timespec now,
+                      gpr_timespec deadline);
+  void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
+                   grpc_closure *closure);
+  void (*destroy)(grpc_pollset *pollset);
+} cq_poller_vtable;
+
+typedef struct non_polling_worker {
+  gpr_cv cv;
+  bool kicked;
+  struct non_polling_worker *next;
+  struct non_polling_worker *prev;
+} non_polling_worker;
+
+typedef struct {
+  gpr_mu mu;
+  non_polling_worker *root;
+  grpc_closure *shutdown;
+} non_polling_poller;
+
+static size_t non_polling_poller_size(void) {
+  return sizeof(non_polling_poller);
+}
+
+static void non_polling_poller_init(grpc_pollset *pollset, gpr_mu **mu) {
+  non_polling_poller *npp = (non_polling_poller *)pollset;
+  gpr_mu_init(&npp->mu);
+  *mu = &npp->mu;
+}
+
+static void non_polling_poller_destroy(grpc_pollset *pollset) {
+  non_polling_poller *npp = (non_polling_poller *)pollset;
+  gpr_mu_destroy(&npp->mu);
+}
+
+static grpc_error *non_polling_poller_work(grpc_exec_ctx *exec_ctx,
+                                           grpc_pollset *pollset,
+                                           grpc_pollset_worker **worker,
+                                           gpr_timespec now,
+                                           gpr_timespec deadline) {
+  non_polling_poller *npp = (non_polling_poller *)pollset;
+  if (npp->shutdown) return GRPC_ERROR_NONE;
+  non_polling_worker w;
+  gpr_cv_init(&w.cv);
+  if (worker != NULL) *worker = (grpc_pollset_worker *)&w;
+  if (npp->root == NULL) {
+    npp->root = w.next = w.prev = &w;
+  } else {
+    w.next = npp->root;
+    w.prev = w.next->prev;
+    w.next->prev = w.prev->next = &w;
+  }
+  w.kicked = false;
+  while (!npp->shutdown && !w.kicked && !gpr_cv_wait(&w.cv, &npp->mu, deadline))
+    ;
+  if (&w == npp->root) {
+    npp->root = w.next;
+    if (&w == npp->root) {
+      if (npp->shutdown) {
+        grpc_closure_sched(exec_ctx, npp->shutdown, GRPC_ERROR_NONE);
+      }
+      npp->root = NULL;
+    }
+  }
+  w.next->prev = w.prev;
+  w.prev->next = w.next;
+  gpr_cv_destroy(&w.cv);
+  if (worker != NULL) *worker = NULL;
+  return GRPC_ERROR_NONE;
+}
+
+static grpc_error *non_polling_poller_kick(
+    grpc_pollset *pollset, grpc_pollset_worker *specific_worker) {
+  non_polling_poller *p = (non_polling_poller *)pollset;
+  if (specific_worker == NULL) specific_worker = (grpc_pollset_worker *)p->root;
+  if (specific_worker != NULL) {
+    non_polling_worker *w = (non_polling_worker *)specific_worker;
+    if (!w->kicked) {
+      w->kicked = true;
+      gpr_cv_signal(&w->cv);
+    }
+  }
+  return GRPC_ERROR_NONE;
+}
+
+static void non_polling_poller_shutdown(grpc_exec_ctx *exec_ctx,
+                                        grpc_pollset *pollset,
+                                        grpc_closure *closure) {
+  non_polling_poller *p = (non_polling_poller *)pollset;
+  GPR_ASSERT(closure != NULL);
+  p->shutdown = closure;
+  if (p->root == NULL) {
+    grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE);
+  } else {
+    non_polling_worker *w = p->root;
+    do {
+      gpr_cv_signal(&w->cv);
+      w = w->next;
+    } while (w != p->root);
+  }
+}
+
+static const cq_poller_vtable g_poller_vtable_by_poller_type[] = {
+    /* GRPC_CQ_DEFAULT_POLLING */
+    {.can_get_pollset = true,
+     .can_listen = true,
+     .size = grpc_pollset_size,
+     .init = grpc_pollset_init,
+     .kick = grpc_pollset_kick,
+     .work = grpc_pollset_work,
+     .shutdown = grpc_pollset_shutdown,
+     .destroy = grpc_pollset_destroy},
+    /* GRPC_CQ_NON_LISTENING */
+    {.can_get_pollset = true,
+     .can_listen = false,
+     .size = grpc_pollset_size,
+     .init = grpc_pollset_init,
+     .kick = grpc_pollset_kick,
+     .work = grpc_pollset_work,
+     .shutdown = grpc_pollset_shutdown,
+     .destroy = grpc_pollset_destroy},
+    /* GRPC_CQ_NON_POLLING */
+    {.can_get_pollset = false,
+     .can_listen = false,
+     .size = non_polling_poller_size,
+     .init = non_polling_poller_init,
+     .kick = non_polling_poller_kick,
+     .work = non_polling_poller_work,
+     .shutdown = non_polling_poller_shutdown,
+     .destroy = non_polling_poller_destroy},
+};
+
 /* Completion queue structure */
 struct grpc_completion_queue {
   /** owned by pollset */
   gpr_mu *mu;
+
+  grpc_cq_completion_type completion_type;
+
+  const cq_poller_vtable *poller_vtable;
+
   /** completed events */
   grpc_cq_completion completed_head;
   grpc_cq_completion *completed_tail;
@@ -79,6 +224,7 @@ struct grpc_completion_queue {
   int shutdown_called;
   int is_server_cq;
   /** Can the server cq accept incoming channels */
+  /* TODO: sreek - This will no longer be needed. Use polling_type set */
   int is_non_listening_server_cq;
   int num_pluckers;
   plucker pluckers[GRPC_MAX_COMPLETION_QUEUE_PLUCKERS];
@@ -110,21 +256,31 @@ int grpc_cq_event_timeout_trace;
 static void on_pollset_shutdown_done(grpc_exec_ctx *exec_ctx, void *cc,
                                      grpc_error *error);
 
-grpc_completion_queue *grpc_completion_queue_create(void *reserved) {
+grpc_completion_queue *grpc_completion_queue_create_internal(
+    grpc_cq_completion_type completion_type,
+    grpc_cq_polling_type polling_type) {
   grpc_completion_queue *cc;
-  GPR_ASSERT(!reserved);
 
-  GPR_TIMER_BEGIN("grpc_completion_queue_create", 0);
+  GPR_TIMER_BEGIN("grpc_completion_queue_create_internal", 0);
+
+  GRPC_API_TRACE(
+      "grpc_completion_queue_create_internal(completion_type=%d, "
+      "polling_type=%d)",
+      2, (completion_type, polling_type));
 
-  GRPC_API_TRACE("grpc_completion_queue_create(reserved=%p)", 1, (reserved));
+  const cq_poller_vtable *poller_vtable =
+      &g_poller_vtable_by_poller_type[polling_type];
 
-  cc = gpr_zalloc(sizeof(grpc_completion_queue) + grpc_pollset_size());
-  grpc_pollset_init(POLLSET_FROM_CQ(cc), &cc->mu);
+  cc = gpr_zalloc(sizeof(grpc_completion_queue) + poller_vtable->size());
+  poller_vtable->init(POLLSET_FROM_CQ(cc), &cc->mu);
 #ifndef NDEBUG
   cc->outstanding_tags = NULL;
   cc->outstanding_tag_capacity = 0;
 #endif
 
+  cc->completion_type = completion_type;
+  cc->poller_vtable = poller_vtable;
+
   /* Initial ref is dropped by grpc_completion_queue_shutdown */
   gpr_ref_init(&cc->pending_events, 1);
   /* One for destroy(), one for pollset_shutdown */
@@ -143,11 +299,15 @@ grpc_completion_queue *grpc_completion_queue_create(void *reserved) {
   grpc_closure_init(&cc->pollset_shutdown_done, on_pollset_shutdown_done, cc,
                     grpc_schedule_on_exec_ctx);
 
-  GPR_TIMER_END("grpc_completion_queue_create", 0);
+  GPR_TIMER_END("grpc_completion_queue_create_internal", 0);
 
   return cc;
 }
 
+grpc_cq_completion_type grpc_get_cq_completion_type(grpc_completion_queue *cc) {
+  return cc->completion_type;
+}
+
 #ifdef GRPC_CQ_REF_COUNT_DEBUG
 void grpc_cq_internal_ref(grpc_completion_queue *cc, const char *reason,
                           const char *file, int line) {
@@ -175,7 +335,7 @@ void grpc_cq_internal_unref(grpc_completion_queue *cc) {
 #endif
   if (gpr_unref(&cc->owning_refs)) {
     GPR_ASSERT(cc->completed_head.next == (uintptr_t)&cc->completed_head);
-    grpc_pollset_destroy(POLLSET_FROM_CQ(cc));
+    cc->poller_vtable->destroy(POLLSET_FROM_CQ(cc));
 #ifndef NDEBUG
     gpr_free(cc->outstanding_tags);
 #endif
@@ -260,7 +420,7 @@ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc,
       }
     }
     grpc_error *kick_error =
-        grpc_pollset_kick(POLLSET_FROM_CQ(cc), pluck_worker);
+        cc->poller_vtable->kick(POLLSET_FROM_CQ(cc), pluck_worker);
     gpr_mu_unlock(cc->mu);
     if (kick_error != GRPC_ERROR_NONE) {
       const char *msg = grpc_error_string(kick_error);
@@ -275,8 +435,8 @@ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc,
     GPR_ASSERT(!cc->shutdown);
     GPR_ASSERT(cc->shutdown_called);
     cc->shutdown = 1;
-    grpc_pollset_shutdown(exec_ctx, POLLSET_FROM_CQ(cc),
-                          &cc->pollset_shutdown_done);
+    cc->poller_vtable->shutdown(exec_ctx, POLLSET_FROM_CQ(cc),
+                                &cc->pollset_shutdown_done);
     gpr_mu_unlock(cc->mu);
   }
 
@@ -345,9 +505,15 @@ static void dump_pending_tags(grpc_completion_queue *cc) {}
 grpc_event grpc_completion_queue_next(grpc_completion_queue *cc,
                                       gpr_timespec deadline, void *reserved) {
   grpc_event ret;
-  grpc_pollset_worker *worker = NULL;
   gpr_timespec now;
 
+  if (cc->completion_type != GRPC_CQ_NEXT) {
+    gpr_log(GPR_ERROR,
+            "grpc_completion_queue_next() cannot be called on this completion "
+            "queue since its completion type is not GRPC_CQ_NEXT");
+    abort();
+  }
+
   GPR_TIMER_BEGIN("grpc_completion_queue_next", 0);
 
   GRPC_API_TRACE(
@@ -426,8 +592,8 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc,
       gpr_mu_lock(cc->mu);
       continue;
     } else {
-      grpc_error *err = grpc_pollset_work(&exec_ctx, POLLSET_FROM_CQ(cc),
-                                          &worker, now, iteration_deadline);
+      grpc_error *err = cc->poller_vtable->work(&exec_ctx, POLLSET_FROM_CQ(cc),
+                                                NULL, now, iteration_deadline);
       if (err != GRPC_ERROR_NONE) {
         gpr_mu_unlock(cc->mu);
         const char *msg = grpc_error_string(err);
@@ -517,6 +683,13 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
 
   GPR_TIMER_BEGIN("grpc_completion_queue_pluck", 0);
 
+  if (cc->completion_type != GRPC_CQ_PLUCK) {
+    gpr_log(GPR_ERROR,
+            "grpc_completion_queue_pluck() cannot be called on this completion "
+            "queue since its completion type is not GRPC_CQ_PLUCK");
+    abort();
+  }
+
   if (grpc_cq_pluck_trace) {
     GRPC_API_TRACE(
         "grpc_completion_queue_pluck("
@@ -611,8 +784,8 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
       grpc_exec_ctx_flush(&exec_ctx);
       gpr_mu_lock(cc->mu);
     } else {
-      grpc_error *err = grpc_pollset_work(&exec_ctx, POLLSET_FROM_CQ(cc),
-                                          &worker, now, iteration_deadline);
+      grpc_error *err = cc->poller_vtable->work(
+          &exec_ctx, POLLSET_FROM_CQ(cc), &worker, now, iteration_deadline);
       if (err != GRPC_ERROR_NONE) {
         del_plucker(cc, tag, &worker);
         gpr_mu_unlock(cc->mu);
@@ -656,8 +829,8 @@ void grpc_completion_queue_shutdown(grpc_completion_queue *cc) {
   if (gpr_unref(&cc->pending_events)) {
     GPR_ASSERT(!cc->shutdown);
     cc->shutdown = 1;
-    grpc_pollset_shutdown(&exec_ctx, POLLSET_FROM_CQ(cc),
-                          &cc->pollset_shutdown_done);
+    cc->poller_vtable->shutdown(&exec_ctx, POLLSET_FROM_CQ(cc),
+                                &cc->pollset_shutdown_done);
   }
   gpr_mu_unlock(cc->mu);
   grpc_exec_ctx_finish(&exec_ctx);
@@ -673,7 +846,7 @@ void grpc_completion_queue_destroy(grpc_completion_queue *cc) {
 }
 
 grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc) {
-  return POLLSET_FROM_CQ(cc);
+  return cc->poller_vtable->can_get_pollset ? POLLSET_FROM_CQ(cc) : NULL;
 }
 
 grpc_completion_queue *grpc_cq_from_pollset(grpc_pollset *ps) {
@@ -681,13 +854,23 @@ grpc_completion_queue *grpc_cq_from_pollset(grpc_pollset *ps) {
 }
 
 void grpc_cq_mark_non_listening_server_cq(grpc_completion_queue *cc) {
+  /* TODO: sreek - use cc->polling_type field here and add a validation check
+     (i.e grpc_cq_mark_non_listening_server_cq can only be called on a cc whose
+     polling_type is set to GRPC_CQ_NON_LISTENING */
   cc->is_non_listening_server_cq = 1;
 }
 
 bool grpc_cq_is_non_listening_server_cq(grpc_completion_queue *cc) {
+  /* TODO (sreek) - return (cc->polling_type == GRPC_CQ_NON_LISTENING) */
   return (cc->is_non_listening_server_cq == 1);
 }
 
 void grpc_cq_mark_server_cq(grpc_completion_queue *cc) { cc->is_server_cq = 1; }
 
-int grpc_cq_is_server_cq(grpc_completion_queue *cc) { return cc->is_server_cq; }
+bool grpc_cq_is_server_cq(grpc_completion_queue *cc) {
+  return cc->is_server_cq;
+}
+
+bool grpc_cq_can_listen(grpc_completion_queue *cc) {
+  return cc->poller_vtable->can_listen;
+}
diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h
index 5d73dd7216e449ef741735fa7e1dcc4c957b2e42..a932087939d028f19f62685bfa81ed544693c12f 100644
--- a/src/core/lib/surface/completion_queue.h
+++ b/src/core/lib/surface/completion_queue.h
@@ -94,9 +94,13 @@ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc,
 grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc);
 grpc_completion_queue *grpc_cq_from_pollset(grpc_pollset *ps);
 
-void grpc_cq_mark_non_listening_server_cq(grpc_completion_queue *cc);
-bool grpc_cq_is_non_listening_server_cq(grpc_completion_queue *cc);
 void grpc_cq_mark_server_cq(grpc_completion_queue *cc);
-int grpc_cq_is_server_cq(grpc_completion_queue *cc);
+bool grpc_cq_is_server_cq(grpc_completion_queue *cc);
+bool grpc_cq_can_listen(grpc_completion_queue *cc);
+
+grpc_cq_completion_type grpc_get_cq_completion_type(grpc_completion_queue *cc);
+
+grpc_completion_queue *grpc_completion_queue_create_internal(
+    grpc_cq_completion_type completion_type, grpc_cq_polling_type polling_type);
 
 #endif /* GRPC_CORE_LIB_SURFACE_COMPLETION_QUEUE_H */
diff --git a/src/core/lib/surface/completion_queue_factory.c b/src/core/lib/surface/completion_queue_factory.c
new file mode 100644
index 0000000000000000000000000000000000000000..d68b84eddd3f33b5bb92029720286c7eec888b21
--- /dev/null
+++ b/src/core/lib/surface/completion_queue_factory.c
@@ -0,0 +1,92 @@
+/*
+ *
+ * Copyright 2017, 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/lib/surface/completion_queue_factory.h"
+#include "src/core/lib/surface/completion_queue.h"
+
+#include <grpc/support/log.h>
+
+/*
+ * == Default completion queue factory implementation ==
+ */
+
+static grpc_completion_queue* default_create(
+    const grpc_completion_queue_factory* factory,
+    const grpc_completion_queue_attributes* attr) {
+  return grpc_completion_queue_create_internal(attr->cq_completion_type,
+                                               attr->cq_polling_type);
+}
+
+static grpc_completion_queue_factory_vtable default_vtable = {default_create};
+
+static const grpc_completion_queue_factory g_default_cq_factory = {
+    "Default Factory", NULL, &default_vtable};
+
+/*
+ * == Completion queue factory APIs
+ */
+
+const grpc_completion_queue_factory* grpc_completion_queue_factory_lookup(
+    const grpc_completion_queue_attributes* attributes) {
+  GPR_ASSERT(attributes->version >= 1 &&
+             attributes->version <= GRPC_CQ_CURRENT_VERSION);
+
+  /* The default factory can handle version 1 of the attributes structure. We
+     may have to change this as more fields are added to the structure */
+  return &g_default_cq_factory;
+}
+
+/*
+ * == Completion queue creation APIs ==
+ */
+
+grpc_completion_queue* grpc_completion_queue_create_for_next(void* reserved) {
+  GPR_ASSERT(!reserved);
+  grpc_completion_queue_attributes attr = {1, GRPC_CQ_NEXT,
+                                           GRPC_CQ_DEFAULT_POLLING};
+  return g_default_cq_factory.vtable->create(&g_default_cq_factory, &attr);
+}
+
+grpc_completion_queue* grpc_completion_queue_create_for_pluck(void* reserved) {
+  GPR_ASSERT(!reserved);
+  grpc_completion_queue_attributes attr = {1, GRPC_CQ_PLUCK,
+                                           GRPC_CQ_DEFAULT_POLLING};
+  return g_default_cq_factory.vtable->create(&g_default_cq_factory, &attr);
+}
+
+grpc_completion_queue* grpc_completion_queue_create(
+    const grpc_completion_queue_factory* factory,
+    const grpc_completion_queue_attributes* attr, void* reserved) {
+  GPR_ASSERT(!reserved);
+  return factory->vtable->create(factory, attr);
+}
diff --git a/src/core/lib/surface/completion_queue_factory.h b/src/core/lib/surface/completion_queue_factory.h
new file mode 100644
index 0000000000000000000000000000000000000000..57e90b509074cdfb7c5f2b8348b2431f9ee852f5
--- /dev/null
+++ b/src/core/lib/surface/completion_queue_factory.h
@@ -0,0 +1,51 @@
+/*
+ *
+ * Copyright 2017, 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_CORE_LIB_SURFACE_COMPLETION_QUEUE_FACTORY_H
+#define GRPC_CORE_LIB_SURFACE_COMPLETION_QUEUE_FACTORY_H
+
+#include <grpc/grpc.h>
+#include "src/core/lib/surface/completion_queue.h"
+
+typedef struct grpc_completion_queue_factory_vtable {
+  grpc_completion_queue* (*create)(const grpc_completion_queue_factory*,
+                                   const grpc_completion_queue_attributes*);
+} grpc_completion_queue_factory_vtable;
+
+struct grpc_completion_queue_factory {
+  const char* name;
+  void* data; /* Factory specific data */
+  grpc_completion_queue_factory_vtable* vtable;
+};
+
+#endif /* GRPC_CORE_LIB_SURFACE_COMPLETION_QUEUE_FACTORY_H */
diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c
index 91bd014a0e5c6f0a8928466775ae91ef21e616d6..4b381b19546d32eed9a0ad0eebd400fe391f822f 100644
--- a/src/core/lib/surface/init.c
+++ b/src/core/lib/surface/init.c
@@ -41,13 +41,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include "src/core/lib/channel/channel_stack.h"
-#include "src/core/lib/channel/compress_filter.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/deadline_filter.h"
 #include "src/core/lib/channel/handshaker_registry.h"
-#include "src/core/lib/channel/http_client_filter.h"
-#include "src/core/lib/channel/http_server_filter.h"
-#include "src/core/lib/channel/message_size_filter.h"
 #include "src/core/lib/debug/trace.h"
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/iomgr/combiner.h"
@@ -95,57 +90,13 @@ static bool prepend_filter(grpc_exec_ctx *exec_ctx,
       builder, (const grpc_channel_filter *)arg, NULL, NULL);
 }
 
-static bool maybe_add_http_filter(grpc_exec_ctx *exec_ctx,
-                                  grpc_channel_stack_builder *builder,
-                                  void *arg) {
-  grpc_transport *t = grpc_channel_stack_builder_get_transport(builder);
-  if (t && strstr(t->vtable->name, "http")) {
-    return grpc_channel_stack_builder_prepend_filter(
-        builder, (const grpc_channel_filter *)arg, NULL, NULL);
-  }
-  return true;
-}
-
 static void register_builtin_channel_init() {
-  grpc_channel_init_register_stage(
-      GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
-      prepend_filter, (void *)&grpc_client_deadline_filter);
-  grpc_channel_init_register_stage(
-      GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, prepend_filter,
-      (void *)&grpc_server_deadline_filter);
-  grpc_channel_init_register_stage(
-      GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
-      prepend_filter, (void *)&grpc_message_size_filter);
-  grpc_channel_init_register_stage(
-      GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
-      prepend_filter, (void *)&grpc_message_size_filter);
-  grpc_channel_init_register_stage(
-      GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, prepend_filter,
-      (void *)&grpc_message_size_filter);
-  grpc_channel_init_register_stage(
-      GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, prepend_filter,
-      (void *)&grpc_compress_filter);
-  grpc_channel_init_register_stage(
-      GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
-      prepend_filter, (void *)&grpc_compress_filter);
-  grpc_channel_init_register_stage(
-      GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, prepend_filter,
-      (void *)&grpc_compress_filter);
-  grpc_channel_init_register_stage(
-      GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
-      maybe_add_http_filter, (void *)&grpc_http_client_filter);
   grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL,
                                    GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
                                    grpc_add_connected_filter, NULL);
-  grpc_channel_init_register_stage(
-      GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
-      maybe_add_http_filter, (void *)&grpc_http_client_filter);
   grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL,
                                    GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
                                    grpc_add_connected_filter, NULL);
-  grpc_channel_init_register_stage(
-      GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
-      maybe_add_http_filter, (void *)&grpc_http_server_filter);
   grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL,
                                    GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
                                    grpc_add_connected_filter, NULL);
@@ -189,7 +140,6 @@ void grpc_init(void) {
     grpc_register_tracer("channel_stack_builder",
                          &grpc_trace_channel_stack_builder);
     grpc_register_tracer("http1", &grpc_http1_trace);
-    grpc_register_tracer("compression", &grpc_compression_trace);
     grpc_register_tracer("queue_pluck", &grpc_cq_pluck_trace);
     grpc_register_tracer("combiner", &grpc_combiner_trace);
     grpc_register_tracer("server_channel", &grpc_server_channel_trace);
diff --git a/src/core/lib/surface/init_secure.c b/src/core/lib/surface/init_secure.c
index 46b9a8f922c8c14f00c1117a08e32bf7a1cd9c55..746134676f8ad9b22cf09a4ccd7e43c2eff16f9e 100644
--- a/src/core/lib/surface/init_secure.c
+++ b/src/core/lib/surface/init_secure.c
@@ -31,6 +31,8 @@
  *
  */
 
+#include <grpc/support/port_platform.h>
+
 #include "src/core/lib/surface/init.h"
 
 #include <limits.h>
@@ -43,7 +45,7 @@
 #include "src/core/lib/security/transport/security_connector.h"
 #include "src/core/lib/security/transport/security_handshaker.h"
 #include "src/core/lib/surface/channel_init.h"
-#include "src/core/lib/tsi/transport_security_interface.h"
+#include "src/core/tsi/transport_security_interface.h"
 
 void grpc_security_pre_init(void) {
   grpc_register_tracer("secure_endpoint", &grpc_trace_secure_endpoint);
diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.cc
similarity index 74%
rename from src/core/lib/surface/lame_client.c
rename to src/core/lib/surface/lame_client.cc
index 49bc4c114b37afcc696b88cc98986321e7846af3..88f4eaac08f6a3e17879c0c6c81df3e39ad49c81 100644
--- a/src/core/lib/surface/lame_client.c
+++ b/src/core/lib/surface/lame_client.cc
@@ -31,39 +31,50 @@
  *
  */
 
-#include "src/core/lib/surface/lame_client.h"
-
 #include <grpc/grpc.h>
 
 #include <string.h>
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+
+#include "src/core/lib/support/atomic.h"
+
+extern "C" {
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/surface/channel.h"
+#include "src/core/lib/surface/lame_client.h"
 #include "src/core/lib/transport/static_metadata.h"
+}
 
-typedef struct {
+namespace grpc_core {
+
+namespace {
+
+struct CallData {
   grpc_linked_mdelem status;
   grpc_linked_mdelem details;
-  gpr_atm filled_metadata;
-} call_data;
+  grpc_core::atomic<bool> filled_metadata;
+};
 
-typedef struct {
+struct ChannelData {
   grpc_status_code error_code;
   const char *error_message;
-} channel_data;
+};
 
 static void fill_metadata(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                           grpc_metadata_batch *mdb) {
-  call_data *calld = elem->call_data;
-  if (!gpr_atm_no_barrier_cas(&calld->filled_metadata, 0, 1)) {
+  CallData *calld = static_cast<CallData *>(elem->call_data);
+  bool expected = false;
+  if (!calld->filled_metadata.compare_exchange_strong(
+          expected, true, grpc_core::memory_order_relaxed,
+          grpc_core::memory_order_relaxed)) {
     return;
   }
-  channel_data *chand = elem->channel_data;
+  ChannelData *chand = static_cast<ChannelData *>(elem->channel_data);
   char tmp[GPR_LTOA_MIN_BUFSIZE];
   gpr_ltoa(chand->error_code, tmp);
   calld->status.md = grpc_mdelem_from_slices(
@@ -80,17 +91,19 @@ static void fill_metadata(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
   mdb->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
 }
 
-static void lame_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
-                                           grpc_call_element *elem,
-                                           grpc_transport_stream_op *op) {
-  GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
-  if (op->recv_initial_metadata != NULL) {
-    fill_metadata(exec_ctx, elem, op->recv_initial_metadata);
-  } else if (op->recv_trailing_metadata != NULL) {
-    fill_metadata(exec_ctx, elem, op->recv_trailing_metadata);
+static void lame_start_transport_stream_op_batch(
+    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+    grpc_transport_stream_op_batch *op) {
+  if (op->recv_initial_metadata) {
+    fill_metadata(exec_ctx, elem,
+                  op->payload->recv_initial_metadata.recv_initial_metadata);
+  } else if (op->recv_trailing_metadata) {
+    fill_metadata(exec_ctx, elem,
+                  op->payload->recv_trailing_metadata.recv_trailing_metadata);
   }
-  grpc_transport_stream_op_finish_with_failure(
-      exec_ctx, op, GRPC_ERROR_CREATE("lame client channel"));
+  grpc_transport_stream_op_batch_finish_with_failure(
+      exec_ctx, op,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("lame client channel"));
 }
 
 static char *lame_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
@@ -111,8 +124,9 @@ static void lame_start_transport_op(grpc_exec_ctx *exec_ctx,
                        GRPC_ERROR_NONE);
   }
   if (op->send_ping != NULL) {
-    grpc_closure_sched(exec_ctx, op->send_ping,
-                       GRPC_ERROR_CREATE("lame client channel"));
+    grpc_closure_sched(
+        exec_ctx, op->send_ping,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("lame client channel"));
   }
   GRPC_ERROR_UNREF(op->disconnect_with_error);
   if (op->on_consumed != NULL) {
@@ -123,15 +137,13 @@ static void lame_start_transport_op(grpc_exec_ctx *exec_ctx,
 static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
                                   grpc_call_element *elem,
                                   const grpc_call_element_args *args) {
-  call_data *calld = elem->call_data;
-  gpr_atm_no_barrier_store(&calld->filled_metadata, 0);
   return GRPC_ERROR_NONE;
 }
 
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
-                              void *and_free_memory) {
-  gpr_free(and_free_memory);
+                              grpc_closure *then_schedule_closure) {
+  grpc_closure_sched(exec_ctx, then_schedule_closure, GRPC_ERROR_NONE);
 }
 
 static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
@@ -145,18 +157,22 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
                                  grpc_channel_element *elem) {}
 
-const grpc_channel_filter grpc_lame_filter = {
-    lame_start_transport_stream_op,
-    lame_start_transport_op,
-    sizeof(call_data),
-    init_call_elem,
+}  // namespace
+
+}  // namespace grpc_core
+
+extern "C" const grpc_channel_filter grpc_lame_filter = {
+    grpc_core::lame_start_transport_stream_op_batch,
+    grpc_core::lame_start_transport_op,
+    sizeof(grpc_core::CallData),
+    grpc_core::init_call_elem,
     grpc_call_stack_ignore_set_pollset_or_pollset_set,
-    destroy_call_elem,
-    sizeof(channel_data),
-    init_channel_elem,
-    destroy_channel_elem,
-    lame_get_peer,
-    lame_get_channel_info,
+    grpc_core::destroy_call_elem,
+    sizeof(grpc_core::ChannelData),
+    grpc_core::init_channel_elem,
+    grpc_core::destroy_channel_elem,
+    grpc_core::lame_get_peer,
+    grpc_core::lame_get_channel_info,
     "lame-client",
 };
 
@@ -167,7 +183,6 @@ grpc_channel *grpc_lame_client_channel_create(const char *target,
                                               const char *error_message) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_channel_element *elem;
-  channel_data *chand;
   grpc_channel *channel = grpc_channel_create(&exec_ctx, target, NULL,
                                               GRPC_CLIENT_LAME_CHANNEL, NULL);
   elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
@@ -176,7 +191,7 @@ grpc_channel *grpc_lame_client_channel_create(const char *target,
       "error_message=%s)",
       3, (target, (int)error_code, error_message));
   GPR_ASSERT(elem->filter == &grpc_lame_filter);
-  chand = (channel_data *)elem->channel_data;
+  auto chand = static_cast<grpc_core::ChannelData *>(elem->channel_data);
   chand->error_code = error_code;
   chand->error_message = error_message;
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c
index b360579553659fc005bfa10658d00077a30199f3..934ca0431a6f2349232712fc4b8464c6201494b9 100644
--- a/src/core/lib/surface/server.c
+++ b/src/core/lib/surface/server.c
@@ -44,6 +44,7 @@
 
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/connected_channel.h"
+#include "src/core/lib/iomgr/executor.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/stack_lockfree.h"
@@ -154,8 +155,7 @@ struct call_data {
   grpc_completion_queue *cq_new;
 
   grpc_metadata_batch *recv_initial_metadata;
-  bool recv_idempotent_request;
-  bool recv_cacheable_request;
+  uint32_t recv_initial_metadata_flags;
   grpc_metadata_array initial_metadata;
 
   request_matcher *request_matcher;
@@ -212,6 +212,11 @@ struct grpc_server {
   gpr_mu mu_global; /* mutex for server and channel state */
   gpr_mu mu_call;   /* mutex for call-specific state */
 
+  /* startup synchronization: flag is protected by mu_global, signals whether
+     we are doing the listener start routine or not */
+  bool starting;
+  gpr_cv starting_cv;
+
   registered_method *registered_methods;
   /** one request matcher for unregistered methods */
   request_matcher unregistered_request_matcher;
@@ -288,10 +293,10 @@ static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
   grpc_channel_element *elem;
 
   op->goaway_error =
-      send_goaway
-          ? grpc_error_set_int(GRPC_ERROR_CREATE("Server shutdown"),
-                               GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_OK)
-          : GRPC_ERROR_NONE;
+      send_goaway ? grpc_error_set_int(
+                        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server shutdown"),
+                        GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_OK)
+                  : GRPC_ERROR_NONE;
   op->set_accept_stream = true;
   sc->slice = grpc_slice_from_copied_string("Server shutdown");
   op->disconnect_with_error = send_disconnect;
@@ -340,7 +345,7 @@ static void request_matcher_destroy(request_matcher *rm) {
 
 static void kill_zombie(grpc_exec_ctx *exec_ctx, void *elem,
                         grpc_error *error) {
-  grpc_call_destroy(grpc_call_from_top_element(elem));
+  grpc_call_unref(grpc_call_from_top_element(elem));
 }
 
 static void request_matcher_zombify_all_pending_calls(grpc_exec_ctx *exec_ctx,
@@ -389,6 +394,7 @@ static void server_delete(grpc_exec_ctx *exec_ctx, grpc_server *server) {
   grpc_channel_args_destroy(exec_ctx, server->channel_args);
   gpr_mu_destroy(&server->mu_global);
   gpr_mu_destroy(&server->mu_call);
+  gpr_cv_destroy(&server->starting_cv);
   while ((rm = server->registered_methods) != NULL) {
     server->registered_methods = rm->next;
     if (server->started) {
@@ -498,13 +504,7 @@ static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
       rc->data.batch.details->host = grpc_slice_ref_internal(calld->host);
       rc->data.batch.details->method = grpc_slice_ref_internal(calld->path);
       rc->data.batch.details->deadline = calld->deadline;
-      rc->data.batch.details->flags =
-          (calld->recv_idempotent_request
-               ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST
-               : 0) |
-          (calld->recv_cacheable_request
-               ? GRPC_INITIAL_METADATA_CACHEABLE_REQUEST
-               : 0);
+      rc->data.batch.details->flags = calld->recv_initial_metadata_flags;
       break;
     case REGISTERED_CALL:
       *rc->data.registered.deadline = calld->deadline;
@@ -632,7 +632,8 @@ static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
       if (!grpc_slice_eq(rm->host, calld->host)) continue;
       if (!grpc_slice_eq(rm->method, calld->path)) continue;
       if ((rm->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) &&
-          !calld->recv_idempotent_request) {
+          0 == (calld->recv_initial_metadata_flags &
+                GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST)) {
         continue;
       }
       finish_start_new_rpc(exec_ctx, server, elem,
@@ -649,7 +650,8 @@ static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
       if (rm->has_host) continue;
       if (!grpc_slice_eq(rm->method, calld->path)) continue;
       if ((rm->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) &&
-          !calld->recv_idempotent_request) {
+          0 == (calld->recv_initial_metadata_flags &
+                GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST)) {
         continue;
       }
       finish_start_new_rpc(exec_ctx, server, elem,
@@ -712,8 +714,9 @@ static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
     return;
   }
 
-  kill_pending_work_locked(exec_ctx, server,
-                           GRPC_ERROR_CREATE("Server Shutdown"));
+  kill_pending_work_locked(
+      exec_ctx, server,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server Shutdown"));
 
   if (server->root_channel_data.next != &server->root_channel_data ||
       server->listeners_destroyed < num_listeners(server)) {
@@ -771,8 +774,8 @@ static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
     /* do nothing */
   } else {
     grpc_error *src_error = error;
-    error =
-        GRPC_ERROR_CREATE_REFERENCING("Missing :authority or :path", &error, 1);
+    error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+        "Missing :authority or :path", &error, 1);
     GRPC_ERROR_UNREF(src_error);
   }
 
@@ -780,22 +783,25 @@ static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
 }
 
 static void server_mutate_op(grpc_call_element *elem,
-                             grpc_transport_stream_op *op) {
+                             grpc_transport_stream_op_batch *op) {
   call_data *calld = elem->call_data;
 
-  if (op->recv_initial_metadata != NULL) {
-    GPR_ASSERT(op->recv_idempotent_request == NULL);
-    calld->recv_initial_metadata = op->recv_initial_metadata;
-    calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready;
-    op->recv_initial_metadata_ready = &calld->server_on_recv_initial_metadata;
-    op->recv_idempotent_request = &calld->recv_idempotent_request;
-    op->recv_cacheable_request = &calld->recv_cacheable_request;
+  if (op->recv_initial_metadata) {
+    GPR_ASSERT(op->payload->recv_initial_metadata.recv_flags == NULL);
+    calld->recv_initial_metadata =
+        op->payload->recv_initial_metadata.recv_initial_metadata;
+    calld->on_done_recv_initial_metadata =
+        op->payload->recv_initial_metadata.recv_initial_metadata_ready;
+    op->payload->recv_initial_metadata.recv_initial_metadata_ready =
+        &calld->server_on_recv_initial_metadata;
+    op->payload->recv_initial_metadata.recv_flags =
+        &calld->recv_initial_metadata_flags;
   }
 }
 
-static void server_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
-                                             grpc_call_element *elem,
-                                             grpc_transport_stream_op *op) {
+static void server_start_transport_stream_op_batch(
+    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+    grpc_transport_stream_op_batch *op) {
   GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
   server_mutate_op(elem, op);
   grpc_call_next_op(exec_ctx, elem, op);
@@ -898,7 +904,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
 
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
-                              void *ignored) {
+                              grpc_closure *ignored) {
   channel_data *chand = elem->channel_data;
   call_data *calld = elem->call_data;
 
@@ -959,7 +965,7 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
 }
 
 const grpc_channel_filter grpc_server_top_filter = {
-    server_start_transport_stream_op,
+    server_start_transport_stream_op_batch,
     grpc_channel_next_op,
     sizeof(call_data),
     init_call_elem,
@@ -975,7 +981,7 @@ const grpc_channel_filter grpc_server_top_filter = {
 
 static void register_completion_queue(grpc_server *server,
                                       grpc_completion_queue *cq,
-                                      bool is_non_listening, void *reserved) {
+                                      void *reserved) {
   size_t i, n;
   GPR_ASSERT(!reserved);
   for (i = 0; i < server->cq_count; i++) {
@@ -984,10 +990,6 @@ static void register_completion_queue(grpc_server *server,
 
   grpc_cq_mark_server_cq(cq);
 
-  if (is_non_listening) {
-    grpc_cq_mark_non_listening_server_cq(cq);
-  }
-
   GRPC_CQ_INTERNAL_REF(cq, "server");
   n = server->cq_count++;
   server->cqs = gpr_realloc(server->cqs,
@@ -1001,16 +1003,16 @@ void grpc_server_register_completion_queue(grpc_server *server,
   GRPC_API_TRACE(
       "grpc_server_register_completion_queue(server=%p, cq=%p, reserved=%p)", 3,
       (server, cq, reserved));
-  register_completion_queue(server, cq, false, reserved);
-}
 
-void grpc_server_register_non_listening_completion_queue(
-    grpc_server *server, grpc_completion_queue *cq, void *reserved) {
-  GRPC_API_TRACE(
-      "grpc_server_register_non_listening_completion_queue(server=%p, cq=%p, "
-      "reserved=%p)",
-      3, (server, cq, reserved));
-  register_completion_queue(server, cq, true, reserved);
+  if (grpc_get_cq_completion_type(cq) != GRPC_CQ_NEXT) {
+    gpr_log(GPR_INFO,
+            "Completion queue which is not of type GRPC_CQ_NEXT is being "
+            "registered as a server-completion-queue");
+    /* Ideally we should log an error and abort but ruby-wrapped-language API
+       calls grpc_completion_queue_pluck() on server completion queues */
+  }
+
+  register_completion_queue(server, cq, reserved);
 }
 
 grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) {
@@ -1018,10 +1020,9 @@ grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) {
 
   grpc_server *server = gpr_zalloc(sizeof(grpc_server));
 
-  GPR_ASSERT(grpc_is_initialized() && "call grpc_init()");
-
   gpr_mu_init(&server->mu_global);
   gpr_mu_init(&server->mu_call);
+  gpr_cv_init(&server->starting_cv);
 
   /* decremented by grpc_server_destroy */
   gpr_ref_init(&server->internal_refcount, 1);
@@ -1078,8 +1079,22 @@ void *grpc_server_register_method(
   return m;
 }
 
+static void start_listeners(grpc_exec_ctx *exec_ctx, void *s,
+                            grpc_error *error) {
+  grpc_server *server = s;
+  for (listener *l = server->listeners; l; l = l->next) {
+    l->start(exec_ctx, server, l->arg, server->pollsets, server->pollset_count);
+  }
+
+  gpr_mu_lock(&server->mu_global);
+  server->starting = false;
+  gpr_cv_signal(&server->starting_cv);
+  gpr_mu_unlock(&server->mu_global);
+
+  server_unref(exec_ctx, server);
+}
+
 void grpc_server_start(grpc_server *server) {
-  listener *l;
   size_t i;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
@@ -1093,7 +1108,7 @@ void grpc_server_start(grpc_server *server) {
   server->requested_calls_per_cq =
       gpr_malloc(sizeof(*server->requested_calls_per_cq) * server->cq_count);
   for (i = 0; i < server->cq_count; i++) {
-    if (!grpc_cq_is_non_listening_server_cq(server->cqs[i])) {
+    if (grpc_cq_can_listen(server->cqs[i])) {
       server->pollsets[server->pollset_count++] =
           grpc_cq_pollset(server->cqs[i]);
     }
@@ -1113,10 +1128,11 @@ void grpc_server_start(grpc_server *server) {
                          (size_t)server->max_requested_calls_per_cq, server);
   }
 
-  for (l = server->listeners; l; l = l->next) {
-    l->start(&exec_ctx, server, l->arg, server->pollsets,
-             server->pollset_count);
-  }
+  server_ref(server);
+  server->starting = true;
+  grpc_closure_sched(&exec_ctx, grpc_closure_create(start_listeners, server,
+                                                    grpc_executor_scheduler),
+                     GRPC_ERROR_NONE);
 
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -1219,7 +1235,8 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
   op->on_connectivity_state_change = &chand->channel_connectivity_changed;
   op->connectivity_state = &chand->connectivity_state;
   if (gpr_atm_acq_load(&s->shutdown_flag) != 0) {
-    op->disconnect_with_error = GRPC_ERROR_CREATE("Server shutdown");
+    op->disconnect_with_error =
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server shutdown");
   }
   grpc_transport_perform_op(exec_ctx, transport, op);
 }
@@ -1249,8 +1266,14 @@ void grpc_server_shutdown_and_notify(grpc_server *server,
   GRPC_API_TRACE("grpc_server_shutdown_and_notify(server=%p, cq=%p, tag=%p)", 3,
                  (server, cq, tag));
 
-  /* lock, and gather up some stuff to do */
+  /* wait for startup to be finished: locks mu_global */
   gpr_mu_lock(&server->mu_global);
+  while (server->starting) {
+    gpr_cv_wait(&server->starting_cv, &server->mu_global,
+                gpr_inf_future(GPR_CLOCK_REALTIME));
+  }
+
+  /* stay locked, and gather up some stuff to do */
   grpc_cq_begin_op(cq, tag);
   if (server->shutdown_published) {
     grpc_cq_end_op(&exec_ctx, cq, tag, GRPC_ERROR_NONE, done_published_shutdown,
@@ -1277,8 +1300,9 @@ void grpc_server_shutdown_and_notify(grpc_server *server,
 
   /* collect all unregistered then registered calls */
   gpr_mu_lock(&server->mu_call);
-  kill_pending_work_locked(&exec_ctx, server,
-                           GRPC_ERROR_CREATE("Server Shutdown"));
+  kill_pending_work_locked(
+      &exec_ctx, server,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server Shutdown"));
   gpr_mu_unlock(&server->mu_call);
 
   maybe_finish_shutdown(&exec_ctx, server);
@@ -1308,8 +1332,9 @@ void grpc_server_cancel_all_calls(grpc_server *server) {
   channel_broadcaster_init(server, &broadcaster);
   gpr_mu_unlock(&server->mu_global);
 
-  channel_broadcaster_shutdown(&exec_ctx, &broadcaster, false /* send_goaway */,
-                               GRPC_ERROR_CREATE("Cancelling all calls"));
+  channel_broadcaster_shutdown(
+      &exec_ctx, &broadcaster, false /* send_goaway */,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Cancelling all calls"));
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
@@ -1357,16 +1382,16 @@ static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx,
   int request_id;
   if (gpr_atm_acq_load(&server->shutdown_flag)) {
     fail_call(exec_ctx, server, cq_idx, rc,
-              GRPC_ERROR_CREATE("Server Shutdown"));
+              GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server Shutdown"));
     return GRPC_CALL_OK;
   }
   request_id = gpr_stack_lockfree_pop(server->request_freelist_per_cq[cq_idx]);
   if (request_id == -1) {
     /* out of request ids: just fail this one */
     fail_call(exec_ctx, server, cq_idx, rc,
-              grpc_error_set_int(GRPC_ERROR_CREATE("Out of request ids"),
-                                 GRPC_ERROR_INT_LIMIT,
-                                 server->max_requested_calls_per_cq));
+              grpc_error_set_int(
+                  GRPC_ERROR_CREATE_FROM_STATIC_STRING("Out of request ids"),
+                  GRPC_ERROR_INT_LIMIT, server->max_requested_calls_per_cq));
     return GRPC_CALL_OK;
   }
   switch (rc->type) {
diff --git a/src/core/lib/surface/validate_metadata.c b/src/core/lib/surface/validate_metadata.c
index 7ec9137265dac05495de4147e83997662f1382f7..6e76c4efe70e5235109df32d85610e6732c875c2 100644
--- a/src/core/lib/surface/validate_metadata.c
+++ b/src/core/lib/surface/validate_metadata.c
@@ -39,6 +39,7 @@
 #include <grpc/support/port_platform.h>
 
 #include "src/core/lib/iomgr/error.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 
 static grpc_error *conforms_to(grpc_slice slice, const uint8_t *legal_bits,
@@ -52,9 +53,10 @@ static grpc_error *conforms_to(grpc_slice slice, const uint8_t *legal_bits,
     if ((legal_bits[byte] & (1 << bit)) == 0) {
       char *dump = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
       grpc_error *error = grpc_error_set_str(
-          grpc_error_set_int(GRPC_ERROR_CREATE(err_desc), GRPC_ERROR_INT_OFFSET,
+          grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(err_desc),
+                             GRPC_ERROR_INT_OFFSET,
                              p - GRPC_SLICE_START_PTR(slice)),
-          GRPC_ERROR_STR_RAW_BYTES, dump);
+          GRPC_ERROR_STR_RAW_BYTES, grpc_slice_from_copied_string(dump));
       gpr_free(dump);
       return error;
     }
@@ -74,10 +76,12 @@ grpc_error *grpc_validate_header_key_is_legal(grpc_slice slice) {
       0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
   if (GRPC_SLICE_LENGTH(slice) == 0) {
-    return GRPC_ERROR_CREATE("Metadata keys cannot be zero length");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Metadata keys cannot be zero length");
   }
   if (GRPC_SLICE_START_PTR(slice)[0] == ':') {
-    return GRPC_ERROR_CREATE("Metadata keys cannot start with :");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Metadata keys cannot start with :");
   }
   return conforms_to(slice, legal_header_bits, "Illegal header key");
 }
diff --git a/src/core/lib/surface/version.c b/src/core/lib/surface/version.c
index 1143a9e044e97901e084416f670755494b66dacd..cddc595e4c9b2d35abaf2cc8ccf86965cb229d00 100644
--- a/src/core/lib/surface/version.c
+++ b/src/core/lib/surface/version.c
@@ -36,6 +36,6 @@
 
 #include <grpc/grpc.h>
 
-const char *grpc_version_string(void) { return "3.0.0-dev"; }
+const char *grpc_version_string(void) { return "4.0.0-dev"; }
 
-const char *grpc_g_stands_for(void) { return "green"; }
+const char *grpc_g_stands_for(void) { return "gregarious"; }
diff --git a/src/core/lib/transport/bdp_estimator.h b/src/core/lib/transport/bdp_estimator.h
index bcaf899910d00bdfb298ba21939f510fbc83a41b..df8d1f6fc0f12cff0f45e3b104fc472af901cc1a 100644
--- a/src/core/lib/transport/bdp_estimator.h
+++ b/src/core/lib/transport/bdp_estimator.h
@@ -73,4 +73,4 @@ void grpc_bdp_estimator_start_ping(grpc_bdp_estimator *estimator);
 // Completes a previously started ping
 void grpc_bdp_estimator_complete_ping(grpc_bdp_estimator *estimator);
 
-#endif
+#endif /* GRPC_CORE_LIB_TRANSPORT_BDP_ESTIMATOR_H */
diff --git a/src/core/lib/transport/byte_stream.c b/src/core/lib/transport/byte_stream.c
index 4d4206189e7be0243148d9cebb9b8962f2bd4701..5800c70ef4456ca475572bfa81f83c89ba9c7730 100644
--- a/src/core/lib/transport/byte_stream.c
+++ b/src/core/lib/transport/byte_stream.c
@@ -40,10 +40,15 @@
 #include "src/core/lib/slice/slice_internal.h"
 
 int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx,
-                          grpc_byte_stream *byte_stream, grpc_slice *slice,
-                          size_t max_size_hint, grpc_closure *on_complete) {
-  return byte_stream->next(exec_ctx, byte_stream, slice, max_size_hint,
-                           on_complete);
+                          grpc_byte_stream *byte_stream, size_t max_size_hint,
+                          grpc_closure *on_complete) {
+  return byte_stream->next(exec_ctx, byte_stream, max_size_hint, on_complete);
+}
+
+grpc_error *grpc_byte_stream_pull(grpc_exec_ctx *exec_ctx,
+                                  grpc_byte_stream *byte_stream,
+                                  grpc_slice *slice) {
+  return byte_stream->pull(exec_ctx, byte_stream, slice);
 }
 
 void grpc_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
@@ -53,16 +58,24 @@ void grpc_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
 
 /* slice_buffer_stream */
 
-static int slice_buffer_stream_next(grpc_exec_ctx *exec_ctx,
-                                    grpc_byte_stream *byte_stream,
-                                    grpc_slice *slice, size_t max_size_hint,
-                                    grpc_closure *on_complete) {
+static bool slice_buffer_stream_next(grpc_exec_ctx *exec_ctx,
+                                     grpc_byte_stream *byte_stream,
+                                     size_t max_size_hint,
+                                     grpc_closure *on_complete) {
+  grpc_slice_buffer_stream *stream = (grpc_slice_buffer_stream *)byte_stream;
+  GPR_ASSERT(stream->cursor < stream->backing_buffer->count);
+  return true;
+}
+
+static grpc_error *slice_buffer_stream_pull(grpc_exec_ctx *exec_ctx,
+                                            grpc_byte_stream *byte_stream,
+                                            grpc_slice *slice) {
   grpc_slice_buffer_stream *stream = (grpc_slice_buffer_stream *)byte_stream;
   GPR_ASSERT(stream->cursor < stream->backing_buffer->count);
   *slice =
       grpc_slice_ref_internal(stream->backing_buffer->slices[stream->cursor]);
   stream->cursor++;
-  return 1;
+  return GRPC_ERROR_NONE;
 }
 
 static void slice_buffer_stream_destroy(grpc_exec_ctx *exec_ctx,
@@ -75,6 +88,7 @@ void grpc_slice_buffer_stream_init(grpc_slice_buffer_stream *stream,
   stream->base.length = (uint32_t)slice_buffer->length;
   stream->base.flags = flags;
   stream->base.next = slice_buffer_stream_next;
+  stream->base.pull = slice_buffer_stream_pull;
   stream->base.destroy = slice_buffer_stream_destroy;
   stream->backing_buffer = slice_buffer;
   stream->cursor = 0;
diff --git a/src/core/lib/transport/byte_stream.h b/src/core/lib/transport/byte_stream.h
index 1fdd5b4d77529f0ad84332bd2be4e9c85185b08b..381c65fb044bcc159f0552a3e26a634653ace868 100644
--- a/src/core/lib/transport/byte_stream.h
+++ b/src/core/lib/transport/byte_stream.h
@@ -49,9 +49,10 @@ typedef struct grpc_byte_stream grpc_byte_stream;
 struct grpc_byte_stream {
   uint32_t length;
   uint32_t flags;
-  int (*next)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream,
-              grpc_slice *slice, size_t max_size_hint,
-              grpc_closure *on_complete);
+  bool (*next)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream,
+               size_t max_size_hint, grpc_closure *on_complete);
+  grpc_error *(*pull)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream,
+                      grpc_slice *slice);
   void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream);
 };
 
@@ -61,12 +62,20 @@ struct grpc_byte_stream {
  *
  * max_size_hint can be set as a hint as to the maximum number
  * of bytes that would be acceptable to read.
+ */
+int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx,
+                          grpc_byte_stream *byte_stream, size_t max_size_hint,
+                          grpc_closure *on_complete);
+
+/* returns the next slice in the byte stream when it is ready (indicated by
+ * either grpc_byte_stream_next returning 1 or on_complete passed to
+ * grpc_byte_stream_next is called).
  *
  * once a slice is returned into *slice, it is owned by the caller.
  */
-int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx,
-                          grpc_byte_stream *byte_stream, grpc_slice *slice,
-                          size_t max_size_hint, grpc_closure *on_complete);
+grpc_error *grpc_byte_stream_pull(grpc_exec_ctx *exec_ctx,
+                                  grpc_byte_stream *byte_stream,
+                                  grpc_slice *slice);
 
 void grpc_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
                               grpc_byte_stream *byte_stream);
diff --git a/src/core/lib/transport/connectivity_state.c b/src/core/lib/transport/connectivity_state.c
index afe1f6164d71974baa52c508cc730347067a2643..3757b252676850f460f9474bf1daf6742270f8f2 100644
--- a/src/core/lib/transport/connectivity_state.c
+++ b/src/core/lib/transport/connectivity_state.c
@@ -79,7 +79,8 @@ void grpc_connectivity_state_destroy(grpc_exec_ctx *exec_ctx,
       *w->current = GRPC_CHANNEL_SHUTDOWN;
       error = GRPC_ERROR_NONE;
     } else {
-      error = GRPC_ERROR_CREATE("Shutdown connectivity owner");
+      error =
+          GRPC_ERROR_CREATE_FROM_STATIC_STRING("Shutdown connectivity owner");
     }
     grpc_closure_sched(exec_ctx, w->notify, error);
     gpr_free(w);
diff --git a/src/core/lib/transport/error_utils.c b/src/core/lib/transport/error_utils.c
index da77828d9c11bb7ea9c13691d3711fe78de808c1..4e70f8749d5d5348008eaa269e561d7e486bde46 100644
--- a/src/core/lib/transport/error_utils.c
+++ b/src/core/lib/transport/error_utils.c
@@ -44,18 +44,18 @@ static grpc_error *recursively_find_error_with_field(grpc_error *error,
   }
   if (grpc_error_is_special(error)) return NULL;
   // Otherwise, search through its children.
-  intptr_t key = 0;
-  while (true) {
-    grpc_error *child_error = gpr_avl_get(error->errs, (void *)key++);
-    if (child_error == NULL) break;
-    grpc_error *result = recursively_find_error_with_field(child_error, which);
-    if (result != NULL) return result;
+  uint8_t slot = error->first_err;
+  while (slot != UINT8_MAX) {
+    grpc_linked_error *lerr = (grpc_linked_error *)(error->arena + slot);
+    grpc_error *result = recursively_find_error_with_field(lerr->err, which);
+    if (result) return result;
+    slot = lerr->next;
   }
   return NULL;
 }
 
 void grpc_error_get_status(grpc_error *error, gpr_timespec deadline,
-                           grpc_status_code *code, const char **msg,
+                           grpc_status_code *code, grpc_slice *slice,
                            grpc_http2_error_code *http_error) {
   // Start with the parent error and recurse through the tree of children
   // until we find the first one that has a status code.
@@ -97,11 +97,11 @@ void grpc_error_get_status(grpc_error *error, gpr_timespec deadline,
 
   // If the error has a status message, use it.  Otherwise, fall back to
   // the error description.
-  if (msg != NULL) {
-    *msg = grpc_error_get_str(found_error, GRPC_ERROR_STR_GRPC_MESSAGE);
-    if (*msg == NULL && error != GRPC_ERROR_NONE) {
-      *msg = grpc_error_get_str(found_error, GRPC_ERROR_STR_DESCRIPTION);
-      if (*msg == NULL) *msg = "unknown error";  // Just in case.
+  if (slice != NULL) {
+    if (!grpc_error_get_str(found_error, GRPC_ERROR_STR_GRPC_MESSAGE, slice)) {
+      if (!grpc_error_get_str(found_error, GRPC_ERROR_STR_DESCRIPTION, slice)) {
+        *slice = grpc_slice_from_static_string("unknown error");
+      }
     }
   }
 
@@ -112,13 +112,13 @@ bool grpc_error_has_clear_grpc_status(grpc_error *error) {
   if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, NULL)) {
     return true;
   }
-  intptr_t key = 0;
-  while (true) {
-    grpc_error *child_error = gpr_avl_get(error->errs, (void *)key++);
-    if (child_error == NULL) break;
-    if (grpc_error_has_clear_grpc_status(child_error)) {
+  uint8_t slot = error->first_err;
+  while (slot != UINT8_MAX) {
+    grpc_linked_error *lerr = (grpc_linked_error *)(error->arena + slot);
+    if (grpc_error_has_clear_grpc_status(lerr->err)) {
       return true;
     }
+    slot = lerr->next;
   }
   return false;
 }
diff --git a/src/core/lib/transport/error_utils.h b/src/core/lib/transport/error_utils.h
index 105338880ac89b73e6370750fff0ca6d98283430..3b44466ab830ca935962fd410194bc6bfba041ea 100644
--- a/src/core/lib/transport/error_utils.h
+++ b/src/core/lib/transport/error_utils.h
@@ -44,7 +44,7 @@
 /// attributes (code, msg, http_status) are unneeded, they can be passed as
 /// NULL.
 void grpc_error_get_status(grpc_error *error, gpr_timespec deadline,
-                           grpc_status_code *code, const char **msg,
+                           grpc_status_code *code, grpc_slice *slice,
                            grpc_http2_error_code *http_status);
 
 /// A utility function to check whether there is a clear status code that
diff --git a/src/core/lib/transport/metadata_batch.c b/src/core/lib/transport/metadata_batch.c
index fc2c52bd8a6f1bade9757e18b9296c08c97e28fe..fa73244aa43b9062d335e4e5222e264661bc61ce 100644
--- a/src/core/lib/transport/metadata_batch.c
+++ b/src/core/lib/transport/metadata_batch.c
@@ -101,12 +101,10 @@ void grpc_metadata_batch_destroy(grpc_exec_ctx *exec_ctx,
 }
 
 grpc_error *grpc_attach_md_to_error(grpc_error *src, grpc_mdelem md) {
-  char *k = grpc_slice_to_c_string(GRPC_MDKEY(md));
-  char *v = grpc_slice_to_c_string(GRPC_MDVALUE(md));
   grpc_error *out = grpc_error_set_str(
-      grpc_error_set_str(src, GRPC_ERROR_STR_KEY, k), GRPC_ERROR_STR_VALUE, v);
-  gpr_free(k);
-  gpr_free(v);
+      grpc_error_set_str(src, GRPC_ERROR_STR_KEY,
+                         grpc_slice_ref_internal(GRPC_MDKEY(md))),
+      GRPC_ERROR_STR_VALUE, grpc_slice_ref_internal(GRPC_MDVALUE(md)));
   return out;
 }
 
@@ -126,7 +124,8 @@ static grpc_error *maybe_link_callout(grpc_metadata_batch *batch,
     return GRPC_ERROR_NONE;
   }
   return grpc_attach_md_to_error(
-      GRPC_ERROR_CREATE("Unallowed duplicate metadata"), storage->md);
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Unallowed duplicate metadata"),
+      storage->md);
 }
 
 static void maybe_unlink_callout(grpc_metadata_batch *batch,
@@ -302,7 +301,7 @@ static void add_error(grpc_error **composite, grpc_error *error,
                       const char *composite_error_string) {
   if (error == GRPC_ERROR_NONE) return;
   if (*composite == GRPC_ERROR_NONE) {
-    *composite = GRPC_ERROR_CREATE(composite_error_string);
+    *composite = GRPC_ERROR_CREATE_FROM_COPIED_STRING(composite_error_string);
   }
   *composite = grpc_error_add_child(*composite, error);
 }
diff --git a/src/core/lib/transport/pid_controller.c b/src/core/lib/transport/pid_controller.c
index 19cb1c0b367d0aea0b6298a0d4153242317e3172..c851564201f2eba8015f3924fc456becb4b95a3b 100644
--- a/src/core/lib/transport/pid_controller.c
+++ b/src/core/lib/transport/pid_controller.c
@@ -49,6 +49,7 @@ void grpc_pid_controller_reset(grpc_pid_controller *pid_controller) {
 
 double grpc_pid_controller_update(grpc_pid_controller *pid_controller,
                                   double error, double dt) {
+  if (dt == 0) return pid_controller->last_control_value;
   /* integrate error using the trapezoid rule */
   pid_controller->error_integral +=
       dt * (pid_controller->last_error + error) * 0.5;
diff --git a/src/core/lib/transport/service_config.c b/src/core/lib/transport/service_config.c
index 12da2a88feb9537ace387c80d8be1fa13157cb75..6aecb7fa936369c24e904e796fc102c2d3b958fc 100644
--- a/src/core/lib/transport/service_config.c
+++ b/src/core/lib/transport/service_config.c
@@ -93,6 +93,18 @@ void grpc_service_config_destroy(grpc_service_config* service_config) {
   gpr_free(service_config);
 }
 
+void grpc_service_config_parse_global_params(
+    const grpc_service_config* service_config,
+    void (*process_json)(const grpc_json* json, void* arg), void* arg) {
+  const grpc_json* json = service_config->json_tree;
+  if (json->type != GRPC_JSON_OBJECT || json->key != NULL) return;
+  for (grpc_json* field = json->child; field != NULL; field = field->next) {
+    if (field->key == NULL) return;
+    if (strcmp(field->key, "methodConfig") == 0) continue;
+    process_json(field, arg);
+  }
+}
+
 const char* grpc_service_config_get_lb_policy_name(
     const grpc_service_config* service_config) {
   const grpc_json* json = service_config->json_tree;
@@ -150,7 +162,6 @@ static char* parse_json_method_name(grpc_json* json) {
 static bool parse_json_method_config(
     grpc_exec_ctx* exec_ctx, grpc_json* json,
     void* (*create_value)(const grpc_json* method_config_json),
-    const grpc_slice_hash_table_vtable* vtable,
     grpc_slice_hash_table_entry* entries, size_t* idx) {
   // Construct value.
   void* method_config = create_value(json);
@@ -173,13 +184,11 @@ static bool parse_json_method_config(
   // Add entry for each path.
   for (size_t i = 0; i < paths.count; ++i) {
     entries[*idx].key = grpc_slice_from_copied_string(paths.strs[i]);
-    entries[*idx].value = vtable->copy_value(method_config);
-    entries[*idx].vtable = vtable;
+    entries[*idx].value = method_config;
     ++*idx;
   }
   success = true;
 done:
-  vtable->destroy_value(exec_ctx, method_config);
   gpr_strvec_destroy(&paths);
   return success;
 }
@@ -187,7 +196,7 @@ done:
 grpc_slice_hash_table* grpc_service_config_create_method_config_table(
     grpc_exec_ctx* exec_ctx, const grpc_service_config* service_config,
     void* (*create_value)(const grpc_json* method_config_json),
-    const grpc_slice_hash_table_vtable* vtable) {
+    void (*destroy_value)(grpc_exec_ctx* exec_ctx, void* value)) {
   const grpc_json* json = service_config->json_tree;
   // Traverse parsed JSON tree.
   if (json->type != GRPC_JSON_OBJECT || json->key != NULL) return NULL;
@@ -208,8 +217,8 @@ grpc_slice_hash_table* grpc_service_config_create_method_config_table(
       size_t idx = 0;
       for (grpc_json* method = field->child; method != NULL;
            method = method->next) {
-        if (!parse_json_method_config(exec_ctx, method, create_value, vtable,
-                                      entries, &idx)) {
+        if (!parse_json_method_config(exec_ctx, method, create_value, entries,
+                                      &idx)) {
           return NULL;
         }
       }
@@ -219,12 +228,8 @@ grpc_slice_hash_table* grpc_service_config_create_method_config_table(
   // Instantiate method config table.
   grpc_slice_hash_table* method_config_table = NULL;
   if (entries != NULL) {
-    method_config_table = grpc_slice_hash_table_create(num_entries, entries);
-    // Clean up.
-    for (size_t i = 0; i < num_entries; ++i) {
-      grpc_slice_unref_internal(exec_ctx, entries[i].key);
-      vtable->destroy_value(exec_ctx, entries[i].value);
-    }
+    method_config_table =
+        grpc_slice_hash_table_create(num_entries, entries, destroy_value);
     gpr_free(entries);
   }
   return method_config_table;
diff --git a/src/core/lib/transport/service_config.h b/src/core/lib/transport/service_config.h
index cd739a593c27f939d2d7963ecee4d84e9619aa65..e0548b9c3fa3c17c59ec4eed40405dc8b1f842fe 100644
--- a/src/core/lib/transport/service_config.h
+++ b/src/core/lib/transport/service_config.h
@@ -42,6 +42,12 @@ typedef struct grpc_service_config grpc_service_config;
 grpc_service_config* grpc_service_config_create(const char* json_string);
 void grpc_service_config_destroy(grpc_service_config* service_config);
 
+/// Invokes \a process_json() for each global parameter in the service
+/// config.  \a arg is passed as the second argument to \a process_json().
+void grpc_service_config_parse_global_params(
+    const grpc_service_config* service_config,
+    void (*process_json)(const grpc_json* json, void* arg), void* arg);
+
 /// Gets the LB policy name from \a service_config.
 /// Returns NULL if no LB policy name was specified.
 /// Caller does NOT take ownership.
@@ -51,12 +57,12 @@ const char* grpc_service_config_get_lb_policy_name(
 /// Creates a method config table based on the data in \a json.
 /// The table's keys are request paths.  The table's value type is
 /// returned by \a create_value(), based on data parsed from the JSON tree.
-/// \a vtable provides methods used to manage the values.
+/// \a destroy_value is used to clean up values.
 /// Returns NULL on error.
 grpc_slice_hash_table* grpc_service_config_create_method_config_table(
     grpc_exec_ctx* exec_ctx, const grpc_service_config* service_config,
     void* (*create_value)(const grpc_json* method_config_json),
-    const grpc_slice_hash_table_vtable* vtable);
+    void (*destroy_value)(grpc_exec_ctx* exec_ctx, void* value));
 
 /// A helper function for looking up values in the table returned by
 /// \a grpc_service_config_create_method_config_table().
diff --git a/src/core/lib/transport/static_metadata.c b/src/core/lib/transport/static_metadata.c
index c13ba230b325a721b60e7f71ea13e71d4ef4c836..862cdaa8e09c3aedd11b40140a672131d7b388d2 100644
--- a/src/core/lib/transport/static_metadata.c
+++ b/src/core/lib/transport/static_metadata.c
@@ -51,67 +51,69 @@ static uint8_t g_bytes[] = {
     115, 103, 114, 112, 99,  45,  112, 97,  121, 108, 111, 97,  100, 45,  98,
     105, 110, 103, 114, 112, 99,  45,  101, 110, 99,  111, 100, 105, 110, 103,
     103, 114, 112, 99,  45,  97,  99,  99,  101, 112, 116, 45,  101, 110, 99,
-    111, 100, 105, 110, 103, 99,  111, 110, 116, 101, 110, 116, 45,  116, 121,
-    112, 101, 103, 114, 112, 99,  45,  105, 110, 116, 101, 114, 110, 97,  108,
-    45,  101, 110, 99,  111, 100, 105, 110, 103, 45,  114, 101, 113, 117, 101,
-    115, 116, 117, 115, 101, 114, 45,  97,  103, 101, 110, 116, 104, 111, 115,
-    116, 108, 98,  45,  116, 111, 107, 101, 110, 103, 114, 112, 99,  45,  116,
-    105, 109, 101, 111, 117, 116, 103, 114, 112, 99,  45,  116, 114, 97,  99,
-    105, 110, 103, 45,  98,  105, 110, 103, 114, 112, 99,  45,  115, 116, 97,
-    116, 115, 45,  98,  105, 110, 103, 114, 112, 99,  46,  119, 97,  105, 116,
-    95,  102, 111, 114, 95,  114, 101, 97,  100, 121, 103, 114, 112, 99,  46,
-    116, 105, 109, 101, 111, 117, 116, 103, 114, 112, 99,  46,  109, 97,  120,
-    95,  114, 101, 113, 117, 101, 115, 116, 95,  109, 101, 115, 115, 97,  103,
-    101, 95,  98,  121, 116, 101, 115, 103, 114, 112, 99,  46,  109, 97,  120,
-    95,  114, 101, 115, 112, 111, 110, 115, 101, 95,  109, 101, 115, 115, 97,
-    103, 101, 95,  98,  121, 116, 101, 115, 47,  103, 114, 112, 99,  46,  108,
-    98,  46,  118, 49,  46,  76,  111, 97,  100, 66,  97,  108, 97,  110, 99,
-    101, 114, 47,  66,  97,  108, 97,  110, 99,  101, 76,  111, 97,  100, 48,
-    49,  50,  105, 100, 101, 110, 116, 105, 116, 121, 103, 122, 105, 112, 100,
-    101, 102, 108, 97,  116, 101, 116, 114, 97,  105, 108, 101, 114, 115, 97,
-    112, 112, 108, 105, 99,  97,  116, 105, 111, 110, 47,  103, 114, 112, 99,
-    80,  79,  83,  84,  50,  48,  48,  52,  48,  52,  104, 116, 116, 112, 104,
-    116, 116, 112, 115, 103, 114, 112, 99,  71,  69,  84,  80,  85,  84,  47,
-    47,  105, 110, 100, 101, 120, 46,  104, 116, 109, 108, 50,  48,  52,  50,
-    48,  54,  51,  48,  52,  52,  48,  48,  53,  48,  48,  97,  99,  99,  101,
-    112, 116, 45,  99,  104, 97,  114, 115, 101, 116, 97,  99,  99,  101, 112,
-    116, 45,  101, 110, 99,  111, 100, 105, 110, 103, 103, 122, 105, 112, 44,
-    32,  100, 101, 102, 108, 97,  116, 101, 97,  99,  99,  101, 112, 116, 45,
-    108, 97,  110, 103, 117, 97,  103, 101, 97,  99,  99,  101, 112, 116, 45,
-    114, 97,  110, 103, 101, 115, 97,  99,  99,  101, 112, 116, 97,  99,  99,
-    101, 115, 115, 45,  99,  111, 110, 116, 114, 111, 108, 45,  97,  108, 108,
-    111, 119, 45,  111, 114, 105, 103, 105, 110, 97,  103, 101, 97,  108, 108,
-    111, 119, 97,  117, 116, 104, 111, 114, 105, 122, 97,  116, 105, 111, 110,
-    99,  97,  99,  104, 101, 45,  99,  111, 110, 116, 114, 111, 108, 99,  111,
-    110, 116, 101, 110, 116, 45,  100, 105, 115, 112, 111, 115, 105, 116, 105,
-    111, 110, 99,  111, 110, 116, 101, 110, 116, 45,  101, 110, 99,  111, 100,
-    105, 110, 103, 99,  111, 110, 116, 101, 110, 116, 45,  108, 97,  110, 103,
-    117, 97,  103, 101, 99,  111, 110, 116, 101, 110, 116, 45,  108, 101, 110,
-    103, 116, 104, 99,  111, 110, 116, 101, 110, 116, 45,  108, 111, 99,  97,
-    116, 105, 111, 110, 99,  111, 110, 116, 101, 110, 116, 45,  114, 97,  110,
-    103, 101, 99,  111, 111, 107, 105, 101, 100, 97,  116, 101, 101, 116, 97,
-    103, 101, 120, 112, 101, 99,  116, 101, 120, 112, 105, 114, 101, 115, 102,
-    114, 111, 109, 105, 102, 45,  109, 97,  116, 99,  104, 105, 102, 45,  109,
-    111, 100, 105, 102, 105, 101, 100, 45,  115, 105, 110, 99,  101, 105, 102,
-    45,  110, 111, 110, 101, 45,  109, 97,  116, 99,  104, 105, 102, 45,  114,
-    97,  110, 103, 101, 105, 102, 45,  117, 110, 109, 111, 100, 105, 102, 105,
-    101, 100, 45,  115, 105, 110, 99,  101, 108, 97,  115, 116, 45,  109, 111,
-    100, 105, 102, 105, 101, 100, 108, 105, 110, 107, 108, 111, 99,  97,  116,
-    105, 111, 110, 109, 97,  120, 45,  102, 111, 114, 119, 97,  114, 100, 115,
-    112, 114, 111, 120, 121, 45,  97,  117, 116, 104, 101, 110, 116, 105, 99,
-    97,  116, 101, 112, 114, 111, 120, 121, 45,  97,  117, 116, 104, 111, 114,
-    105, 122, 97,  116, 105, 111, 110, 114, 97,  110, 103, 101, 114, 101, 102,
-    101, 114, 101, 114, 114, 101, 102, 114, 101, 115, 104, 114, 101, 116, 114,
-    121, 45,  97,  102, 116, 101, 114, 115, 101, 114, 118, 101, 114, 115, 101,
-    116, 45,  99,  111, 111, 107, 105, 101, 115, 116, 114, 105, 99,  116, 45,
-    116, 114, 97,  110, 115, 112, 111, 114, 116, 45,  115, 101, 99,  117, 114,
-    105, 116, 121, 116, 114, 97,  110, 115, 102, 101, 114, 45,  101, 110, 99,
-    111, 100, 105, 110, 103, 118, 97,  114, 121, 118, 105, 97,  119, 119, 119,
-    45,  97,  117, 116, 104, 101, 110, 116, 105, 99,  97,  116, 101, 105, 100,
-    101, 110, 116, 105, 116, 121, 44,  100, 101, 102, 108, 97,  116, 101, 105,
-    100, 101, 110, 116, 105, 116, 121, 44,  103, 122, 105, 112, 100, 101, 102,
-    108, 97,  116, 101, 44,  103, 122, 105, 112, 105, 100, 101, 110, 116, 105,
-    116, 121, 44,  100, 101, 102, 108, 97,  116, 101, 44,  103, 122, 105, 112};
+    111, 100, 105, 110, 103, 103, 114, 112, 99,  45,  115, 101, 114, 118, 101,
+    114, 45,  115, 116, 97,  116, 115, 45,  98,  105, 110, 103, 114, 112, 99,
+    45,  116, 97,  103, 115, 45,  98,  105, 110, 103, 114, 112, 99,  45,  116,
+    114, 97,  99,  101, 45,  98,  105, 110, 99,  111, 110, 116, 101, 110, 116,
+    45,  116, 121, 112, 101, 103, 114, 112, 99,  45,  105, 110, 116, 101, 114,
+    110, 97,  108, 45,  101, 110, 99,  111, 100, 105, 110, 103, 45,  114, 101,
+    113, 117, 101, 115, 116, 117, 115, 101, 114, 45,  97,  103, 101, 110, 116,
+    104, 111, 115, 116, 108, 98,  45,  116, 111, 107, 101, 110, 103, 114, 112,
+    99,  45,  116, 105, 109, 101, 111, 117, 116, 103, 114, 112, 99,  46,  119,
+    97,  105, 116, 95,  102, 111, 114, 95,  114, 101, 97,  100, 121, 103, 114,
+    112, 99,  46,  116, 105, 109, 101, 111, 117, 116, 103, 114, 112, 99,  46,
+    109, 97,  120, 95,  114, 101, 113, 117, 101, 115, 116, 95,  109, 101, 115,
+    115, 97,  103, 101, 95,  98,  121, 116, 101, 115, 103, 114, 112, 99,  46,
+    109, 97,  120, 95,  114, 101, 115, 112, 111, 110, 115, 101, 95,  109, 101,
+    115, 115, 97,  103, 101, 95,  98,  121, 116, 101, 115, 47,  103, 114, 112,
+    99,  46,  108, 98,  46,  118, 49,  46,  76,  111, 97,  100, 66,  97,  108,
+    97,  110, 99,  101, 114, 47,  66,  97,  108, 97,  110, 99,  101, 76,  111,
+    97,  100, 48,  49,  50,  105, 100, 101, 110, 116, 105, 116, 121, 103, 122,
+    105, 112, 100, 101, 102, 108, 97,  116, 101, 116, 114, 97,  105, 108, 101,
+    114, 115, 97,  112, 112, 108, 105, 99,  97,  116, 105, 111, 110, 47,  103,
+    114, 112, 99,  80,  79,  83,  84,  50,  48,  48,  52,  48,  52,  104, 116,
+    116, 112, 104, 116, 116, 112, 115, 103, 114, 112, 99,  71,  69,  84,  80,
+    85,  84,  47,  47,  105, 110, 100, 101, 120, 46,  104, 116, 109, 108, 50,
+    48,  52,  50,  48,  54,  51,  48,  52,  52,  48,  48,  53,  48,  48,  97,
+    99,  99,  101, 112, 116, 45,  99,  104, 97,  114, 115, 101, 116, 97,  99,
+    99,  101, 112, 116, 45,  101, 110, 99,  111, 100, 105, 110, 103, 103, 122,
+    105, 112, 44,  32,  100, 101, 102, 108, 97,  116, 101, 97,  99,  99,  101,
+    112, 116, 45,  108, 97,  110, 103, 117, 97,  103, 101, 97,  99,  99,  101,
+    112, 116, 45,  114, 97,  110, 103, 101, 115, 97,  99,  99,  101, 112, 116,
+    97,  99,  99,  101, 115, 115, 45,  99,  111, 110, 116, 114, 111, 108, 45,
+    97,  108, 108, 111, 119, 45,  111, 114, 105, 103, 105, 110, 97,  103, 101,
+    97,  108, 108, 111, 119, 97,  117, 116, 104, 111, 114, 105, 122, 97,  116,
+    105, 111, 110, 99,  97,  99,  104, 101, 45,  99,  111, 110, 116, 114, 111,
+    108, 99,  111, 110, 116, 101, 110, 116, 45,  100, 105, 115, 112, 111, 115,
+    105, 116, 105, 111, 110, 99,  111, 110, 116, 101, 110, 116, 45,  101, 110,
+    99,  111, 100, 105, 110, 103, 99,  111, 110, 116, 101, 110, 116, 45,  108,
+    97,  110, 103, 117, 97,  103, 101, 99,  111, 110, 116, 101, 110, 116, 45,
+    108, 101, 110, 103, 116, 104, 99,  111, 110, 116, 101, 110, 116, 45,  108,
+    111, 99,  97,  116, 105, 111, 110, 99,  111, 110, 116, 101, 110, 116, 45,
+    114, 97,  110, 103, 101, 99,  111, 111, 107, 105, 101, 100, 97,  116, 101,
+    101, 116, 97,  103, 101, 120, 112, 101, 99,  116, 101, 120, 112, 105, 114,
+    101, 115, 102, 114, 111, 109, 105, 102, 45,  109, 97,  116, 99,  104, 105,
+    102, 45,  109, 111, 100, 105, 102, 105, 101, 100, 45,  115, 105, 110, 99,
+    101, 105, 102, 45,  110, 111, 110, 101, 45,  109, 97,  116, 99,  104, 105,
+    102, 45,  114, 97,  110, 103, 101, 105, 102, 45,  117, 110, 109, 111, 100,
+    105, 102, 105, 101, 100, 45,  115, 105, 110, 99,  101, 108, 97,  115, 116,
+    45,  109, 111, 100, 105, 102, 105, 101, 100, 108, 98,  45,  99,  111, 115,
+    116, 45,  98,  105, 110, 108, 105, 110, 107, 108, 111, 99,  97,  116, 105,
+    111, 110, 109, 97,  120, 45,  102, 111, 114, 119, 97,  114, 100, 115, 112,
+    114, 111, 120, 121, 45,  97,  117, 116, 104, 101, 110, 116, 105, 99,  97,
+    116, 101, 112, 114, 111, 120, 121, 45,  97,  117, 116, 104, 111, 114, 105,
+    122, 97,  116, 105, 111, 110, 114, 97,  110, 103, 101, 114, 101, 102, 101,
+    114, 101, 114, 114, 101, 102, 114, 101, 115, 104, 114, 101, 116, 114, 121,
+    45,  97,  102, 116, 101, 114, 115, 101, 114, 118, 101, 114, 115, 101, 116,
+    45,  99,  111, 111, 107, 105, 101, 115, 116, 114, 105, 99,  116, 45,  116,
+    114, 97,  110, 115, 112, 111, 114, 116, 45,  115, 101, 99,  117, 114, 105,
+    116, 121, 116, 114, 97,  110, 115, 102, 101, 114, 45,  101, 110, 99,  111,
+    100, 105, 110, 103, 118, 97,  114, 121, 118, 105, 97,  119, 119, 119, 45,
+    97,  117, 116, 104, 101, 110, 116, 105, 99,  97,  116, 101, 105, 100, 101,
+    110, 116, 105, 116, 121, 44,  100, 101, 102, 108, 97,  116, 101, 105, 100,
+    101, 110, 116, 105, 116, 121, 44,  103, 122, 105, 112, 100, 101, 102, 108,
+    97,  116, 101, 44,  103, 122, 105, 112, 105, 100, 101, 110, 116, 105, 116,
+    121, 44,  100, 101, 102, 108, 97,  116, 101, 44,  103, 122, 105, 112};
 
 static void static_ref(void *unused) {}
 static void static_unref(grpc_exec_ctx *exec_ctx, void *unused) {}
@@ -220,6 +222,8 @@ grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = {
     {&grpc_static_metadata_vtable, &static_sub_refcnt},
     {&grpc_static_metadata_vtable, &static_sub_refcnt},
     {&grpc_static_metadata_vtable, &static_sub_refcnt},
+    {&grpc_static_metadata_vtable, &static_sub_refcnt},
+    {&grpc_static_metadata_vtable, &static_sub_refcnt},
 };
 
 const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {
@@ -246,196 +250,201 @@ const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {
     {.refcount = &grpc_static_metadata_refcounts[10],
      .data.refcounted = {g_bytes + 90, 20}},
     {.refcount = &grpc_static_metadata_refcounts[11],
-     .data.refcounted = {g_bytes + 110, 12}},
+     .data.refcounted = {g_bytes + 110, 21}},
     {.refcount = &grpc_static_metadata_refcounts[12],
-     .data.refcounted = {g_bytes + 122, 30}},
+     .data.refcounted = {g_bytes + 131, 13}},
     {.refcount = &grpc_static_metadata_refcounts[13],
-     .data.refcounted = {g_bytes + 152, 10}},
+     .data.refcounted = {g_bytes + 144, 14}},
     {.refcount = &grpc_static_metadata_refcounts[14],
-     .data.refcounted = {g_bytes + 162, 4}},
+     .data.refcounted = {g_bytes + 158, 12}},
     {.refcount = &grpc_static_metadata_refcounts[15],
-     .data.refcounted = {g_bytes + 166, 8}},
+     .data.refcounted = {g_bytes + 170, 30}},
     {.refcount = &grpc_static_metadata_refcounts[16],
-     .data.refcounted = {g_bytes + 174, 12}},
+     .data.refcounted = {g_bytes + 200, 10}},
     {.refcount = &grpc_static_metadata_refcounts[17],
-     .data.refcounted = {g_bytes + 186, 16}},
+     .data.refcounted = {g_bytes + 210, 4}},
     {.refcount = &grpc_static_metadata_refcounts[18],
-     .data.refcounted = {g_bytes + 202, 14}},
+     .data.refcounted = {g_bytes + 214, 8}},
     {.refcount = &grpc_static_metadata_refcounts[19],
-     .data.refcounted = {g_bytes + 216, 0}},
+     .data.refcounted = {g_bytes + 222, 12}},
     {.refcount = &grpc_static_metadata_refcounts[20],
-     .data.refcounted = {g_bytes + 216, 19}},
+     .data.refcounted = {g_bytes + 234, 0}},
     {.refcount = &grpc_static_metadata_refcounts[21],
-     .data.refcounted = {g_bytes + 235, 12}},
+     .data.refcounted = {g_bytes + 234, 19}},
     {.refcount = &grpc_static_metadata_refcounts[22],
-     .data.refcounted = {g_bytes + 247, 30}},
+     .data.refcounted = {g_bytes + 253, 12}},
     {.refcount = &grpc_static_metadata_refcounts[23],
-     .data.refcounted = {g_bytes + 277, 31}},
+     .data.refcounted = {g_bytes + 265, 30}},
     {.refcount = &grpc_static_metadata_refcounts[24],
-     .data.refcounted = {g_bytes + 308, 36}},
+     .data.refcounted = {g_bytes + 295, 31}},
     {.refcount = &grpc_static_metadata_refcounts[25],
-     .data.refcounted = {g_bytes + 344, 1}},
+     .data.refcounted = {g_bytes + 326, 36}},
     {.refcount = &grpc_static_metadata_refcounts[26],
-     .data.refcounted = {g_bytes + 345, 1}},
+     .data.refcounted = {g_bytes + 362, 1}},
     {.refcount = &grpc_static_metadata_refcounts[27],
-     .data.refcounted = {g_bytes + 346, 1}},
+     .data.refcounted = {g_bytes + 363, 1}},
     {.refcount = &grpc_static_metadata_refcounts[28],
-     .data.refcounted = {g_bytes + 347, 8}},
+     .data.refcounted = {g_bytes + 364, 1}},
     {.refcount = &grpc_static_metadata_refcounts[29],
-     .data.refcounted = {g_bytes + 355, 4}},
+     .data.refcounted = {g_bytes + 365, 8}},
     {.refcount = &grpc_static_metadata_refcounts[30],
-     .data.refcounted = {g_bytes + 359, 7}},
+     .data.refcounted = {g_bytes + 373, 4}},
     {.refcount = &grpc_static_metadata_refcounts[31],
-     .data.refcounted = {g_bytes + 366, 8}},
+     .data.refcounted = {g_bytes + 377, 7}},
     {.refcount = &grpc_static_metadata_refcounts[32],
-     .data.refcounted = {g_bytes + 374, 16}},
+     .data.refcounted = {g_bytes + 384, 8}},
     {.refcount = &grpc_static_metadata_refcounts[33],
-     .data.refcounted = {g_bytes + 390, 4}},
+     .data.refcounted = {g_bytes + 392, 16}},
     {.refcount = &grpc_static_metadata_refcounts[34],
-     .data.refcounted = {g_bytes + 394, 3}},
+     .data.refcounted = {g_bytes + 408, 4}},
     {.refcount = &grpc_static_metadata_refcounts[35],
-     .data.refcounted = {g_bytes + 397, 3}},
+     .data.refcounted = {g_bytes + 412, 3}},
     {.refcount = &grpc_static_metadata_refcounts[36],
-     .data.refcounted = {g_bytes + 400, 4}},
+     .data.refcounted = {g_bytes + 415, 3}},
     {.refcount = &grpc_static_metadata_refcounts[37],
-     .data.refcounted = {g_bytes + 404, 5}},
+     .data.refcounted = {g_bytes + 418, 4}},
     {.refcount = &grpc_static_metadata_refcounts[38],
-     .data.refcounted = {g_bytes + 409, 4}},
+     .data.refcounted = {g_bytes + 422, 5}},
     {.refcount = &grpc_static_metadata_refcounts[39],
-     .data.refcounted = {g_bytes + 413, 3}},
+     .data.refcounted = {g_bytes + 427, 4}},
     {.refcount = &grpc_static_metadata_refcounts[40],
-     .data.refcounted = {g_bytes + 416, 3}},
+     .data.refcounted = {g_bytes + 431, 3}},
     {.refcount = &grpc_static_metadata_refcounts[41],
-     .data.refcounted = {g_bytes + 419, 1}},
+     .data.refcounted = {g_bytes + 434, 3}},
     {.refcount = &grpc_static_metadata_refcounts[42],
-     .data.refcounted = {g_bytes + 420, 11}},
+     .data.refcounted = {g_bytes + 437, 1}},
     {.refcount = &grpc_static_metadata_refcounts[43],
-     .data.refcounted = {g_bytes + 431, 3}},
+     .data.refcounted = {g_bytes + 438, 11}},
     {.refcount = &grpc_static_metadata_refcounts[44],
-     .data.refcounted = {g_bytes + 434, 3}},
+     .data.refcounted = {g_bytes + 449, 3}},
     {.refcount = &grpc_static_metadata_refcounts[45],
-     .data.refcounted = {g_bytes + 437, 3}},
+     .data.refcounted = {g_bytes + 452, 3}},
     {.refcount = &grpc_static_metadata_refcounts[46],
-     .data.refcounted = {g_bytes + 440, 3}},
+     .data.refcounted = {g_bytes + 455, 3}},
     {.refcount = &grpc_static_metadata_refcounts[47],
-     .data.refcounted = {g_bytes + 443, 3}},
+     .data.refcounted = {g_bytes + 458, 3}},
     {.refcount = &grpc_static_metadata_refcounts[48],
-     .data.refcounted = {g_bytes + 446, 14}},
+     .data.refcounted = {g_bytes + 461, 3}},
     {.refcount = &grpc_static_metadata_refcounts[49],
-     .data.refcounted = {g_bytes + 460, 15}},
+     .data.refcounted = {g_bytes + 464, 14}},
     {.refcount = &grpc_static_metadata_refcounts[50],
-     .data.refcounted = {g_bytes + 475, 13}},
+     .data.refcounted = {g_bytes + 478, 15}},
     {.refcount = &grpc_static_metadata_refcounts[51],
-     .data.refcounted = {g_bytes + 488, 15}},
+     .data.refcounted = {g_bytes + 493, 13}},
     {.refcount = &grpc_static_metadata_refcounts[52],
-     .data.refcounted = {g_bytes + 503, 13}},
+     .data.refcounted = {g_bytes + 506, 15}},
     {.refcount = &grpc_static_metadata_refcounts[53],
-     .data.refcounted = {g_bytes + 516, 6}},
+     .data.refcounted = {g_bytes + 521, 13}},
     {.refcount = &grpc_static_metadata_refcounts[54],
-     .data.refcounted = {g_bytes + 522, 27}},
+     .data.refcounted = {g_bytes + 534, 6}},
     {.refcount = &grpc_static_metadata_refcounts[55],
-     .data.refcounted = {g_bytes + 549, 3}},
+     .data.refcounted = {g_bytes + 540, 27}},
     {.refcount = &grpc_static_metadata_refcounts[56],
-     .data.refcounted = {g_bytes + 552, 5}},
+     .data.refcounted = {g_bytes + 567, 3}},
     {.refcount = &grpc_static_metadata_refcounts[57],
-     .data.refcounted = {g_bytes + 557, 13}},
+     .data.refcounted = {g_bytes + 570, 5}},
     {.refcount = &grpc_static_metadata_refcounts[58],
-     .data.refcounted = {g_bytes + 570, 13}},
+     .data.refcounted = {g_bytes + 575, 13}},
     {.refcount = &grpc_static_metadata_refcounts[59],
-     .data.refcounted = {g_bytes + 583, 19}},
+     .data.refcounted = {g_bytes + 588, 13}},
     {.refcount = &grpc_static_metadata_refcounts[60],
-     .data.refcounted = {g_bytes + 602, 16}},
+     .data.refcounted = {g_bytes + 601, 19}},
     {.refcount = &grpc_static_metadata_refcounts[61],
-     .data.refcounted = {g_bytes + 618, 16}},
+     .data.refcounted = {g_bytes + 620, 16}},
     {.refcount = &grpc_static_metadata_refcounts[62],
-     .data.refcounted = {g_bytes + 634, 14}},
+     .data.refcounted = {g_bytes + 636, 16}},
     {.refcount = &grpc_static_metadata_refcounts[63],
-     .data.refcounted = {g_bytes + 648, 16}},
+     .data.refcounted = {g_bytes + 652, 14}},
     {.refcount = &grpc_static_metadata_refcounts[64],
-     .data.refcounted = {g_bytes + 664, 13}},
+     .data.refcounted = {g_bytes + 666, 16}},
     {.refcount = &grpc_static_metadata_refcounts[65],
-     .data.refcounted = {g_bytes + 677, 6}},
+     .data.refcounted = {g_bytes + 682, 13}},
     {.refcount = &grpc_static_metadata_refcounts[66],
-     .data.refcounted = {g_bytes + 683, 4}},
+     .data.refcounted = {g_bytes + 695, 6}},
     {.refcount = &grpc_static_metadata_refcounts[67],
-     .data.refcounted = {g_bytes + 687, 4}},
+     .data.refcounted = {g_bytes + 701, 4}},
     {.refcount = &grpc_static_metadata_refcounts[68],
-     .data.refcounted = {g_bytes + 691, 6}},
+     .data.refcounted = {g_bytes + 705, 4}},
     {.refcount = &grpc_static_metadata_refcounts[69],
-     .data.refcounted = {g_bytes + 697, 7}},
+     .data.refcounted = {g_bytes + 709, 6}},
     {.refcount = &grpc_static_metadata_refcounts[70],
-     .data.refcounted = {g_bytes + 704, 4}},
+     .data.refcounted = {g_bytes + 715, 7}},
     {.refcount = &grpc_static_metadata_refcounts[71],
-     .data.refcounted = {g_bytes + 708, 8}},
+     .data.refcounted = {g_bytes + 722, 4}},
     {.refcount = &grpc_static_metadata_refcounts[72],
-     .data.refcounted = {g_bytes + 716, 17}},
+     .data.refcounted = {g_bytes + 726, 8}},
     {.refcount = &grpc_static_metadata_refcounts[73],
-     .data.refcounted = {g_bytes + 733, 13}},
+     .data.refcounted = {g_bytes + 734, 17}},
     {.refcount = &grpc_static_metadata_refcounts[74],
-     .data.refcounted = {g_bytes + 746, 8}},
+     .data.refcounted = {g_bytes + 751, 13}},
     {.refcount = &grpc_static_metadata_refcounts[75],
-     .data.refcounted = {g_bytes + 754, 19}},
+     .data.refcounted = {g_bytes + 764, 8}},
     {.refcount = &grpc_static_metadata_refcounts[76],
-     .data.refcounted = {g_bytes + 773, 13}},
+     .data.refcounted = {g_bytes + 772, 19}},
     {.refcount = &grpc_static_metadata_refcounts[77],
-     .data.refcounted = {g_bytes + 786, 4}},
+     .data.refcounted = {g_bytes + 791, 13}},
     {.refcount = &grpc_static_metadata_refcounts[78],
-     .data.refcounted = {g_bytes + 790, 8}},
+     .data.refcounted = {g_bytes + 804, 11}},
     {.refcount = &grpc_static_metadata_refcounts[79],
-     .data.refcounted = {g_bytes + 798, 12}},
+     .data.refcounted = {g_bytes + 815, 4}},
     {.refcount = &grpc_static_metadata_refcounts[80],
-     .data.refcounted = {g_bytes + 810, 18}},
+     .data.refcounted = {g_bytes + 819, 8}},
     {.refcount = &grpc_static_metadata_refcounts[81],
-     .data.refcounted = {g_bytes + 828, 19}},
+     .data.refcounted = {g_bytes + 827, 12}},
     {.refcount = &grpc_static_metadata_refcounts[82],
-     .data.refcounted = {g_bytes + 847, 5}},
+     .data.refcounted = {g_bytes + 839, 18}},
     {.refcount = &grpc_static_metadata_refcounts[83],
-     .data.refcounted = {g_bytes + 852, 7}},
+     .data.refcounted = {g_bytes + 857, 19}},
     {.refcount = &grpc_static_metadata_refcounts[84],
-     .data.refcounted = {g_bytes + 859, 7}},
+     .data.refcounted = {g_bytes + 876, 5}},
     {.refcount = &grpc_static_metadata_refcounts[85],
-     .data.refcounted = {g_bytes + 866, 11}},
+     .data.refcounted = {g_bytes + 881, 7}},
     {.refcount = &grpc_static_metadata_refcounts[86],
-     .data.refcounted = {g_bytes + 877, 6}},
+     .data.refcounted = {g_bytes + 888, 7}},
     {.refcount = &grpc_static_metadata_refcounts[87],
-     .data.refcounted = {g_bytes + 883, 10}},
+     .data.refcounted = {g_bytes + 895, 11}},
     {.refcount = &grpc_static_metadata_refcounts[88],
-     .data.refcounted = {g_bytes + 893, 25}},
+     .data.refcounted = {g_bytes + 906, 6}},
     {.refcount = &grpc_static_metadata_refcounts[89],
-     .data.refcounted = {g_bytes + 918, 17}},
+     .data.refcounted = {g_bytes + 912, 10}},
     {.refcount = &grpc_static_metadata_refcounts[90],
-     .data.refcounted = {g_bytes + 935, 4}},
+     .data.refcounted = {g_bytes + 922, 25}},
     {.refcount = &grpc_static_metadata_refcounts[91],
-     .data.refcounted = {g_bytes + 939, 3}},
+     .data.refcounted = {g_bytes + 947, 17}},
     {.refcount = &grpc_static_metadata_refcounts[92],
-     .data.refcounted = {g_bytes + 942, 16}},
+     .data.refcounted = {g_bytes + 964, 4}},
     {.refcount = &grpc_static_metadata_refcounts[93],
-     .data.refcounted = {g_bytes + 958, 16}},
+     .data.refcounted = {g_bytes + 968, 3}},
     {.refcount = &grpc_static_metadata_refcounts[94],
-     .data.refcounted = {g_bytes + 974, 13}},
+     .data.refcounted = {g_bytes + 971, 16}},
     {.refcount = &grpc_static_metadata_refcounts[95],
-     .data.refcounted = {g_bytes + 987, 12}},
+     .data.refcounted = {g_bytes + 987, 16}},
     {.refcount = &grpc_static_metadata_refcounts[96],
-     .data.refcounted = {g_bytes + 999, 21}},
+     .data.refcounted = {g_bytes + 1003, 13}},
+    {.refcount = &grpc_static_metadata_refcounts[97],
+     .data.refcounted = {g_bytes + 1016, 12}},
+    {.refcount = &grpc_static_metadata_refcounts[98],
+     .data.refcounted = {g_bytes + 1028, 21}},
 };
 
 uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8};
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8};
 
 static const int8_t elems_r[] = {
-    10,  8,   -3, 0,   9,   21,  -75, 22,  0,   10,  -7,  20, 0,  19, 18, 17,
-    0,   0,   0,  0,   0,   0,   0,   0,   0,   0,   0,   0,  0,  0,  0,  0,
-    0,   0,   0,  0,   0,   0,   0,   0,   0,   0,   0,   0,  0,  0,  0,  0,
-    -48, -49, 16, -51, -52, -53, -54, -54, -55, -56, -57, 0,  37, 36, 35, 34,
-    33,  32,  31, 30,  29,  28,  27,  26,  25,  24,  23,  22, 21, 20, 19, 18,
-    17,  16,  15, 14,  13,  12,  11,  14,  13,  12,  11,  10, 9,  8,  0};
+    10,  8,   -3,  0,   9,  21, -77, 22,  0,   10, -7,  0,   0,   0,
+    14,  0,   13,  12,  11, 0,  0,   0,   0,   0,  0,   0,   0,   0,
+    0,   0,   0,   0,   0,  0,  0,   0,   0,   0,  0,   0,   0,   0,
+    0,   0,   0,   0,   0,  0,  0,   -50, -51, 16, -53, -54, -55, -56,
+    -56, -57, -58, -59, 0,  37, 36,  35,  34,  33, 32,  31,  30,  29,
+    28,  27,  26,  25,  24, 23, 22,  21,  20,  19, 18,  17,  16,  15,
+    14,  13,  12,  11,  10, 13, 12,  11,  10,  9,  8,   7,   0};
 static uint32_t elems_phash(uint32_t i) {
-  i -= 41;
-  uint32_t x = i % 95;
-  uint32_t y = i / 95;
+  i -= 42;
+  uint32_t x = i % 97;
+  uint32_t y = i / 97;
   uint32_t h = x;
   if (y < GPR_ARRAY_SIZE(elems_r)) {
     uint32_t delta = (uint32_t)elems_r[y];
@@ -445,29 +454,30 @@ static uint32_t elems_phash(uint32_t i) {
 }
 
 static const uint16_t elem_keys[] = {
-    998,  999,  1000, 237,  238,  239,  240,  241,  136,  137,  41,   42,
-    424,  425,  426,  901,  902,  903,  704,  705,  1086, 516,  706,  1280,
-    1377, 1474, 4675, 4772, 4803, 4966, 5063, 5160, 5257, 1099, 5354, 5451,
-    5548, 5645, 5742, 5839, 5936, 6033, 6130, 6227, 6324, 6421, 6518, 6615,
-    6712, 6809, 6906, 7003, 7100, 7197, 7294, 7391, 7488, 7585, 7682, 7779,
-    7876, 7973, 8070, 8167, 8264, 1063, 1064, 1065, 1066, 8361, 8458, 8555,
-    8652, 8749, 8846, 8943, 310,  0,    0,    0,    0,    0,    0,    0,
+    1019, 1020, 1021, 242,  243,  244,  245,  246,  139,  140,  42,   43,
+    433,  434,  435,  920,  921,  922,  719,  720,  1406, 527,  721,  1604,
+    1703, 1802, 4871, 4970, 5001, 5168, 5267, 5366, 5465, 1419, 5564, 5663,
+    5762, 5861, 5960, 6059, 6158, 6257, 6356, 6455, 6554, 6653, 6752, 6851,
+    6950, 7049, 7148, 7247, 7346, 7445, 7544, 7643, 7742, 7841, 7940, 8039,
+    8138, 8237, 8336, 8435, 8534, 8633, 1085, 1086, 1087, 1088, 8732, 8831,
+    8930, 9029, 9128, 9227, 9326, 0,    317,  0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    130,  228,  229,  0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    133,  233,  234,  0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0};
 static const uint8_t elem_idxs[] = {
-    73,  76,  74,  19,  20,  21,  22,  23,  15,  16,  17,  18,  11,  12,  13,
-    3,   4,   5,   0,   1,   41,  6,   2,   69,  48,  55,  24,  25,  26,  27,
+    74,  77,  75,  19,  20,  21,  22,  23,  15,  16,  17,  18,  11,  12,  13,
+    3,   4,   5,   0,   1,   41,  6,   2,   70,  48,  55,  24,  25,  26,  27,
     28,  29,  30,  7,   31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  42,
     43,  44,  45,  46,  47,  49,  50,  51,  52,  53,  54,  56,  57,  58,  59,
-    60,  61,  62,  63,  64,  75,  77,  78,  79,  65,  66,  67,  68,  70,  71,
-    72,  14,  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-    255, 255, 255, 255, 255, 255, 255, 255, 255, 8,   9,   10};
+    60,  61,  62,  63,  64,  65,  76,  78,  79,  80,  66,  67,  68,  69,  71,
+    72,  73,  255, 14,  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 8,   9,   10};
 
 grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {
   if (a == -1 || b == -1) return GRPC_MDNULL;
-  uint32_t k = (uint32_t)(a * 97 + b);
+  uint32_t k = (uint32_t)(a * 99 + b);
   uint32_t h = elems_phash(k);
   return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k
              ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]],
@@ -476,326 +486,330 @@ grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {
 }
 
 grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {
-    {{.refcount = &grpc_static_metadata_refcounts[7],
-      .data.refcounted = {g_bytes + 50, 11}},
-     {.refcount = &grpc_static_metadata_refcounts[25],
-      .data.refcounted = {g_bytes + 344, 1}}},
     {{.refcount = &grpc_static_metadata_refcounts[7],
       .data.refcounted = {g_bytes + 50, 11}},
      {.refcount = &grpc_static_metadata_refcounts[26],
-      .data.refcounted = {g_bytes + 345, 1}}},
+      .data.refcounted = {g_bytes + 362, 1}}},
     {{.refcount = &grpc_static_metadata_refcounts[7],
       .data.refcounted = {g_bytes + 50, 11}},
      {.refcount = &grpc_static_metadata_refcounts[27],
-      .data.refcounted = {g_bytes + 346, 1}}},
-    {{.refcount = &grpc_static_metadata_refcounts[9],
-      .data.refcounted = {g_bytes + 77, 13}},
+      .data.refcounted = {g_bytes + 363, 1}}},
+    {{.refcount = &grpc_static_metadata_refcounts[7],
+      .data.refcounted = {g_bytes + 50, 11}},
      {.refcount = &grpc_static_metadata_refcounts[28],
-      .data.refcounted = {g_bytes + 347, 8}}},
+      .data.refcounted = {g_bytes + 364, 1}}},
     {{.refcount = &grpc_static_metadata_refcounts[9],
       .data.refcounted = {g_bytes + 77, 13}},
      {.refcount = &grpc_static_metadata_refcounts[29],
-      .data.refcounted = {g_bytes + 355, 4}}},
+      .data.refcounted = {g_bytes + 365, 8}}},
     {{.refcount = &grpc_static_metadata_refcounts[9],
       .data.refcounted = {g_bytes + 77, 13}},
      {.refcount = &grpc_static_metadata_refcounts[30],
-      .data.refcounted = {g_bytes + 359, 7}}},
+      .data.refcounted = {g_bytes + 373, 4}}},
+    {{.refcount = &grpc_static_metadata_refcounts[9],
+      .data.refcounted = {g_bytes + 77, 13}},
+     {.refcount = &grpc_static_metadata_refcounts[31],
+      .data.refcounted = {g_bytes + 377, 7}}},
     {{.refcount = &grpc_static_metadata_refcounts[5],
       .data.refcounted = {g_bytes + 36, 2}},
-     {.refcount = &grpc_static_metadata_refcounts[31],
-      .data.refcounted = {g_bytes + 366, 8}}},
-    {{.refcount = &grpc_static_metadata_refcounts[11],
-      .data.refcounted = {g_bytes + 110, 12}},
      {.refcount = &grpc_static_metadata_refcounts[32],
-      .data.refcounted = {g_bytes + 374, 16}}},
+      .data.refcounted = {g_bytes + 384, 8}}},
+    {{.refcount = &grpc_static_metadata_refcounts[14],
+      .data.refcounted = {g_bytes + 158, 12}},
+     {.refcount = &grpc_static_metadata_refcounts[33],
+      .data.refcounted = {g_bytes + 392, 16}}},
     {{.refcount = &grpc_static_metadata_refcounts[1],
       .data.refcounted = {g_bytes + 5, 7}},
-     {.refcount = &grpc_static_metadata_refcounts[33],
-      .data.refcounted = {g_bytes + 390, 4}}},
-    {{.refcount = &grpc_static_metadata_refcounts[2],
-      .data.refcounted = {g_bytes + 12, 7}},
      {.refcount = &grpc_static_metadata_refcounts[34],
-      .data.refcounted = {g_bytes + 394, 3}}},
+      .data.refcounted = {g_bytes + 408, 4}}},
     {{.refcount = &grpc_static_metadata_refcounts[2],
       .data.refcounted = {g_bytes + 12, 7}},
      {.refcount = &grpc_static_metadata_refcounts[35],
-      .data.refcounted = {g_bytes + 397, 3}}},
-    {{.refcount = &grpc_static_metadata_refcounts[4],
-      .data.refcounted = {g_bytes + 29, 7}},
+      .data.refcounted = {g_bytes + 412, 3}}},
+    {{.refcount = &grpc_static_metadata_refcounts[2],
+      .data.refcounted = {g_bytes + 12, 7}},
      {.refcount = &grpc_static_metadata_refcounts[36],
-      .data.refcounted = {g_bytes + 400, 4}}},
+      .data.refcounted = {g_bytes + 415, 3}}},
     {{.refcount = &grpc_static_metadata_refcounts[4],
       .data.refcounted = {g_bytes + 29, 7}},
      {.refcount = &grpc_static_metadata_refcounts[37],
-      .data.refcounted = {g_bytes + 404, 5}}},
+      .data.refcounted = {g_bytes + 418, 4}}},
     {{.refcount = &grpc_static_metadata_refcounts[4],
       .data.refcounted = {g_bytes + 29, 7}},
      {.refcount = &grpc_static_metadata_refcounts[38],
-      .data.refcounted = {g_bytes + 409, 4}}},
+      .data.refcounted = {g_bytes + 422, 5}}},
+    {{.refcount = &grpc_static_metadata_refcounts[4],
+      .data.refcounted = {g_bytes + 29, 7}},
+     {.refcount = &grpc_static_metadata_refcounts[39],
+      .data.refcounted = {g_bytes + 427, 4}}},
     {{.refcount = &grpc_static_metadata_refcounts[3],
       .data.refcounted = {g_bytes + 19, 10}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[1],
       .data.refcounted = {g_bytes + 5, 7}},
-     {.refcount = &grpc_static_metadata_refcounts[39],
-      .data.refcounted = {g_bytes + 413, 3}}},
+     {.refcount = &grpc_static_metadata_refcounts[40],
+      .data.refcounted = {g_bytes + 431, 3}}},
     {{.refcount = &grpc_static_metadata_refcounts[1],
       .data.refcounted = {g_bytes + 5, 7}},
-     {.refcount = &grpc_static_metadata_refcounts[40],
-      .data.refcounted = {g_bytes + 416, 3}}},
-    {{.refcount = &grpc_static_metadata_refcounts[0],
-      .data.refcounted = {g_bytes + 0, 5}},
      {.refcount = &grpc_static_metadata_refcounts[41],
-      .data.refcounted = {g_bytes + 419, 1}}},
+      .data.refcounted = {g_bytes + 434, 3}}},
     {{.refcount = &grpc_static_metadata_refcounts[0],
       .data.refcounted = {g_bytes + 0, 5}},
      {.refcount = &grpc_static_metadata_refcounts[42],
-      .data.refcounted = {g_bytes + 420, 11}}},
-    {{.refcount = &grpc_static_metadata_refcounts[2],
-      .data.refcounted = {g_bytes + 12, 7}},
+      .data.refcounted = {g_bytes + 437, 1}}},
+    {{.refcount = &grpc_static_metadata_refcounts[0],
+      .data.refcounted = {g_bytes + 0, 5}},
      {.refcount = &grpc_static_metadata_refcounts[43],
-      .data.refcounted = {g_bytes + 431, 3}}},
+      .data.refcounted = {g_bytes + 438, 11}}},
     {{.refcount = &grpc_static_metadata_refcounts[2],
       .data.refcounted = {g_bytes + 12, 7}},
      {.refcount = &grpc_static_metadata_refcounts[44],
-      .data.refcounted = {g_bytes + 434, 3}}},
+      .data.refcounted = {g_bytes + 449, 3}}},
     {{.refcount = &grpc_static_metadata_refcounts[2],
       .data.refcounted = {g_bytes + 12, 7}},
      {.refcount = &grpc_static_metadata_refcounts[45],
-      .data.refcounted = {g_bytes + 437, 3}}},
+      .data.refcounted = {g_bytes + 452, 3}}},
     {{.refcount = &grpc_static_metadata_refcounts[2],
       .data.refcounted = {g_bytes + 12, 7}},
      {.refcount = &grpc_static_metadata_refcounts[46],
-      .data.refcounted = {g_bytes + 440, 3}}},
+      .data.refcounted = {g_bytes + 455, 3}}},
     {{.refcount = &grpc_static_metadata_refcounts[2],
       .data.refcounted = {g_bytes + 12, 7}},
      {.refcount = &grpc_static_metadata_refcounts[47],
-      .data.refcounted = {g_bytes + 443, 3}}},
-    {{.refcount = &grpc_static_metadata_refcounts[48],
-      .data.refcounted = {g_bytes + 446, 14}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
-    {{.refcount = &grpc_static_metadata_refcounts[49],
-      .data.refcounted = {g_bytes + 460, 15}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 458, 3}}},
+    {{.refcount = &grpc_static_metadata_refcounts[2],
+      .data.refcounted = {g_bytes + 12, 7}},
+     {.refcount = &grpc_static_metadata_refcounts[48],
+      .data.refcounted = {g_bytes + 461, 3}}},
     {{.refcount = &grpc_static_metadata_refcounts[49],
-      .data.refcounted = {g_bytes + 460, 15}},
-     {.refcount = &grpc_static_metadata_refcounts[50],
-      .data.refcounted = {g_bytes + 475, 13}}},
-    {{.refcount = &grpc_static_metadata_refcounts[51],
-      .data.refcounted = {g_bytes + 488, 15}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 464, 14}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
+    {{.refcount = &grpc_static_metadata_refcounts[50],
+      .data.refcounted = {g_bytes + 478, 15}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
+    {{.refcount = &grpc_static_metadata_refcounts[50],
+      .data.refcounted = {g_bytes + 478, 15}},
+     {.refcount = &grpc_static_metadata_refcounts[51],
+      .data.refcounted = {g_bytes + 493, 13}}},
     {{.refcount = &grpc_static_metadata_refcounts[52],
-      .data.refcounted = {g_bytes + 503, 13}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 506, 15}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[53],
-      .data.refcounted = {g_bytes + 516, 6}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 521, 13}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[54],
-      .data.refcounted = {g_bytes + 522, 27}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 534, 6}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[55],
-      .data.refcounted = {g_bytes + 549, 3}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 540, 27}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[56],
-      .data.refcounted = {g_bytes + 552, 5}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 567, 3}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[57],
-      .data.refcounted = {g_bytes + 557, 13}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 570, 5}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[58],
-      .data.refcounted = {g_bytes + 570, 13}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 575, 13}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[59],
-      .data.refcounted = {g_bytes + 583, 19}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 588, 13}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[60],
-      .data.refcounted = {g_bytes + 602, 16}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 601, 19}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[61],
-      .data.refcounted = {g_bytes + 618, 16}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 620, 16}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[62],
-      .data.refcounted = {g_bytes + 634, 14}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 636, 16}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[63],
-      .data.refcounted = {g_bytes + 648, 16}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 652, 14}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[64],
-      .data.refcounted = {g_bytes + 664, 13}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
-    {{.refcount = &grpc_static_metadata_refcounts[11],
-      .data.refcounted = {g_bytes + 110, 12}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 666, 16}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[65],
-      .data.refcounted = {g_bytes + 677, 6}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 682, 13}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
+    {{.refcount = &grpc_static_metadata_refcounts[14],
+      .data.refcounted = {g_bytes + 158, 12}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[66],
-      .data.refcounted = {g_bytes + 683, 4}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 695, 6}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[67],
-      .data.refcounted = {g_bytes + 687, 4}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 701, 4}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[68],
-      .data.refcounted = {g_bytes + 691, 6}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 705, 4}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[69],
-      .data.refcounted = {g_bytes + 697, 7}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 709, 6}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[70],
-      .data.refcounted = {g_bytes + 704, 4}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
-    {{.refcount = &grpc_static_metadata_refcounts[14],
-      .data.refcounted = {g_bytes + 162, 4}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 715, 7}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[71],
-      .data.refcounted = {g_bytes + 708, 8}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 722, 4}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
+    {{.refcount = &grpc_static_metadata_refcounts[17],
+      .data.refcounted = {g_bytes + 210, 4}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[72],
-      .data.refcounted = {g_bytes + 716, 17}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 726, 8}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[73],
-      .data.refcounted = {g_bytes + 733, 13}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 734, 17}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[74],
-      .data.refcounted = {g_bytes + 746, 8}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 751, 13}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[75],
-      .data.refcounted = {g_bytes + 754, 19}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 764, 8}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[76],
-      .data.refcounted = {g_bytes + 773, 13}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
-    {{.refcount = &grpc_static_metadata_refcounts[15],
-      .data.refcounted = {g_bytes + 166, 8}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 772, 19}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[77],
-      .data.refcounted = {g_bytes + 786, 4}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 791, 13}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
+    {{.refcount = &grpc_static_metadata_refcounts[18],
+      .data.refcounted = {g_bytes + 214, 8}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[78],
-      .data.refcounted = {g_bytes + 790, 8}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 804, 11}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[79],
-      .data.refcounted = {g_bytes + 798, 12}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 815, 4}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[80],
-      .data.refcounted = {g_bytes + 810, 18}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 819, 8}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[81],
-      .data.refcounted = {g_bytes + 828, 19}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 827, 12}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[82],
-      .data.refcounted = {g_bytes + 847, 5}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 839, 18}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[83],
-      .data.refcounted = {g_bytes + 852, 7}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 857, 19}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[84],
-      .data.refcounted = {g_bytes + 859, 7}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 876, 5}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[85],
-      .data.refcounted = {g_bytes + 866, 11}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 881, 7}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[86],
-      .data.refcounted = {g_bytes + 877, 6}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 888, 7}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[87],
-      .data.refcounted = {g_bytes + 883, 10}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 895, 11}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[88],
-      .data.refcounted = {g_bytes + 893, 25}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 906, 6}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[89],
-      .data.refcounted = {g_bytes + 918, 17}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
-    {{.refcount = &grpc_static_metadata_refcounts[13],
-      .data.refcounted = {g_bytes + 152, 10}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 912, 10}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[90],
-      .data.refcounted = {g_bytes + 935, 4}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 922, 25}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[91],
-      .data.refcounted = {g_bytes + 939, 3}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 947, 17}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
+    {{.refcount = &grpc_static_metadata_refcounts[16],
+      .data.refcounted = {g_bytes + 200, 10}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[92],
-      .data.refcounted = {g_bytes + 942, 16}},
-     {.refcount = &grpc_static_metadata_refcounts[19],
-      .data.refcounted = {g_bytes + 216, 0}}},
+      .data.refcounted = {g_bytes + 964, 4}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
+    {{.refcount = &grpc_static_metadata_refcounts[93],
+      .data.refcounted = {g_bytes + 968, 3}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
+    {{.refcount = &grpc_static_metadata_refcounts[94],
+      .data.refcounted = {g_bytes + 971, 16}},
+     {.refcount = &grpc_static_metadata_refcounts[20],
+      .data.refcounted = {g_bytes + 234, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[10],
       .data.refcounted = {g_bytes + 90, 20}},
-     {.refcount = &grpc_static_metadata_refcounts[28],
-      .data.refcounted = {g_bytes + 347, 8}}},
+     {.refcount = &grpc_static_metadata_refcounts[29],
+      .data.refcounted = {g_bytes + 365, 8}}},
     {{.refcount = &grpc_static_metadata_refcounts[10],
       .data.refcounted = {g_bytes + 90, 20}},
-     {.refcount = &grpc_static_metadata_refcounts[30],
-      .data.refcounted = {g_bytes + 359, 7}}},
+     {.refcount = &grpc_static_metadata_refcounts[31],
+      .data.refcounted = {g_bytes + 377, 7}}},
     {{.refcount = &grpc_static_metadata_refcounts[10],
       .data.refcounted = {g_bytes + 90, 20}},
-     {.refcount = &grpc_static_metadata_refcounts[93],
-      .data.refcounted = {g_bytes + 958, 16}}},
+     {.refcount = &grpc_static_metadata_refcounts[95],
+      .data.refcounted = {g_bytes + 987, 16}}},
     {{.refcount = &grpc_static_metadata_refcounts[10],
       .data.refcounted = {g_bytes + 90, 20}},
-     {.refcount = &grpc_static_metadata_refcounts[29],
-      .data.refcounted = {g_bytes + 355, 4}}},
+     {.refcount = &grpc_static_metadata_refcounts[30],
+      .data.refcounted = {g_bytes + 373, 4}}},
     {{.refcount = &grpc_static_metadata_refcounts[10],
       .data.refcounted = {g_bytes + 90, 20}},
-     {.refcount = &grpc_static_metadata_refcounts[94],
-      .data.refcounted = {g_bytes + 974, 13}}},
+     {.refcount = &grpc_static_metadata_refcounts[96],
+      .data.refcounted = {g_bytes + 1003, 13}}},
     {{.refcount = &grpc_static_metadata_refcounts[10],
       .data.refcounted = {g_bytes + 90, 20}},
-     {.refcount = &grpc_static_metadata_refcounts[95],
-      .data.refcounted = {g_bytes + 987, 12}}},
+     {.refcount = &grpc_static_metadata_refcounts[97],
+      .data.refcounted = {g_bytes + 1016, 12}}},
     {{.refcount = &grpc_static_metadata_refcounts[10],
       .data.refcounted = {g_bytes + 90, 20}},
-     {.refcount = &grpc_static_metadata_refcounts[96],
-      .data.refcounted = {g_bytes + 999, 21}}},
+     {.refcount = &grpc_static_metadata_refcounts[98],
+      .data.refcounted = {g_bytes + 1028, 21}}},
 };
-const uint8_t grpc_static_accept_encoding_metadata[8] = {0,  73, 74, 75,
-                                                         76, 77, 78, 79};
+const uint8_t grpc_static_accept_encoding_metadata[8] = {0,  74, 75, 76,
+                                                         77, 78, 79, 80};
diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h
index f9600ee2e4e0c06d4807ceb9d7f18df7478ee89c..84fb316fd66a23037f97dc1d9b29cb37d86b51f0 100644
--- a/src/core/lib/transport/static_metadata.h
+++ b/src/core/lib/transport/static_metadata.h
@@ -44,7 +44,7 @@
 
 #include "src/core/lib/transport/metadata.h"
 
-#define GRPC_STATIC_MDSTR_COUNT 97
+#define GRPC_STATIC_MDSTR_COUNT 99
 extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];
 /* ":path" */
 #define GRPC_MDSTR_PATH (grpc_static_slice_table[0])
@@ -68,182 +68,186 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];
 #define GRPC_MDSTR_GRPC_ENCODING (grpc_static_slice_table[9])
 /* "grpc-accept-encoding" */
 #define GRPC_MDSTR_GRPC_ACCEPT_ENCODING (grpc_static_slice_table[10])
+/* "grpc-server-stats-bin" */
+#define GRPC_MDSTR_GRPC_SERVER_STATS_BIN (grpc_static_slice_table[11])
+/* "grpc-tags-bin" */
+#define GRPC_MDSTR_GRPC_TAGS_BIN (grpc_static_slice_table[12])
+/* "grpc-trace-bin" */
+#define GRPC_MDSTR_GRPC_TRACE_BIN (grpc_static_slice_table[13])
 /* "content-type" */
-#define GRPC_MDSTR_CONTENT_TYPE (grpc_static_slice_table[11])
+#define GRPC_MDSTR_CONTENT_TYPE (grpc_static_slice_table[14])
 /* "grpc-internal-encoding-request" */
-#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (grpc_static_slice_table[12])
+#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (grpc_static_slice_table[15])
 /* "user-agent" */
-#define GRPC_MDSTR_USER_AGENT (grpc_static_slice_table[13])
+#define GRPC_MDSTR_USER_AGENT (grpc_static_slice_table[16])
 /* "host" */
-#define GRPC_MDSTR_HOST (grpc_static_slice_table[14])
+#define GRPC_MDSTR_HOST (grpc_static_slice_table[17])
 /* "lb-token" */
-#define GRPC_MDSTR_LB_TOKEN (grpc_static_slice_table[15])
+#define GRPC_MDSTR_LB_TOKEN (grpc_static_slice_table[18])
 /* "grpc-timeout" */
-#define GRPC_MDSTR_GRPC_TIMEOUT (grpc_static_slice_table[16])
-/* "grpc-tracing-bin" */
-#define GRPC_MDSTR_GRPC_TRACING_BIN (grpc_static_slice_table[17])
-/* "grpc-stats-bin" */
-#define GRPC_MDSTR_GRPC_STATS_BIN (grpc_static_slice_table[18])
+#define GRPC_MDSTR_GRPC_TIMEOUT (grpc_static_slice_table[19])
 /* "" */
-#define GRPC_MDSTR_EMPTY (grpc_static_slice_table[19])
+#define GRPC_MDSTR_EMPTY (grpc_static_slice_table[20])
 /* "grpc.wait_for_ready" */
-#define GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY (grpc_static_slice_table[20])
+#define GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY (grpc_static_slice_table[21])
 /* "grpc.timeout" */
-#define GRPC_MDSTR_GRPC_DOT_TIMEOUT (grpc_static_slice_table[21])
+#define GRPC_MDSTR_GRPC_DOT_TIMEOUT (grpc_static_slice_table[22])
 /* "grpc.max_request_message_bytes" */
 #define GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES \
-  (grpc_static_slice_table[22])
+  (grpc_static_slice_table[23])
 /* "grpc.max_response_message_bytes" */
 #define GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES \
-  (grpc_static_slice_table[23])
+  (grpc_static_slice_table[24])
 /* "/grpc.lb.v1.LoadBalancer/BalanceLoad" */
 #define GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD \
-  (grpc_static_slice_table[24])
+  (grpc_static_slice_table[25])
 /* "0" */
-#define GRPC_MDSTR_0 (grpc_static_slice_table[25])
+#define GRPC_MDSTR_0 (grpc_static_slice_table[26])
 /* "1" */
-#define GRPC_MDSTR_1 (grpc_static_slice_table[26])
+#define GRPC_MDSTR_1 (grpc_static_slice_table[27])
 /* "2" */
-#define GRPC_MDSTR_2 (grpc_static_slice_table[27])
+#define GRPC_MDSTR_2 (grpc_static_slice_table[28])
 /* "identity" */
-#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[28])
+#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[29])
 /* "gzip" */
-#define GRPC_MDSTR_GZIP (grpc_static_slice_table[29])
+#define GRPC_MDSTR_GZIP (grpc_static_slice_table[30])
 /* "deflate" */
-#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[30])
+#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[31])
 /* "trailers" */
-#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[31])
+#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[32])
 /* "application/grpc" */
-#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[32])
+#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[33])
 /* "POST" */
-#define GRPC_MDSTR_POST (grpc_static_slice_table[33])
+#define GRPC_MDSTR_POST (grpc_static_slice_table[34])
 /* "200" */
-#define GRPC_MDSTR_200 (grpc_static_slice_table[34])
+#define GRPC_MDSTR_200 (grpc_static_slice_table[35])
 /* "404" */
-#define GRPC_MDSTR_404 (grpc_static_slice_table[35])
+#define GRPC_MDSTR_404 (grpc_static_slice_table[36])
 /* "http" */
-#define GRPC_MDSTR_HTTP (grpc_static_slice_table[36])
+#define GRPC_MDSTR_HTTP (grpc_static_slice_table[37])
 /* "https" */
-#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[37])
+#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[38])
 /* "grpc" */
-#define GRPC_MDSTR_GRPC (grpc_static_slice_table[38])
+#define GRPC_MDSTR_GRPC (grpc_static_slice_table[39])
 /* "GET" */
-#define GRPC_MDSTR_GET (grpc_static_slice_table[39])
+#define GRPC_MDSTR_GET (grpc_static_slice_table[40])
 /* "PUT" */
-#define GRPC_MDSTR_PUT (grpc_static_slice_table[40])
+#define GRPC_MDSTR_PUT (grpc_static_slice_table[41])
 /* "/" */
-#define GRPC_MDSTR_SLASH (grpc_static_slice_table[41])
+#define GRPC_MDSTR_SLASH (grpc_static_slice_table[42])
 /* "/index.html" */
-#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[42])
+#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[43])
 /* "204" */
-#define GRPC_MDSTR_204 (grpc_static_slice_table[43])
+#define GRPC_MDSTR_204 (grpc_static_slice_table[44])
 /* "206" */
-#define GRPC_MDSTR_206 (grpc_static_slice_table[44])
+#define GRPC_MDSTR_206 (grpc_static_slice_table[45])
 /* "304" */
-#define GRPC_MDSTR_304 (grpc_static_slice_table[45])
+#define GRPC_MDSTR_304 (grpc_static_slice_table[46])
 /* "400" */
-#define GRPC_MDSTR_400 (grpc_static_slice_table[46])
+#define GRPC_MDSTR_400 (grpc_static_slice_table[47])
 /* "500" */
-#define GRPC_MDSTR_500 (grpc_static_slice_table[47])
+#define GRPC_MDSTR_500 (grpc_static_slice_table[48])
 /* "accept-charset" */
-#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[48])
+#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[49])
 /* "accept-encoding" */
-#define GRPC_MDSTR_ACCEPT_ENCODING (grpc_static_slice_table[49])
+#define GRPC_MDSTR_ACCEPT_ENCODING (grpc_static_slice_table[50])
 /* "gzip, deflate" */
-#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[50])
+#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[51])
 /* "accept-language" */
-#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[51])
+#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[52])
 /* "accept-ranges" */
-#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[52])
+#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[53])
 /* "accept" */
-#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[53])
+#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[54])
 /* "access-control-allow-origin" */
-#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[54])
+#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[55])
 /* "age" */
-#define GRPC_MDSTR_AGE (grpc_static_slice_table[55])
+#define GRPC_MDSTR_AGE (grpc_static_slice_table[56])
 /* "allow" */
-#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[56])
+#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[57])
 /* "authorization" */
-#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[57])
+#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[58])
 /* "cache-control" */
-#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[58])
+#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[59])
 /* "content-disposition" */
-#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[59])
+#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[60])
 /* "content-encoding" */
-#define GRPC_MDSTR_CONTENT_ENCODING (grpc_static_slice_table[60])
+#define GRPC_MDSTR_CONTENT_ENCODING (grpc_static_slice_table[61])
 /* "content-language" */
-#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[61])
+#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[62])
 /* "content-length" */
-#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[62])
+#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[63])
 /* "content-location" */
-#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[63])
+#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[64])
 /* "content-range" */
-#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[64])
+#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[65])
 /* "cookie" */
-#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[65])
+#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[66])
 /* "date" */
-#define GRPC_MDSTR_DATE (grpc_static_slice_table[66])
+#define GRPC_MDSTR_DATE (grpc_static_slice_table[67])
 /* "etag" */
-#define GRPC_MDSTR_ETAG (grpc_static_slice_table[67])
+#define GRPC_MDSTR_ETAG (grpc_static_slice_table[68])
 /* "expect" */
-#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[68])
+#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[69])
 /* "expires" */
-#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[69])
+#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[70])
 /* "from" */
-#define GRPC_MDSTR_FROM (grpc_static_slice_table[70])
+#define GRPC_MDSTR_FROM (grpc_static_slice_table[71])
 /* "if-match" */
-#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[71])
+#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[72])
 /* "if-modified-since" */
-#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[72])
+#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[73])
 /* "if-none-match" */
-#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[73])
+#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[74])
 /* "if-range" */
-#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[74])
+#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[75])
 /* "if-unmodified-since" */
-#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[75])
+#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[76])
 /* "last-modified" */
-#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[76])
+#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[77])
+/* "lb-cost-bin" */
+#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[78])
 /* "link" */
-#define GRPC_MDSTR_LINK (grpc_static_slice_table[77])
+#define GRPC_MDSTR_LINK (grpc_static_slice_table[79])
 /* "location" */
-#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[78])
+#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[80])
 /* "max-forwards" */
-#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[79])
+#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[81])
 /* "proxy-authenticate" */
-#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[80])
+#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[82])
 /* "proxy-authorization" */
-#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[81])
+#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[83])
 /* "range" */
-#define GRPC_MDSTR_RANGE (grpc_static_slice_table[82])
+#define GRPC_MDSTR_RANGE (grpc_static_slice_table[84])
 /* "referer" */
-#define GRPC_MDSTR_REFERER (grpc_static_slice_table[83])
+#define GRPC_MDSTR_REFERER (grpc_static_slice_table[85])
 /* "refresh" */
-#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[84])
+#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[86])
 /* "retry-after" */
-#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[85])
+#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[87])
 /* "server" */
-#define GRPC_MDSTR_SERVER (grpc_static_slice_table[86])
+#define GRPC_MDSTR_SERVER (grpc_static_slice_table[88])
 /* "set-cookie" */
-#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[87])
+#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[89])
 /* "strict-transport-security" */
-#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[88])
+#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[90])
 /* "transfer-encoding" */
-#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[89])
+#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[91])
 /* "vary" */
-#define GRPC_MDSTR_VARY (grpc_static_slice_table[90])
+#define GRPC_MDSTR_VARY (grpc_static_slice_table[92])
 /* "via" */
-#define GRPC_MDSTR_VIA (grpc_static_slice_table[91])
+#define GRPC_MDSTR_VIA (grpc_static_slice_table[93])
 /* "www-authenticate" */
-#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[92])
+#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[94])
 /* "identity,deflate" */
-#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[93])
+#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[95])
 /* "identity,gzip" */
-#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[94])
+#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[96])
 /* "deflate,gzip" */
-#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[95])
+#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[97])
 /* "identity,deflate,gzip" */
 #define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
-  (grpc_static_slice_table[96])
+  (grpc_static_slice_table[98])
 
 extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable;
 extern grpc_slice_refcount
@@ -255,7 +259,7 @@ extern grpc_slice_refcount
 #define GRPC_STATIC_METADATA_INDEX(static_slice) \
   ((int)((static_slice).refcount - grpc_static_metadata_refcounts))
 
-#define GRPC_STATIC_MDELEM_COUNT 80
+#define GRPC_STATIC_MDELEM_COUNT 81
 extern grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
 extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];
 /* "grpc-status": "0" */
@@ -426,78 +430,81 @@ extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];
 /* "lb-token": "" */
 #define GRPC_MDELEM_LB_TOKEN_EMPTY \
   (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC))
+/* "lb-cost-bin": "" */
+#define GRPC_MDELEM_LB_COST_BIN_EMPTY \
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC))
 /* "link": "" */
 #define GRPC_MDELEM_LINK_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC))
 /* "location": "" */
 #define GRPC_MDELEM_LOCATION_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC))
 /* "max-forwards": "" */
 #define GRPC_MDELEM_MAX_FORWARDS_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC))
 /* "proxy-authenticate": "" */
 #define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC))
 /* "proxy-authorization": "" */
 #define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC))
 /* "range": "" */
 #define GRPC_MDELEM_RANGE_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC))
 /* "referer": "" */
 #define GRPC_MDELEM_REFERER_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC))
 /* "refresh": "" */
 #define GRPC_MDELEM_REFRESH_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC))
 /* "retry-after": "" */
 #define GRPC_MDELEM_RETRY_AFTER_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC))
 /* "server": "" */
 #define GRPC_MDELEM_SERVER_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC))
 /* "set-cookie": "" */
 #define GRPC_MDELEM_SET_COOKIE_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC))
 /* "strict-transport-security": "" */
 #define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC))
 /* "transfer-encoding": "" */
 #define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC))
 /* "user-agent": "" */
 #define GRPC_MDELEM_USER_AGENT_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC))
 /* "vary": "" */
 #define GRPC_MDELEM_VARY_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC))
 /* "via": "" */
 #define GRPC_MDELEM_VIA_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC))
 /* "www-authenticate": "" */
 #define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC))
 /* "grpc-accept-encoding": "identity" */
 #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC))
 /* "grpc-accept-encoding": "deflate" */
 #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC))
 /* "grpc-accept-encoding": "identity,deflate" */
 #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], GRPC_MDELEM_STORAGE_STATIC))
 /* "grpc-accept-encoding": "gzip" */
 #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC))
 /* "grpc-accept-encoding": "identity,gzip" */
 #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], GRPC_MDELEM_STORAGE_STATIC))
 /* "grpc-accept-encoding": "deflate,gzip" */
 #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC))
 /* "grpc-accept-encoding": "identity,deflate,gzip" */
 #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80], GRPC_MDELEM_STORAGE_STATIC))
 
 grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b);
 typedef enum {
@@ -512,6 +519,9 @@ typedef enum {
   GRPC_BATCH_GRPC_PAYLOAD_BIN,
   GRPC_BATCH_GRPC_ENCODING,
   GRPC_BATCH_GRPC_ACCEPT_ENCODING,
+  GRPC_BATCH_GRPC_SERVER_STATS_BIN,
+  GRPC_BATCH_GRPC_TAGS_BIN,
+  GRPC_BATCH_GRPC_TRACE_BIN,
   GRPC_BATCH_CONTENT_TYPE,
   GRPC_BATCH_GRPC_INTERNAL_ENCODING_REQUEST,
   GRPC_BATCH_USER_AGENT,
@@ -534,6 +544,9 @@ typedef union {
     struct grpc_linked_mdelem *grpc_payload_bin;
     struct grpc_linked_mdelem *grpc_encoding;
     struct grpc_linked_mdelem *grpc_accept_encoding;
+    struct grpc_linked_mdelem *grpc_server_stats_bin;
+    struct grpc_linked_mdelem *grpc_tags_bin;
+    struct grpc_linked_mdelem *grpc_trace_bin;
     struct grpc_linked_mdelem *content_type;
     struct grpc_linked_mdelem *grpc_internal_encoding_request;
     struct grpc_linked_mdelem *user_agent;
diff --git a/src/core/lib/transport/transport.c b/src/core/lib/transport/transport.c
index 004e748f25190051be03f111f8fce7c424d8c506..82c4e004b7c155a451ada42d6d9ab92f9154dc5f 100644
--- a/src/core/lib/transport/transport.c
+++ b/src/core/lib/transport/transport.c
@@ -84,6 +84,39 @@ void grpc_stream_unref(grpc_exec_ctx *exec_ctx,
   }
 }
 
+#define STREAM_REF_FROM_SLICE_REF(p)         \
+  ((grpc_stream_refcount *)(((uint8_t *)p) - \
+                            offsetof(grpc_stream_refcount, slice_refcount)))
+
+static void slice_stream_ref(void *p) {
+#ifdef GRPC_STREAM_REFCOUNT_DEBUG
+  grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(p), "slice");
+#else
+  grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(p));
+#endif
+}
+
+static void slice_stream_unref(grpc_exec_ctx *exec_ctx, void *p) {
+#ifdef GRPC_STREAM_REFCOUNT_DEBUG
+  grpc_stream_unref(exec_ctx, STREAM_REF_FROM_SLICE_REF(p), "slice");
+#else
+  grpc_stream_unref(exec_ctx, STREAM_REF_FROM_SLICE_REF(p));
+#endif
+}
+
+grpc_slice grpc_slice_from_stream_owned_buffer(grpc_stream_refcount *refcount,
+                                               void *buffer, size_t length) {
+  slice_stream_ref(&refcount->slice_refcount);
+  return (grpc_slice){.refcount = &refcount->slice_refcount,
+                      .data.refcounted = {.bytes = buffer, .length = length}};
+}
+
+static const grpc_slice_refcount_vtable stream_ref_slice_vtable = {
+    .ref = slice_stream_ref,
+    .unref = slice_stream_unref,
+    .eq = grpc_slice_default_eq_impl,
+    .hash = grpc_slice_default_hash_impl};
+
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG
 void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs,
                           grpc_iomgr_cb_func cb, void *cb_arg,
@@ -95,6 +128,8 @@ void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs,
 #endif
   gpr_ref_init(&refcount->refs, initial_refs);
   grpc_closure_init(&refcount->destroy, cb, cb_arg, grpc_schedule_on_exec_ctx);
+  refcount->slice_refcount.vtable = &stream_ref_slice_vtable;
+  refcount->slice_refcount.sub_refcount = &refcount->slice_refcount;
 }
 
 static void move64(uint64_t *from, uint64_t *to) {
@@ -127,15 +162,15 @@ void grpc_transport_destroy(grpc_exec_ctx *exec_ctx,
 int grpc_transport_init_stream(grpc_exec_ctx *exec_ctx,
                                grpc_transport *transport, grpc_stream *stream,
                                grpc_stream_refcount *refcount,
-                               const void *server_data) {
+                               const void *server_data, gpr_arena *arena) {
   return transport->vtable->init_stream(exec_ctx, transport, stream, refcount,
-                                        server_data);
+                                        server_data, arena);
 }
 
 void grpc_transport_perform_stream_op(grpc_exec_ctx *exec_ctx,
                                       grpc_transport *transport,
                                       grpc_stream *stream,
-                                      grpc_transport_stream_op *op) {
+                                      grpc_transport_stream_op_batch *op) {
   transport->vtable->perform_stream_op(exec_ctx, transport, stream, op);
 }
 
@@ -162,9 +197,10 @@ void grpc_transport_set_pops(grpc_exec_ctx *exec_ctx, grpc_transport *transport,
 
 void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx,
                                    grpc_transport *transport,
-                                   grpc_stream *stream, void *and_free_memory) {
+                                   grpc_stream *stream,
+                                   grpc_closure *then_schedule_closure) {
   transport->vtable->destroy_stream(exec_ctx, transport, stream,
-                                    and_free_memory);
+                                    then_schedule_closure);
 }
 
 char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx,
@@ -177,14 +213,23 @@ grpc_endpoint *grpc_transport_get_endpoint(grpc_exec_ctx *exec_ctx,
   return transport->vtable->get_endpoint(exec_ctx, transport);
 }
 
-void grpc_transport_stream_op_finish_with_failure(grpc_exec_ctx *exec_ctx,
-                                                  grpc_transport_stream_op *op,
-                                                  grpc_error *error) {
-  grpc_closure_sched(exec_ctx, op->recv_message_ready, GRPC_ERROR_REF(error));
-  grpc_closure_sched(exec_ctx, op->recv_initial_metadata_ready,
-                     GRPC_ERROR_REF(error));
+void grpc_transport_stream_op_batch_finish_with_failure(
+    grpc_exec_ctx *exec_ctx, grpc_transport_stream_op_batch *op,
+    grpc_error *error) {
+  if (op->recv_message) {
+    grpc_closure_sched(exec_ctx, op->payload->recv_message.recv_message_ready,
+                       GRPC_ERROR_REF(error));
+  }
+  if (op->recv_initial_metadata) {
+    grpc_closure_sched(
+        exec_ctx,
+        op->payload->recv_initial_metadata.recv_initial_metadata_ready,
+        GRPC_ERROR_REF(error));
+  }
   grpc_closure_sched(exec_ctx, op->on_complete, error);
-  GRPC_ERROR_UNREF(op->cancel_error);
+  if (op->cancel_stream) {
+    GRPC_ERROR_UNREF(op->payload->cancel_stream.cancel_error);
+  }
 }
 
 typedef struct {
@@ -213,23 +258,25 @@ grpc_transport_op *grpc_make_transport_op(grpc_closure *on_complete) {
 typedef struct {
   grpc_closure outer_on_complete;
   grpc_closure *inner_on_complete;
-  grpc_transport_stream_op op;
+  grpc_transport_stream_op_batch op;
+  grpc_transport_stream_op_batch_payload payload;
 } made_transport_stream_op;
 
 static void destroy_made_transport_stream_op(grpc_exec_ctx *exec_ctx, void *arg,
                                              grpc_error *error) {
   made_transport_stream_op *op = arg;
-  grpc_closure_sched(exec_ctx, op->inner_on_complete, GRPC_ERROR_REF(error));
+  grpc_closure *c = op->inner_on_complete;
   gpr_free(op);
+  grpc_closure_run(exec_ctx, c, GRPC_ERROR_REF(error));
 }
 
-grpc_transport_stream_op *grpc_make_transport_stream_op(
+grpc_transport_stream_op_batch *grpc_make_transport_stream_op(
     grpc_closure *on_complete) {
-  made_transport_stream_op *op = gpr_malloc(sizeof(*op));
+  made_transport_stream_op *op = gpr_zalloc(sizeof(*op));
+  op->op.payload = &op->payload;
   grpc_closure_init(&op->outer_on_complete, destroy_made_transport_stream_op,
                     op, grpc_schedule_on_exec_ctx);
   op->inner_on_complete = on_complete;
-  memset(&op->op, 0, sizeof(op->op));
   op->op.on_complete = &op->outer_on_complete;
   return &op->op;
 }
diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h
index bb23c0225aa9877779d6d6acdace9704500a4b76..93369cc689f489196b58a75e7ef54819e1b84605 100644
--- a/src/core/lib/transport/transport.h
+++ b/src/core/lib/transport/transport.h
@@ -41,6 +41,7 @@
 #include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/iomgr/pollset.h"
 #include "src/core/lib/iomgr/pollset_set.h"
+#include "src/core/lib/support/arena.h"
 #include "src/core/lib/transport/byte_stream.h"
 #include "src/core/lib/transport/metadata_batch.h"
 
@@ -64,6 +65,7 @@ typedef struct grpc_stream_refcount {
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG
   const char *object_type;
 #endif
+  grpc_slice_refcount slice_refcount;
 } grpc_stream_refcount;
 
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG
@@ -84,6 +86,11 @@ void grpc_stream_unref(grpc_exec_ctx *exec_ctx, grpc_stream_refcount *refcount);
   grpc_stream_ref_init(rc, ir, cb, cb_arg)
 #endif
 
+/* Wrap a buffer that is owned by some stream object into a slice that shares
+   the same refcount */
+grpc_slice grpc_slice_from_stream_owned_buffer(grpc_stream_refcount *refcount,
+                                               void *buffer, size_t length);
+
 typedef struct {
   uint64_t framing_bytes;
   uint64_t data_bytes;
@@ -102,55 +109,98 @@ void grpc_transport_move_stats(grpc_transport_stream_stats *from,
                                grpc_transport_stream_stats *to);
 
 typedef struct {
+  void *extra_arg;
   grpc_closure closure;
-  void *args[2];
-} grpc_transport_private_op_data;
+} grpc_handler_private_op_data;
+
+typedef struct grpc_transport_stream_op_batch_payload
+    grpc_transport_stream_op_batch_payload;
 
 /* Transport stream op: a set of operations to perform on a transport
    against a single stream */
-typedef struct grpc_transport_stream_op {
+typedef struct grpc_transport_stream_op_batch {
   /** Should be enqueued when all requested operations (excluding recv_message
       and recv_initial_metadata which have their own closures) in a given batch
       have been completed. */
   grpc_closure *on_complete;
 
+  /** Values for the stream op (fields set are determined by flags above) */
+  grpc_transport_stream_op_batch_payload *payload;
+
   /** Is the completion of this op covered by a poller (if false: the op should
       complete independently of some pollset being polled) */
-  bool covered_by_poller;
+  bool covered_by_poller : 1;
 
-  /** Send initial metadata to the peer, from the provided metadata batch.
-      idempotent_request MUST be set if this is non-null */
-  grpc_metadata_batch *send_initial_metadata;
-  /** Iff send_initial_metadata != NULL, flags associated with
-      send_initial_metadata: a bitfield of GRPC_INITIAL_METADATA_xxx */
-  uint32_t send_initial_metadata_flags;
+  /** Send initial metadata to the peer, from the provided metadata batch. */
+  bool send_initial_metadata : 1;
 
   /** Send trailing metadata to the peer, from the provided metadata batch. */
-  grpc_metadata_batch *send_trailing_metadata;
+  bool send_trailing_metadata : 1;
 
   /** Send message data to the peer, from the provided byte stream. */
-  grpc_byte_stream *send_message;
+  bool send_message : 1;
 
   /** Receive initial metadata from the stream, into provided metadata batch. */
-  grpc_metadata_batch *recv_initial_metadata;
-  bool *recv_idempotent_request;
-  bool *recv_cacheable_request;
-  /** Should be enqueued when initial metadata is ready to be processed. */
-  grpc_closure *recv_initial_metadata_ready;
+  bool recv_initial_metadata : 1;
 
   /** Receive message data from the stream, into provided byte stream. */
-  grpc_byte_stream **recv_message;
-  /** Should be enqueued when one message is ready to be processed. */
-  grpc_closure *recv_message_ready;
+  bool recv_message : 1;
 
   /** Receive trailing metadata from the stream, into provided metadata batch.
    */
-  grpc_metadata_batch *recv_trailing_metadata;
+  bool recv_trailing_metadata : 1;
 
   /** Collect any stats into provided buffer, zero internal stat counters */
-  grpc_transport_stream_stats *collect_stats;
+  bool collect_stats : 1;
+
+  /** Cancel this stream with the provided error */
+  bool cancel_stream : 1;
+
+  /***************************************************************************
+   * remaining fields are initialized and used at the discretion of the
+   * current handler of the op */
 
-  /** If != GRPC_ERROR_NONE, forcefully close this stream.
+  grpc_handler_private_op_data handler_private;
+} grpc_transport_stream_op_batch;
+
+struct grpc_transport_stream_op_batch_payload {
+  struct {
+    grpc_metadata_batch *send_initial_metadata;
+    /** Iff send_initial_metadata != NULL, flags associated with
+        send_initial_metadata: a bitfield of GRPC_INITIAL_METADATA_xxx */
+    uint32_t send_initial_metadata_flags;
+  } send_initial_metadata;
+
+  struct {
+    grpc_metadata_batch *send_trailing_metadata;
+  } send_trailing_metadata;
+
+  struct {
+    grpc_byte_stream *send_message;
+  } send_message;
+
+  struct {
+    grpc_metadata_batch *recv_initial_metadata;
+    uint32_t *recv_flags;
+    /** Should be enqueued when initial metadata is ready to be processed. */
+    grpc_closure *recv_initial_metadata_ready;
+  } recv_initial_metadata;
+
+  struct {
+    grpc_byte_stream **recv_message;
+    /** Should be enqueued when one message is ready to be processed. */
+    grpc_closure *recv_message_ready;
+  } recv_message;
+
+  struct {
+    grpc_metadata_batch *recv_trailing_metadata;
+  } recv_trailing_metadata;
+
+  struct {
+    grpc_transport_stream_stats *collect_stats;
+  } collect_stats;
+
+  /** Forcefully close this stream.
       The HTTP2 semantics should be:
       - server side: if cancel_error has GRPC_ERROR_INT_GRPC_STATUS, and
         trailing metadata has not been sent, send trailing metadata with status
@@ -160,17 +210,13 @@ typedef struct grpc_transport_stream_op {
         convert to a HTTP2 error code using
         grpc_chttp2_grpc_status_to_http2_error. Send a RST_STREAM with this
         error. */
-  grpc_error *cancel_error;
+  struct {
+    grpc_error *cancel_error;
+  } cancel_stream;
 
   /* Indexes correspond to grpc_context_index enum values */
   grpc_call_context_element *context;
-
-  /***************************************************************************
-   * remaining fields are initialized and used at the discretion of the
-   * current handler of the op */
-
-  grpc_transport_private_op_data handler_private;
-} grpc_transport_stream_op;
+};
 
 /** Transport op: a set of operations to perform on a transport as a whole */
 typedef struct grpc_transport_op {
@@ -203,7 +249,7 @@ typedef struct grpc_transport_op {
    * remaining fields are initialized and used at the discretion of the
    * transport implementation */
 
-  grpc_transport_private_op_data transport_private;
+  grpc_handler_private_op_data handler_private;
 } grpc_transport_op;
 
 /* Returns the amount of memory required to store a grpc_stream for this
@@ -223,7 +269,7 @@ size_t grpc_transport_stream_size(grpc_transport *transport);
 int grpc_transport_init_stream(grpc_exec_ctx *exec_ctx,
                                grpc_transport *transport, grpc_stream *stream,
                                grpc_stream_refcount *refcount,
-                               const void *server_data);
+                               const void *server_data, gpr_arena *arena);
 
 void grpc_transport_set_pops(grpc_exec_ctx *exec_ctx, grpc_transport *transport,
                              grpc_stream *stream, grpc_polling_entity *pollent);
@@ -240,13 +286,14 @@ void grpc_transport_set_pops(grpc_exec_ctx *exec_ctx, grpc_transport *transport,
                  caller, but any child memory must be cleaned up) */
 void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx,
                                    grpc_transport *transport,
-                                   grpc_stream *stream, void *and_free_memory);
+                                   grpc_stream *stream,
+                                   grpc_closure *then_schedule_closure);
 
-void grpc_transport_stream_op_finish_with_failure(grpc_exec_ctx *exec_ctx,
-                                                  grpc_transport_stream_op *op,
-                                                  grpc_error *error);
+void grpc_transport_stream_op_batch_finish_with_failure(
+    grpc_exec_ctx *exec_ctx, grpc_transport_stream_op_batch *op,
+    grpc_error *error);
 
-char *grpc_transport_stream_op_string(grpc_transport_stream_op *op);
+char *grpc_transport_stream_op_batch_string(grpc_transport_stream_op_batch *op);
 char *grpc_transport_op_string(grpc_transport_op *op);
 
 /* Send a batch of operations on a transport
@@ -257,11 +304,12 @@ char *grpc_transport_op_string(grpc_transport_op *op);
      transport - the transport on which to initiate the stream
      stream    - the stream on which to send the operations. This must be
                  non-NULL and previously initialized by the same transport.
-     op        - a grpc_transport_stream_op specifying the op to perform */
+     op        - a grpc_transport_stream_op_batch specifying the op to perform
+   */
 void grpc_transport_perform_stream_op(grpc_exec_ctx *exec_ctx,
                                       grpc_transport *transport,
                                       grpc_stream *stream,
-                                      grpc_transport_stream_op *op);
+                                      grpc_transport_stream_op_batch *op);
 
 void grpc_transport_perform_op(grpc_exec_ctx *exec_ctx,
                                grpc_transport *transport,
@@ -293,9 +341,10 @@ grpc_endpoint *grpc_transport_get_endpoint(grpc_exec_ctx *exec_ctx,
 /* Allocate a grpc_transport_op, and preconfigure the on_consumed closure to
    \a on_consumed and then delete the returned transport op */
 grpc_transport_op *grpc_make_transport_op(grpc_closure *on_consumed);
-/* Allocate a grpc_transport_stream_op, and preconfigure the on_consumed closure
+/* Allocate a grpc_transport_stream_op_batch, and preconfigure the on_consumed
+   closure
    to \a on_consumed and then delete the returned transport op */
-grpc_transport_stream_op *grpc_make_transport_stream_op(
+grpc_transport_stream_op_batch *grpc_make_transport_stream_op(
     grpc_closure *on_consumed);
 
 #ifdef __cplusplus
diff --git a/src/core/lib/transport/transport_impl.h b/src/core/lib/transport/transport_impl.h
index 8553148c35fd984226fd2587c3be4bd138055b51..bbb19a34bdb7dfc170dc8efd881e79f9d54f28f7 100644
--- a/src/core/lib/transport/transport_impl.h
+++ b/src/core/lib/transport/transport_impl.h
@@ -47,7 +47,7 @@ typedef struct grpc_transport_vtable {
   /* implementation of grpc_transport_init_stream */
   int (*init_stream)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
                      grpc_stream *stream, grpc_stream_refcount *refcount,
-                     const void *server_data);
+                     const void *server_data, gpr_arena *arena);
 
   /* implementation of grpc_transport_set_pollset */
   void (*set_pollset)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
@@ -59,7 +59,8 @@ typedef struct grpc_transport_vtable {
 
   /* implementation of grpc_transport_perform_stream_op */
   void (*perform_stream_op)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
-                            grpc_stream *stream, grpc_transport_stream_op *op);
+                            grpc_stream *stream,
+                            grpc_transport_stream_op_batch *op);
 
   /* implementation of grpc_transport_perform_op */
   void (*perform_op)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
@@ -67,7 +68,8 @@ typedef struct grpc_transport_vtable {
 
   /* implementation of grpc_transport_destroy_stream */
   void (*destroy_stream)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
-                         grpc_stream *stream, void *and_free_memory);
+                         grpc_stream *stream,
+                         grpc_closure *then_schedule_closure);
 
   /* implementation of grpc_transport_destroy */
   void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_transport *self);
diff --git a/src/core/lib/transport/transport_op_string.c b/src/core/lib/transport/transport_op_string.c
index 28360e37840de511731b432746c36e118ab42ed8..3a2a793e01bead1059e5c160dcbb4864058ff44b 100644
--- a/src/core/lib/transport/transport_op_string.c
+++ b/src/core/lib/transport/transport_op_string.c
@@ -71,7 +71,8 @@ static void put_metadata_list(gpr_strvec *b, grpc_metadata_batch md) {
   }
 }
 
-char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) {
+char *grpc_transport_stream_op_batch_string(
+    grpc_transport_stream_op_batch *op) {
   char *tmp;
   char *out;
 
@@ -81,45 +82,49 @@ char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) {
   gpr_strvec_add(
       &b, gpr_strdup(op->covered_by_poller ? "[COVERED]" : "[UNCOVERED]"));
 
-  if (op->send_initial_metadata != NULL) {
+  if (op->send_initial_metadata) {
     gpr_strvec_add(&b, gpr_strdup(" "));
     gpr_strvec_add(&b, gpr_strdup("SEND_INITIAL_METADATA{"));
-    put_metadata_list(&b, *op->send_initial_metadata);
+    put_metadata_list(
+        &b, *op->payload->send_initial_metadata.send_initial_metadata);
     gpr_strvec_add(&b, gpr_strdup("}"));
   }
 
-  if (op->send_message != NULL) {
+  if (op->send_message) {
     gpr_strvec_add(&b, gpr_strdup(" "));
     gpr_asprintf(&tmp, "SEND_MESSAGE:flags=0x%08x:len=%d",
-                 op->send_message->flags, op->send_message->length);
+                 op->payload->send_message.send_message->flags,
+                 op->payload->send_message.send_message->length);
     gpr_strvec_add(&b, tmp);
   }
 
-  if (op->send_trailing_metadata != NULL) {
+  if (op->send_trailing_metadata) {
     gpr_strvec_add(&b, gpr_strdup(" "));
     gpr_strvec_add(&b, gpr_strdup("SEND_TRAILING_METADATA{"));
-    put_metadata_list(&b, *op->send_trailing_metadata);
+    put_metadata_list(
+        &b, *op->payload->send_trailing_metadata.send_trailing_metadata);
     gpr_strvec_add(&b, gpr_strdup("}"));
   }
 
-  if (op->recv_initial_metadata != NULL) {
+  if (op->recv_initial_metadata) {
     gpr_strvec_add(&b, gpr_strdup(" "));
     gpr_strvec_add(&b, gpr_strdup("RECV_INITIAL_METADATA"));
   }
 
-  if (op->recv_message != NULL) {
+  if (op->recv_message) {
     gpr_strvec_add(&b, gpr_strdup(" "));
     gpr_strvec_add(&b, gpr_strdup("RECV_MESSAGE"));
   }
 
-  if (op->recv_trailing_metadata != NULL) {
+  if (op->recv_trailing_metadata) {
     gpr_strvec_add(&b, gpr_strdup(" "));
     gpr_strvec_add(&b, gpr_strdup("RECV_TRAILING_METADATA"));
   }
 
-  if (op->cancel_error != GRPC_ERROR_NONE) {
+  if (op->cancel_stream) {
     gpr_strvec_add(&b, gpr_strdup(" "));
-    const char *msg = grpc_error_string(op->cancel_error);
+    const char *msg =
+        grpc_error_string(op->payload->cancel_stream.cancel_error);
     gpr_asprintf(&tmp, "CANCEL:%s", msg);
 
     gpr_strvec_add(&b, tmp);
@@ -204,8 +209,9 @@ char *grpc_transport_op_string(grpc_transport_op *op) {
 }
 
 void grpc_call_log_op(char *file, int line, gpr_log_severity severity,
-                      grpc_call_element *elem, grpc_transport_stream_op *op) {
-  char *str = grpc_transport_stream_op_string(op);
+                      grpc_call_element *elem,
+                      grpc_transport_stream_op_batch *op) {
+  char *str = grpc_transport_stream_op_batch_string(op);
   gpr_log(file, line, severity, "OP[%s:%p]: %s", elem->filter->name, elem, str);
   gpr_free(str);
 }
diff --git a/src/core/plugin_registry/grpc_cronet_plugin_registry.c b/src/core/plugin_registry/grpc_cronet_plugin_registry.c
index c97f47b397a3cfd296068251ad644189c75b7074..907e5a0f3941141c3e688c662df989475217624b 100644
--- a/src/core/plugin_registry/grpc_cronet_plugin_registry.c
+++ b/src/core/plugin_registry/grpc_cronet_plugin_registry.c
@@ -33,16 +33,24 @@
 
 #include <grpc/grpc.h>
 
+extern void grpc_http_filters_init(void);
+extern void grpc_http_filters_shutdown(void);
 extern void grpc_chttp2_plugin_init(void);
 extern void grpc_chttp2_plugin_shutdown(void);
+extern void grpc_deadline_filter_init(void);
+extern void grpc_deadline_filter_shutdown(void);
 extern void grpc_client_channel_init(void);
 extern void grpc_client_channel_shutdown(void);
 extern void grpc_load_reporting_plugin_init(void);
 extern void grpc_load_reporting_plugin_shutdown(void);
 
 void grpc_register_built_in_plugins(void) {
+  grpc_register_plugin(grpc_http_filters_init,
+                       grpc_http_filters_shutdown);
   grpc_register_plugin(grpc_chttp2_plugin_init,
                        grpc_chttp2_plugin_shutdown);
+  grpc_register_plugin(grpc_deadline_filter_init,
+                       grpc_deadline_filter_shutdown);
   grpc_register_plugin(grpc_client_channel_init,
                        grpc_client_channel_shutdown);
   grpc_register_plugin(grpc_load_reporting_plugin_init,
diff --git a/src/core/plugin_registry/grpc_plugin_registry.c b/src/core/plugin_registry/grpc_plugin_registry.c
index 2efd9cd1ad7a76043371a436910b96e9210f4318..25bda7a2622e7fed2e807311654065c3725fa38c 100644
--- a/src/core/plugin_registry/grpc_plugin_registry.c
+++ b/src/core/plugin_registry/grpc_plugin_registry.c
@@ -33,8 +33,12 @@
 
 #include <grpc/grpc.h>
 
+extern void grpc_http_filters_init(void);
+extern void grpc_http_filters_shutdown(void);
 extern void grpc_chttp2_plugin_init(void);
 extern void grpc_chttp2_plugin_shutdown(void);
+extern void grpc_deadline_filter_init(void);
+extern void grpc_deadline_filter_shutdown(void);
 extern void grpc_client_channel_init(void);
 extern void grpc_client_channel_shutdown(void);
 extern void grpc_lb_policy_grpclb_init(void);
@@ -43,6 +47,8 @@ extern void grpc_lb_policy_pick_first_init(void);
 extern void grpc_lb_policy_pick_first_shutdown(void);
 extern void grpc_lb_policy_round_robin_init(void);
 extern void grpc_lb_policy_round_robin_shutdown(void);
+extern void grpc_resolver_dns_ares_init(void);
+extern void grpc_resolver_dns_ares_shutdown(void);
 extern void grpc_resolver_dns_native_init(void);
 extern void grpc_resolver_dns_native_shutdown(void);
 extern void grpc_resolver_sockaddr_init(void);
@@ -51,10 +57,18 @@ extern void grpc_load_reporting_plugin_init(void);
 extern void grpc_load_reporting_plugin_shutdown(void);
 extern void census_grpc_plugin_init(void);
 extern void census_grpc_plugin_shutdown(void);
+extern void grpc_max_age_filter_init(void);
+extern void grpc_max_age_filter_shutdown(void);
+extern void grpc_message_size_filter_init(void);
+extern void grpc_message_size_filter_shutdown(void);
 
 void grpc_register_built_in_plugins(void) {
+  grpc_register_plugin(grpc_http_filters_init,
+                       grpc_http_filters_shutdown);
   grpc_register_plugin(grpc_chttp2_plugin_init,
                        grpc_chttp2_plugin_shutdown);
+  grpc_register_plugin(grpc_deadline_filter_init,
+                       grpc_deadline_filter_shutdown);
   grpc_register_plugin(grpc_client_channel_init,
                        grpc_client_channel_shutdown);
   grpc_register_plugin(grpc_lb_policy_grpclb_init,
@@ -63,6 +77,8 @@ void grpc_register_built_in_plugins(void) {
                        grpc_lb_policy_pick_first_shutdown);
   grpc_register_plugin(grpc_lb_policy_round_robin_init,
                        grpc_lb_policy_round_robin_shutdown);
+  grpc_register_plugin(grpc_resolver_dns_ares_init,
+                       grpc_resolver_dns_ares_shutdown);
   grpc_register_plugin(grpc_resolver_dns_native_init,
                        grpc_resolver_dns_native_shutdown);
   grpc_register_plugin(grpc_resolver_sockaddr_init,
@@ -71,4 +87,8 @@ void grpc_register_built_in_plugins(void) {
                        grpc_load_reporting_plugin_shutdown);
   grpc_register_plugin(census_grpc_plugin_init,
                        census_grpc_plugin_shutdown);
+  grpc_register_plugin(grpc_max_age_filter_init,
+                       grpc_max_age_filter_shutdown);
+  grpc_register_plugin(grpc_message_size_filter_init,
+                       grpc_message_size_filter_shutdown);
 }
diff --git a/src/core/plugin_registry/grpc_unsecure_plugin_registry.c b/src/core/plugin_registry/grpc_unsecure_plugin_registry.c
index 8b18af699dbc1b3fa0e71f10ab0a5751a3b0065b..05d4771bce3d7a4aa0f70cac83daec5572ca4acb 100644
--- a/src/core/plugin_registry/grpc_unsecure_plugin_registry.c
+++ b/src/core/plugin_registry/grpc_unsecure_plugin_registry.c
@@ -33,10 +33,16 @@
 
 #include <grpc/grpc.h>
 
+extern void grpc_http_filters_init(void);
+extern void grpc_http_filters_shutdown(void);
 extern void grpc_chttp2_plugin_init(void);
 extern void grpc_chttp2_plugin_shutdown(void);
+extern void grpc_deadline_filter_init(void);
+extern void grpc_deadline_filter_shutdown(void);
 extern void grpc_client_channel_init(void);
 extern void grpc_client_channel_shutdown(void);
+extern void grpc_resolver_dns_ares_init(void);
+extern void grpc_resolver_dns_ares_shutdown(void);
 extern void grpc_resolver_dns_native_init(void);
 extern void grpc_resolver_dns_native_shutdown(void);
 extern void grpc_resolver_sockaddr_init(void);
@@ -51,12 +57,22 @@ extern void grpc_lb_policy_round_robin_init(void);
 extern void grpc_lb_policy_round_robin_shutdown(void);
 extern void census_grpc_plugin_init(void);
 extern void census_grpc_plugin_shutdown(void);
+extern void grpc_max_age_filter_init(void);
+extern void grpc_max_age_filter_shutdown(void);
+extern void grpc_message_size_filter_init(void);
+extern void grpc_message_size_filter_shutdown(void);
 
 void grpc_register_built_in_plugins(void) {
+  grpc_register_plugin(grpc_http_filters_init,
+                       grpc_http_filters_shutdown);
   grpc_register_plugin(grpc_chttp2_plugin_init,
                        grpc_chttp2_plugin_shutdown);
+  grpc_register_plugin(grpc_deadline_filter_init,
+                       grpc_deadline_filter_shutdown);
   grpc_register_plugin(grpc_client_channel_init,
                        grpc_client_channel_shutdown);
+  grpc_register_plugin(grpc_resolver_dns_ares_init,
+                       grpc_resolver_dns_ares_shutdown);
   grpc_register_plugin(grpc_resolver_dns_native_init,
                        grpc_resolver_dns_native_shutdown);
   grpc_register_plugin(grpc_resolver_sockaddr_init,
@@ -71,4 +87,8 @@ void grpc_register_built_in_plugins(void) {
                        grpc_lb_policy_round_robin_shutdown);
   grpc_register_plugin(census_grpc_plugin_init,
                        census_grpc_plugin_shutdown);
+  grpc_register_plugin(grpc_max_age_filter_init,
+                       grpc_max_age_filter_shutdown);
+  grpc_register_plugin(grpc_message_size_filter_init,
+                       grpc_message_size_filter_shutdown);
 }
diff --git a/src/core/lib/tsi/README.md b/src/core/tsi/README.md
similarity index 100%
rename from src/core/lib/tsi/README.md
rename to src/core/tsi/README.md
diff --git a/src/core/lib/tsi/fake_transport_security.c b/src/core/tsi/fake_transport_security.c
similarity index 99%
rename from src/core/lib/tsi/fake_transport_security.c
rename to src/core/tsi/fake_transport_security.c
index bbe323df3bbdcac2978d64c8e0a7cd538e1f5205..1836beefc421f6c213010bd0b073f779ff9f07f1 100644
--- a/src/core/lib/tsi/fake_transport_security.c
+++ b/src/core/tsi/fake_transport_security.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/lib/tsi/fake_transport_security.h"
+#include "src/core/tsi/fake_transport_security.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -40,7 +40,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/port_platform.h>
 #include <grpc/support/useful.h>
-#include "src/core/lib/tsi/transport_security.h"
+#include "src/core/tsi/transport_security.h"
 
 /* --- Constants. ---*/
 #define TSI_FAKE_FRAME_HEADER_SIZE 4
@@ -499,6 +499,7 @@ static const tsi_handshaker_vtable handshaker_vtable = {
     fake_handshaker_extract_peer,
     fake_handshaker_create_frame_protector,
     fake_handshaker_destroy,
+    NULL,
 };
 
 tsi_handshaker *tsi_create_fake_handshaker(int is_client) {
diff --git a/src/core/lib/tsi/fake_transport_security.h b/src/core/tsi/fake_transport_security.h
similarity index 91%
rename from src/core/lib/tsi/fake_transport_security.h
rename to src/core/tsi/fake_transport_security.h
index 54a9469b5841ec779a1413c563f1eaa31eb9f60b..0697c7279f1b211ac975a10056b485a3f7ce9b8d 100644
--- a/src/core/lib/tsi/fake_transport_security.h
+++ b/src/core/tsi/fake_transport_security.h
@@ -31,10 +31,10 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_TSI_FAKE_TRANSPORT_SECURITY_H
-#define GRPC_CORE_LIB_TSI_FAKE_TRANSPORT_SECURITY_H
+#ifndef GRPC_CORE_TSI_FAKE_TRANSPORT_SECURITY_H
+#define GRPC_CORE_TSI_FAKE_TRANSPORT_SECURITY_H
 
-#include "src/core/lib/tsi/transport_security_interface.h"
+#include "src/core/tsi/transport_security_interface.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -58,4 +58,4 @@ tsi_frame_protector *tsi_create_fake_protector(
 }
 #endif
 
-#endif /* GRPC_CORE_LIB_TSI_FAKE_TRANSPORT_SECURITY_H */
+#endif /* GRPC_CORE_TSI_FAKE_TRANSPORT_SECURITY_H */
diff --git a/src/core/lib/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c
similarity index 85%
rename from src/core/lib/tsi/ssl_transport_security.c
rename to src/core/tsi/ssl_transport_security.c
index 53aabdb92679afbc291d8b3d7f50e34fc7b50547..e1d634a1fa445debefdab856fe34d105ebe1244e 100644
--- a/src/core/lib/tsi/ssl_transport_security.c
+++ b/src/core/tsi/ssl_transport_security.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/lib/tsi/ssl_transport_security.h"
+#include "src/core/tsi/ssl_transport_security.h"
 
 #include <grpc/support/port_platform.h>
 
@@ -45,6 +45,7 @@
 #include <ws2tcpip.h>
 #else
 #include <arpa/inet.h>
+#include <sys/socket.h>
 #endif
 
 #include <grpc/support/alloc.h>
@@ -60,8 +61,8 @@
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
-#include "src/core/lib/tsi/ssl_types.h"
-#include "src/core/lib/tsi/transport_security.h"
+#include "src/core/tsi/ssl_types.h"
+#include "src/core/tsi/transport_security.h"
 
 /* --- Constants. ---*/
 
@@ -81,23 +82,13 @@
 
 /* --- Structure definitions. ---*/
 
-struct tsi_ssl_handshaker_factory {
-  tsi_result (*create_handshaker)(tsi_ssl_handshaker_factory *self,
-                                  const char *server_name_indication,
-                                  tsi_handshaker **handshaker);
-  void (*destroy)(tsi_ssl_handshaker_factory *self);
-};
-
-typedef struct {
-  tsi_ssl_handshaker_factory base;
+struct tsi_ssl_client_handshaker_factory {
   SSL_CTX *ssl_context;
   unsigned char *alpn_protocol_list;
   size_t alpn_protocol_list_length;
-} tsi_ssl_client_handshaker_factory;
-
-typedef struct {
-  tsi_ssl_handshaker_factory base;
+};
 
+struct tsi_ssl_server_handshaker_factory {
   /* Several contexts to support SNI.
      The tsi_peer array contains the subject names of the server certificates
      associated with the contexts at the same index.  */
@@ -106,7 +97,7 @@ typedef struct {
   size_t ssl_context_count;
   unsigned char *alpn_protocol_list;
   size_t alpn_protocol_list_length;
-} tsi_ssl_server_handshaker_factory;
+};
 
 typedef struct {
   tsi_handshaker base;
@@ -488,9 +479,9 @@ static tsi_result do_ssl_write(SSL *ssl, unsigned char *unprotected_bytes,
 }
 
 /* Loads an in-memory PEM certificate chain into the SSL context. */
-static tsi_result ssl_ctx_use_certificate_chain(
-    SSL_CTX *context, const unsigned char *pem_cert_chain,
-    size_t pem_cert_chain_size) {
+static tsi_result ssl_ctx_use_certificate_chain(SSL_CTX *context,
+                                                const char *pem_cert_chain,
+                                                size_t pem_cert_chain_size) {
   tsi_result result = TSI_OK;
   X509 *certificate = NULL;
   BIO *pem;
@@ -531,8 +522,7 @@ static tsi_result ssl_ctx_use_certificate_chain(
 }
 
 /* Loads an in-memory PEM private key into the SSL context. */
-static tsi_result ssl_ctx_use_private_key(SSL_CTX *context,
-                                          const unsigned char *pem_key,
+static tsi_result ssl_ctx_use_private_key(SSL_CTX *context, const char *pem_key,
                                           size_t pem_key_size) {
   tsi_result result = TSI_OK;
   EVP_PKEY *private_key = NULL;
@@ -558,9 +548,11 @@ static tsi_result ssl_ctx_use_private_key(SSL_CTX *context,
 
 /* Loads in-memory PEM verification certs into the SSL context and optionally
    returns the verification cert names (root_names can be NULL). */
-static tsi_result ssl_ctx_load_verification_certs(
-    SSL_CTX *context, const unsigned char *pem_roots, size_t pem_roots_size,
-    STACK_OF(X509_NAME) * *root_names) {
+static tsi_result ssl_ctx_load_verification_certs(SSL_CTX *context,
+                                                  const char *pem_roots,
+                                                  size_t pem_roots_size,
+                                                  STACK_OF(X509_NAME) *
+                                                      *root_names) {
   tsi_result result = TSI_OK;
   size_t num_roots = 0;
   X509 *root = NULL;
@@ -627,24 +619,25 @@ static tsi_result ssl_ctx_load_verification_certs(
 /* Populates the SSL context with a private key and a cert chain, and sets the
    cipher list and the ephemeral ECDH key. */
 static tsi_result populate_ssl_context(
-    SSL_CTX *context, const unsigned char *pem_private_key,
-    size_t pem_private_key_size, const unsigned char *pem_certificate_chain,
-    size_t pem_certificate_chain_size, const char *cipher_list) {
+    SSL_CTX *context, const tsi_ssl_pem_key_cert_pair *key_cert_pair,
+    const char *cipher_list) {
   tsi_result result = TSI_OK;
-  if (pem_certificate_chain != NULL) {
-    result = ssl_ctx_use_certificate_chain(context, pem_certificate_chain,
-                                           pem_certificate_chain_size);
-    if (result != TSI_OK) {
-      gpr_log(GPR_ERROR, "Invalid cert chain file.");
-      return result;
+  if (key_cert_pair != NULL) {
+    if (key_cert_pair->cert_chain != NULL) {
+      result = ssl_ctx_use_certificate_chain(context, key_cert_pair->cert_chain,
+                                             strlen(key_cert_pair->cert_chain));
+      if (result != TSI_OK) {
+        gpr_log(GPR_ERROR, "Invalid cert chain file.");
+        return result;
+      }
     }
-  }
-  if (pem_private_key != NULL) {
-    result =
-        ssl_ctx_use_private_key(context, pem_private_key, pem_private_key_size);
-    if (result != TSI_OK || !SSL_CTX_check_private_key(context)) {
-      gpr_log(GPR_ERROR, "Invalid private key.");
-      return result != TSI_OK ? result : TSI_INVALID_ARGUMENT;
+    if (key_cert_pair->private_key != NULL) {
+      result = ssl_ctx_use_private_key(context, key_cert_pair->private_key,
+                                       strlen(key_cert_pair->private_key));
+      if (result != TSI_OK || !SSL_CTX_check_private_key(context)) {
+        gpr_log(GPR_ERROR, "Invalid private key.");
+        return result != TSI_OK ? result : TSI_INVALID_ARGUMENT;
+      }
     }
   }
   if ((cipher_list != NULL) && !SSL_CTX_set_cipher_list(context, cipher_list)) {
@@ -665,13 +658,12 @@ static tsi_result populate_ssl_context(
 }
 
 /* Extracts the CN and the SANs from an X509 cert as a peer object. */
-static tsi_result extract_x509_subject_names_from_pem_cert(
-    const unsigned char *pem_cert, size_t pem_cert_size, tsi_peer *peer) {
+static tsi_result extract_x509_subject_names_from_pem_cert(const char *pem_cert,
+                                                           tsi_peer *peer) {
   tsi_result result = TSI_OK;
   X509 *cert = NULL;
   BIO *pem;
-  GPR_ASSERT(pem_cert_size <= INT_MAX);
-  pem = BIO_new_mem_buf((void *)pem_cert, (int)pem_cert_size);
+  pem = BIO_new_mem_buf((void *)pem_cert, (int)strlen(pem_cert));
   if (pem == NULL) return TSI_OUT_OF_RESOURCES;
 
   cert = PEM_read_bio_X509(pem, NULL, NULL, "");
@@ -688,8 +680,7 @@ static tsi_result extract_x509_subject_names_from_pem_cert(
 
 /* Builds the alpn protocol name list according to rfc 7301. */
 static tsi_result build_alpn_protocol_name_list(
-    const unsigned char **alpn_protocols,
-    const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols,
+    const char **alpn_protocols, uint16_t num_alpn_protocols,
     unsigned char **protocol_name_list, size_t *protocol_name_list_length) {
   uint16_t i;
   unsigned char *current;
@@ -697,19 +688,21 @@ static tsi_result build_alpn_protocol_name_list(
   *protocol_name_list_length = 0;
   if (num_alpn_protocols == 0) return TSI_INVALID_ARGUMENT;
   for (i = 0; i < num_alpn_protocols; i++) {
-    if (alpn_protocols_lengths[i] == 0) {
-      gpr_log(GPR_ERROR, "Invalid 0-length protocol name.");
+    size_t length = alpn_protocols[i] == NULL ? 0 : strlen(alpn_protocols[i]);
+    if (length == 0 || length > 255) {
+      gpr_log(GPR_ERROR, "Invalid protocol name length: %d.", (int)length);
       return TSI_INVALID_ARGUMENT;
     }
-    *protocol_name_list_length += (size_t)alpn_protocols_lengths[i] + 1;
+    *protocol_name_list_length += length + 1;
   }
   *protocol_name_list = gpr_malloc(*protocol_name_list_length);
   if (*protocol_name_list == NULL) return TSI_OUT_OF_RESOURCES;
   current = *protocol_name_list;
   for (i = 0; i < num_alpn_protocols; i++) {
-    *(current++) = alpn_protocols_lengths[i];
-    memcpy(current, alpn_protocols[i], alpn_protocols_lengths[i]);
-    current += alpn_protocols_lengths[i];
+    size_t length = strlen(alpn_protocols[i]);
+    *(current++) = (uint8_t)length; /* max checked above. */
+    memcpy(current, alpn_protocols[i], length);
+    current += length;
   }
   /* Safety check. */
   if ((current < *protocol_name_list) ||
@@ -1049,22 +1042,11 @@ static const tsi_handshaker_vtable handshaker_vtable = {
     ssl_handshaker_extract_peer,
     ssl_handshaker_create_frame_protector,
     ssl_handshaker_destroy,
+    NULL,
 };
 
 /* --- tsi_ssl_handshaker_factory common methods. --- */
 
-tsi_result tsi_ssl_handshaker_factory_create_handshaker(
-    tsi_ssl_handshaker_factory *self, const char *server_name_indication,
-    tsi_handshaker **handshaker) {
-  if (self == NULL || handshaker == NULL) return TSI_INVALID_ARGUMENT;
-  return self->create_handshaker(self, server_name_indication, handshaker);
-}
-
-void tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory *self) {
-  if (self == NULL) return;
-  self->destroy(self);
-}
-
 static tsi_result create_tsi_ssl_handshaker(SSL_CTX *ctx, int is_client,
                                             const char *server_name_indication,
                                             tsi_handshaker **handshaker) {
@@ -1152,24 +1134,20 @@ static int select_protocol_list(const unsigned char **out,
   return SSL_TLSEXT_ERR_NOACK;
 }
 
-/* --- tsi_ssl__client_handshaker_factory methods implementation. --- */
+/* --- tsi_ssl_client_handshaker_factory methods implementation. --- */
 
-static tsi_result ssl_client_handshaker_factory_create_handshaker(
-    tsi_ssl_handshaker_factory *self, const char *server_name_indication,
+tsi_result tsi_ssl_client_handshaker_factory_create_handshaker(
+    tsi_ssl_client_handshaker_factory *self, const char *server_name_indication,
     tsi_handshaker **handshaker) {
-  tsi_ssl_client_handshaker_factory *impl =
-      (tsi_ssl_client_handshaker_factory *)self;
-  return create_tsi_ssl_handshaker(impl->ssl_context, 1, server_name_indication,
+  return create_tsi_ssl_handshaker(self->ssl_context, 1, server_name_indication,
                                    handshaker);
 }
 
-static void ssl_client_handshaker_factory_destroy(
-    tsi_ssl_handshaker_factory *self) {
-  tsi_ssl_client_handshaker_factory *impl =
-      (tsi_ssl_client_handshaker_factory *)self;
-  if (impl->ssl_context != NULL) SSL_CTX_free(impl->ssl_context);
-  if (impl->alpn_protocol_list != NULL) gpr_free(impl->alpn_protocol_list);
-  gpr_free(impl);
+void tsi_ssl_client_handshaker_factory_destroy(
+    tsi_ssl_client_handshaker_factory *self) {
+  if (self->ssl_context != NULL) SSL_CTX_free(self->ssl_context);
+  if (self->alpn_protocol_list != NULL) gpr_free(self->alpn_protocol_list);
+  gpr_free(self);
 }
 
 static int client_handshaker_factory_npn_callback(SSL *ssl, unsigned char **out,
@@ -1186,36 +1164,29 @@ static int client_handshaker_factory_npn_callback(SSL *ssl, unsigned char **out,
 
 /* --- tsi_ssl_server_handshaker_factory methods implementation. --- */
 
-static tsi_result ssl_server_handshaker_factory_create_handshaker(
-    tsi_ssl_handshaker_factory *self, const char *server_name_indication,
-    tsi_handshaker **handshaker) {
-  tsi_ssl_server_handshaker_factory *impl =
-      (tsi_ssl_server_handshaker_factory *)self;
-  if (impl->ssl_context_count == 0 || server_name_indication != NULL) {
-    return TSI_INVALID_ARGUMENT;
-  }
+tsi_result tsi_ssl_server_handshaker_factory_create_handshaker(
+    tsi_ssl_server_handshaker_factory *self, tsi_handshaker **handshaker) {
+  if (self->ssl_context_count == 0) return TSI_INVALID_ARGUMENT;
   /* Create the handshaker with the first context. We will switch if needed
      because of SNI in ssl_server_handshaker_factory_servername_callback.  */
-  return create_tsi_ssl_handshaker(impl->ssl_contexts[0], 0, NULL, handshaker);
+  return create_tsi_ssl_handshaker(self->ssl_contexts[0], 0, NULL, handshaker);
 }
 
-static void ssl_server_handshaker_factory_destroy(
-    tsi_ssl_handshaker_factory *self) {
-  tsi_ssl_server_handshaker_factory *impl =
-      (tsi_ssl_server_handshaker_factory *)self;
+void tsi_ssl_server_handshaker_factory_destroy(
+    tsi_ssl_server_handshaker_factory *self) {
   size_t i;
-  for (i = 0; i < impl->ssl_context_count; i++) {
-    if (impl->ssl_contexts[i] != NULL) {
-      SSL_CTX_free(impl->ssl_contexts[i]);
-      tsi_peer_destruct(&impl->ssl_context_x509_subject_names[i]);
+  for (i = 0; i < self->ssl_context_count; i++) {
+    if (self->ssl_contexts[i] != NULL) {
+      SSL_CTX_free(self->ssl_contexts[i]);
+      tsi_peer_destruct(&self->ssl_context_x509_subject_names[i]);
     }
   }
-  if (impl->ssl_contexts != NULL) gpr_free(impl->ssl_contexts);
-  if (impl->ssl_context_x509_subject_names != NULL) {
-    gpr_free(impl->ssl_context_x509_subject_names);
+  if (self->ssl_contexts != NULL) gpr_free(self->ssl_contexts);
+  if (self->ssl_context_x509_subject_names != NULL) {
+    gpr_free(self->ssl_context_x509_subject_names);
   }
-  if (impl->alpn_protocol_list != NULL) gpr_free(impl->alpn_protocol_list);
-  gpr_free(impl);
+  if (self->alpn_protocol_list != NULL) gpr_free(self->alpn_protocol_list);
+  gpr_free(self);
 }
 
 static int does_entry_match_name(const char *entry, size_t entry_length,
@@ -1312,12 +1283,10 @@ static int server_handshaker_factory_npn_advertised_callback(
 /* --- tsi_ssl_handshaker_factory constructors. --- */
 
 tsi_result tsi_create_ssl_client_handshaker_factory(
-    const unsigned char *pem_private_key, size_t pem_private_key_size,
-    const unsigned char *pem_cert_chain, size_t pem_cert_chain_size,
-    const unsigned char *pem_root_certs, size_t pem_root_certs_size,
-    const char *cipher_list, const unsigned char **alpn_protocols,
-    const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols,
-    tsi_ssl_handshaker_factory **factory) {
+    const tsi_ssl_pem_key_cert_pair *pem_key_cert_pair,
+    const char *pem_root_certs, const char *cipher_suites,
+    const char **alpn_protocols, uint16_t num_alpn_protocols,
+    tsi_ssl_client_handshaker_factory **factory) {
   SSL_CTX *ssl_context = NULL;
   tsi_ssl_client_handshaker_factory *impl = NULL;
   tsi_result result = TSI_OK;
@@ -1339,20 +1308,19 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
 
   do {
     result =
-        populate_ssl_context(ssl_context, pem_private_key, pem_private_key_size,
-                             pem_cert_chain, pem_cert_chain_size, cipher_list);
+        populate_ssl_context(ssl_context, pem_key_cert_pair, cipher_suites);
     if (result != TSI_OK) break;
     result = ssl_ctx_load_verification_certs(ssl_context, pem_root_certs,
-                                             pem_root_certs_size, NULL);
+                                             strlen(pem_root_certs), NULL);
     if (result != TSI_OK) {
       gpr_log(GPR_ERROR, "Cannot load server root certificates.");
       break;
     }
 
     if (num_alpn_protocols != 0) {
-      result = build_alpn_protocol_name_list(
-          alpn_protocols, alpn_protocols_lengths, num_alpn_protocols,
-          &impl->alpn_protocol_list, &impl->alpn_protocol_list_length);
+      result = build_alpn_protocol_name_list(alpn_protocols, num_alpn_protocols,
+                                             &impl->alpn_protocol_list,
+                                             &impl->alpn_protocol_list_length);
       if (result != TSI_OK) {
         gpr_log(GPR_ERROR, "Building alpn list failed with error %s.",
                 tsi_result_to_string(result));
@@ -1373,48 +1341,35 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
     }
   } while (0);
   if (result != TSI_OK) {
-    ssl_client_handshaker_factory_destroy(&impl->base);
+    tsi_ssl_client_handshaker_factory_destroy(impl);
     return result;
   }
   SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, NULL);
   /* TODO(jboeuf): Add revocation verification. */
 
-  impl->base.create_handshaker =
-      ssl_client_handshaker_factory_create_handshaker;
-  impl->base.destroy = ssl_client_handshaker_factory_destroy;
-  *factory = &impl->base;
+  *factory = impl;
   return TSI_OK;
 }
 
 tsi_result tsi_create_ssl_server_handshaker_factory(
-    const unsigned char **pem_private_keys,
-    const size_t *pem_private_keys_sizes, const unsigned char **pem_cert_chains,
-    const size_t *pem_cert_chains_sizes, size_t key_cert_pair_count,
-    const unsigned char *pem_client_root_certs,
-    size_t pem_client_root_certs_size, int force_client_auth,
-    const char *cipher_list, const unsigned char **alpn_protocols,
-    const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols,
-    tsi_ssl_handshaker_factory **factory) {
+    const tsi_ssl_pem_key_cert_pair *pem_key_cert_pairs,
+    size_t num_key_cert_pairs, const char *pem_client_root_certs,
+    int force_client_auth, const char *cipher_suites,
+    const char **alpn_protocols, uint16_t num_alpn_protocols,
+    tsi_ssl_server_handshaker_factory **factory) {
   return tsi_create_ssl_server_handshaker_factory_ex(
-      pem_private_keys, pem_private_keys_sizes, pem_cert_chains,
-      pem_cert_chains_sizes, key_cert_pair_count, pem_client_root_certs,
-      pem_client_root_certs_size,
+      pem_key_cert_pairs, num_key_cert_pairs, pem_client_root_certs,
       force_client_auth ? TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
                         : TSI_DONT_REQUEST_CLIENT_CERTIFICATE,
-      cipher_list, alpn_protocols, alpn_protocols_lengths, num_alpn_protocols,
-      factory);
+      cipher_suites, alpn_protocols, num_alpn_protocols, factory);
 }
 
 tsi_result tsi_create_ssl_server_handshaker_factory_ex(
-    const unsigned char **pem_private_keys,
-    const size_t *pem_private_keys_sizes, const unsigned char **pem_cert_chains,
-    const size_t *pem_cert_chains_sizes, size_t key_cert_pair_count,
-    const unsigned char *pem_client_root_certs,
-    size_t pem_client_root_certs_size,
+    const tsi_ssl_pem_key_cert_pair *pem_key_cert_pairs,
+    size_t num_key_cert_pairs, const char *pem_client_root_certs,
     tsi_client_certificate_request_type client_certificate_request,
-    const char *cipher_list, const unsigned char **alpn_protocols,
-    const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols,
-    tsi_ssl_handshaker_factory **factory) {
+    const char *cipher_suites, const char **alpn_protocols,
+    uint16_t num_alpn_protocols, tsi_ssl_server_handshaker_factory **factory) {
   tsi_ssl_server_handshaker_factory *impl = NULL;
   tsi_result result = TSI_OK;
   size_t i = 0;
@@ -1423,36 +1378,32 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
 
   if (factory == NULL) return TSI_INVALID_ARGUMENT;
   *factory = NULL;
-  if (key_cert_pair_count == 0 || pem_private_keys == NULL ||
-      pem_cert_chains == NULL) {
+  if (num_key_cert_pairs == 0 || pem_key_cert_pairs == NULL) {
     return TSI_INVALID_ARGUMENT;
   }
 
   impl = gpr_zalloc(sizeof(*impl));
-  impl->base.create_handshaker =
-      ssl_server_handshaker_factory_create_handshaker;
-  impl->base.destroy = ssl_server_handshaker_factory_destroy;
-  impl->ssl_contexts = gpr_zalloc(key_cert_pair_count * sizeof(SSL_CTX *));
+  impl->ssl_contexts = gpr_zalloc(num_key_cert_pairs * sizeof(SSL_CTX *));
   impl->ssl_context_x509_subject_names =
-      gpr_zalloc(key_cert_pair_count * sizeof(tsi_peer));
+      gpr_zalloc(num_key_cert_pairs * sizeof(tsi_peer));
   if (impl->ssl_contexts == NULL ||
       impl->ssl_context_x509_subject_names == NULL) {
-    tsi_ssl_handshaker_factory_destroy(&impl->base);
+    tsi_ssl_server_handshaker_factory_destroy(impl);
     return TSI_OUT_OF_RESOURCES;
   }
-  impl->ssl_context_count = key_cert_pair_count;
+  impl->ssl_context_count = num_key_cert_pairs;
 
   if (num_alpn_protocols > 0) {
-    result = build_alpn_protocol_name_list(
-        alpn_protocols, alpn_protocols_lengths, num_alpn_protocols,
-        &impl->alpn_protocol_list, &impl->alpn_protocol_list_length);
+    result = build_alpn_protocol_name_list(alpn_protocols, num_alpn_protocols,
+                                           &impl->alpn_protocol_list,
+                                           &impl->alpn_protocol_list_length);
     if (result != TSI_OK) {
-      tsi_ssl_handshaker_factory_destroy(&impl->base);
+      tsi_ssl_server_handshaker_factory_destroy(impl);
       return result;
     }
   }
 
-  for (i = 0; i < key_cert_pair_count; i++) {
+  for (i = 0; i < num_key_cert_pairs; i++) {
     do {
       impl->ssl_contexts[i] = SSL_CTX_new(TLSv1_2_method());
       if (impl->ssl_contexts[i] == NULL) {
@@ -1460,16 +1411,15 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
         result = TSI_OUT_OF_RESOURCES;
         break;
       }
-      result = populate_ssl_context(
-          impl->ssl_contexts[i], pem_private_keys[i], pem_private_keys_sizes[i],
-          pem_cert_chains[i], pem_cert_chains_sizes[i], cipher_list);
+      result = populate_ssl_context(impl->ssl_contexts[i],
+                                    &pem_key_cert_pairs[i], cipher_suites);
       if (result != TSI_OK) break;
 
       if (pem_client_root_certs != NULL) {
         STACK_OF(X509_NAME) *root_names = NULL;
         result = ssl_ctx_load_verification_certs(
             impl->ssl_contexts[i], pem_client_root_certs,
-            pem_client_root_certs_size, &root_names);
+            strlen(pem_client_root_certs), &root_names);
         if (result != TSI_OK) {
           gpr_log(GPR_ERROR, "Invalid verification certs.");
           break;
@@ -1502,7 +1452,7 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
       }
 
       result = extract_x509_subject_names_from_pem_cert(
-          pem_cert_chains[i], pem_cert_chains_sizes[i],
+          pem_key_cert_pairs[i].cert_chain,
           &impl->ssl_context_x509_subject_names[i]);
       if (result != TSI_OK) break;
 
@@ -1520,11 +1470,11 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
     } while (0);
 
     if (result != TSI_OK) {
-      tsi_ssl_handshaker_factory_destroy(&impl->base);
+      tsi_ssl_server_handshaker_factory_destroy(impl);
       return result;
     }
   }
-  *factory = &impl->base;
+  *factory = impl;
   return TSI_OK;
 }
 
diff --git a/src/core/lib/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h
similarity index 50%
rename from src/core/lib/tsi/ssl_transport_security.h
rename to src/core/tsi/ssl_transport_security.h
index 7407246118a883e2dfa12386c89d3a38814fc1bd..3117571d9f7d8ec2f5e6d944480176b80885c422 100644
--- a/src/core/lib/tsi/ssl_transport_security.h
+++ b/src/core/tsi/ssl_transport_security.h
@@ -31,10 +31,10 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_TSI_SSL_TRANSPORT_SECURITY_H
-#define GRPC_CORE_LIB_TSI_SSL_TRANSPORT_SECURITY_H
+#ifndef GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H
+#define GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H
 
-#include "src/core/lib/tsi/transport_security_interface.h"
+#include "src/core/tsi/transport_security_interface.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -52,34 +52,40 @@ extern "C" {
 
 #define TSI_SSL_ALPN_SELECTED_PROTOCOL "ssl_alpn_selected_protocol"
 
-/* --- tsi_ssl_handshaker_factory object ---
+/* --- tsi_ssl_client_handshaker_factory object ---
 
-   This object creates tsi_handshaker objects implemented in terms of the
-   TLS 1.2 specificiation.  */
+   This object creates a client tsi_handshaker objects implemented in terms of
+   the TLS 1.2 specificiation.  */
 
-typedef struct tsi_ssl_handshaker_factory tsi_ssl_handshaker_factory;
+typedef struct tsi_ssl_client_handshaker_factory
+    tsi_ssl_client_handshaker_factory;
+
+/* Object that holds a private key / certificate chain pair in PEM format. */
+typedef struct {
+  /* private_key is the NULL-terminated string containing the PEM encoding of
+     the client's private key. */
+  const char *private_key;
+
+  /* cert_chain is the NULL-terminated string containing the PEM encoding of
+     the client's certificate chain. */
+  const char *cert_chain;
+} tsi_ssl_pem_key_cert_pair;
 
 /* Creates a client handshaker factory.
-   - pem_private_key is the buffer containing the PEM encoding of the client's
-     private key. This parameter can be NULL if the client does not have a
-     private key.
-   - pem_private_key_size is the size of the associated buffer.
-   - pem_cert_chain is the buffer containing the PEM encoding of the client's
-     certificate chain. This parameter can be NULL if the client does not have
-     a certificate chain.
-   - pem_cert_chain_size is the size of the associated buffer.
-   - pem_roots_cert is the buffer containing the PEM encoding of the server
-     root certificates. This parameter cannot be NULL.
-   - pem_roots_cert_size is the size of the associated buffer.
+   - pem_key_cert_pair is a pointer to the object containing client's private
+     key and certificate chain. This parameter can be NULL if the client does
+     not have such a key/cert pair.
+   - pem_roots_cert is the NULL-terminated string containing the PEM encoding of
+     the client root certificates. This parameter may be NULL if the server does
+     not want the client to be authenticated with SSL.
    - cipher_suites contains an optional list of the ciphers that the client
      supports. The format of this string is described in:
      https://www.openssl.org/docs/apps/ciphers.html.
      This parameter can be set to NULL to use the default set of ciphers.
      TODO(jboeuf): Revisit the format of this parameter.
-   - alpn_protocols is an array containing the protocol names that the
-     handshakers created with this factory support. This parameter can be NULL.
-   - alpn_protocols_lengths is an array containing the lengths of the alpn
-     protocols specified in alpn_protocols. This parameter can be NULL.
+   - alpn_protocols is an array containing the NULL terminated protocol names
+     that the handshakers created with this factory support. This parameter can
+     be NULL.
    - num_alpn_protocols is the number of alpn protocols and associated lengths
      specified. If this parameter is 0, the other alpn parameters must be NULL.
    - factory is the address of the factory pointer to be created.
@@ -87,45 +93,51 @@ typedef struct tsi_ssl_handshaker_factory tsi_ssl_handshaker_factory;
    - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
      where a parameter is invalid.  */
 tsi_result tsi_create_ssl_client_handshaker_factory(
-    const unsigned char *pem_private_key, size_t pem_private_key_size,
-    const unsigned char *pem_cert_chain, size_t pem_cert_chain_size,
-    const unsigned char *pem_root_certs, size_t pem_root_certs_size,
-    const char *cipher_suites, const unsigned char **alpn_protocols,
-    const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols,
-    tsi_ssl_handshaker_factory **factory);
+    const tsi_ssl_pem_key_cert_pair *pem_key_cert_pair,
+    const char *pem_root_certs, const char *cipher_suites,
+    const char **alpn_protocols, uint16_t num_alpn_protocols,
+    tsi_ssl_client_handshaker_factory **factory);
+
+/* Creates a client handshaker.
+  - self is the factory from which the handshaker will be created.
+  - server_name_indication indicates the name of the server the client is
+    trying to connect to which will be relayed to the server using the SNI
+    extension.
+  - handshaker is the address of the handshaker pointer to be created.
+
+  - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
+    where a parameter is invalid.  */
+tsi_result tsi_ssl_client_handshaker_factory_create_handshaker(
+    tsi_ssl_client_handshaker_factory *self, const char *server_name_indication,
+    tsi_handshaker **handshaker);
+
+/* Destroys the handshaker factory. WARNING: it is unsafe to destroy a factory
+   while handshakers created with this factory are still in use.  */
+void tsi_ssl_client_handshaker_factory_destroy(
+    tsi_ssl_client_handshaker_factory *self);
+
+/* --- tsi_ssl_server_handshaker_factory object ---
+
+   This object creates a client tsi_handshaker objects implemented in terms of
+   the TLS 1.2 specificiation.  */
+
+typedef struct tsi_ssl_server_handshaker_factory
+    tsi_ssl_server_handshaker_factory;
 
 /* Creates a server handshaker factory.
-   - version indicates which version of the specification to use.
-   - pem_private_keys is an array containing the PEM encoding of the server's
-     private keys.  This parameter cannot be NULL. The size of the array is
-     given by the key_cert_pair_count parameter.
-   - pem_private_keys_sizes is the array containing the sizes of the associated
-     buffers.
-   - pem_cert_chains is an array containing the PEM encoding of the server's
-     cert chains.  This parameter cannot be NULL. The size of the array is
-     given by the key_cert_pair_count parameter.
-   - pem_cert_chains_sizes is the array containing the sizes of the associated
-     buffers.
-   - key_cert_pair_count indicates the number of items in the private_key_files
-     and cert_chain_files parameters.
-   - pem_client_roots is the buffer containing the PEM encoding of the client
-     root certificates. This parameter may be NULL in which case the server will
-     not authenticate the client. If not NULL, the force_client_auth parameter
-     specifies if the server will accept only authenticated clients or both
-     authenticated and non-authenticated clients.
-   - pem_client_root_certs_size is the size of the associated buffer.
-   - force_client_auth, if set to non-zero will force the client to authenticate
-     with an SSL cert. Note that this option is ignored if pem_client_root_certs
-     is NULL or pem_client_roots_certs_size is 0
+   - pem_key_cert_pairs is an array private key / certificate chains of the
+     server.
+   - num_key_cert_pairs is the number of items in the pem_key_cert_pairs array.
+   - pem_root_certs is the NULL-terminated string containing the PEM encoding
+     of the server root certificates.
    - cipher_suites contains an optional list of the ciphers that the server
      supports. The format of this string is described in:
      https://www.openssl.org/docs/apps/ciphers.html.
      This parameter can be set to NULL to use the default set of ciphers.
      TODO(jboeuf): Revisit the format of this parameter.
-   - alpn_protocols is an array containing the protocol names that the
-     handshakers created with this factory support. This parameter can be NULL.
-   - alpn_protocols_lengths is an array containing the lengths of the alpn
-     protocols specified in alpn_protocols. This parameter can be NULL.
+   - alpn_protocols is an array containing the NULL terminated protocol names
+     that the handshakers created with this factory support. This parameter can
+     be NULL.
    - num_alpn_protocols is the number of alpn protocols and associated lengths
      specified. If this parameter is 0, the other alpn parameters must be NULL.
    - factory is the address of the factory pointer to be created.
@@ -133,14 +145,11 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
    - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
      where a parameter is invalid.  */
 tsi_result tsi_create_ssl_server_handshaker_factory(
-    const unsigned char **pem_private_keys,
-    const size_t *pem_private_keys_sizes, const unsigned char **pem_cert_chains,
-    const size_t *pem_cert_chains_sizes, size_t key_cert_pair_count,
-    const unsigned char *pem_client_root_certs,
-    size_t pem_client_root_certs_size, int force_client_auth,
-    const char *cipher_suites, const unsigned char **alpn_protocols,
-    const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols,
-    tsi_ssl_handshaker_factory **factory);
+    const tsi_ssl_pem_key_cert_pair *pem_key_cert_pairs,
+    size_t num_key_cert_pairs, const char *pem_client_root_certs,
+    int force_client_auth, const char *cipher_suites,
+    const char **alpn_protocols, uint16_t num_alpn_protocols,
+    tsi_ssl_server_handshaker_factory **factory);
 
 /* Same as tsi_create_ssl_server_handshaker_factory method except uses
    tsi_client_certificate_request_type to support more ways to handle client
@@ -149,33 +158,25 @@ tsi_result tsi_create_ssl_server_handshaker_factory(
      authenticate with an SSL cert. Note that this option is ignored if
      pem_client_root_certs is NULL or pem_client_roots_certs_size is 0 */
 tsi_result tsi_create_ssl_server_handshaker_factory_ex(
-    const unsigned char **pem_private_keys,
-    const size_t *pem_private_keys_sizes, const unsigned char **pem_cert_chains,
-    const size_t *pem_cert_chains_sizes, size_t key_cert_pair_count,
-    const unsigned char *pem_client_root_certs,
-    size_t pem_client_root_certs_size,
+    const tsi_ssl_pem_key_cert_pair *pem_key_cert_pairs,
+    size_t num_key_cert_pairs, const char *pem_client_root_certs,
     tsi_client_certificate_request_type client_certificate_request,
-    const char *cipher_suites, const unsigned char **alpn_protocols,
-    const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols,
-    tsi_ssl_handshaker_factory **factory);
+    const char *cipher_suites, const char **alpn_protocols,
+    uint16_t num_alpn_protocols, tsi_ssl_server_handshaker_factory **factory);
 
-/* Creates a handshaker.
+/* Creates a server handshaker.
   - self is the factory from which the handshaker will be created.
-  - server_name_indication indicates the name of the server the client is
-    trying to connect to which will be relayed to the server using the SNI
-    extension.
-    This parameter must be NULL for a server handshaker factory.
-  - handhshaker is the address of the handshaker pointer to be created.
+  - handshaker is the address of the handshaker pointer to be created.
 
   - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
     where a parameter is invalid.  */
-tsi_result tsi_ssl_handshaker_factory_create_handshaker(
-    tsi_ssl_handshaker_factory *self, const char *server_name_indication,
-    tsi_handshaker **handshaker);
+tsi_result tsi_ssl_server_handshaker_factory_create_handshaker(
+    tsi_ssl_server_handshaker_factory *self, tsi_handshaker **handshaker);
 
 /* Destroys the handshaker factory. WARNING: it is unsafe to destroy a factory
    while handshakers created with this factory are still in use.  */
-void tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory *self);
+void tsi_ssl_server_handshaker_factory_destroy(
+    tsi_ssl_server_handshaker_factory *self);
 
 /* Util that checks that an ssl peer matches a specific name.
    Still TODO(jboeuf):
@@ -188,4 +189,4 @@ int tsi_ssl_peer_matches_name(const tsi_peer *peer, const char *name);
 }
 #endif
 
-#endif /* GRPC_CORE_LIB_TSI_SSL_TRANSPORT_SECURITY_H */
+#endif /* GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H */
diff --git a/src/core/lib/tsi/ssl_types.h b/src/core/tsi/ssl_types.h
similarity index 94%
rename from src/core/lib/tsi/ssl_types.h
rename to src/core/tsi/ssl_types.h
index 0a988effd0f3a66c4d43b93b74b0d30cd002fe88..065cb868000de7aa9350aa1efbebc1a75702c7fd 100644
--- a/src/core/lib/tsi/ssl_types.h
+++ b/src/core/tsi/ssl_types.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_TSI_SSL_TYPES_H
-#define GRPC_CORE_LIB_TSI_SSL_TYPES_H
+#ifndef GRPC_CORE_TSI_SSL_TYPES_H
+#define GRPC_CORE_TSI_SSL_TYPES_H
 
 /* A collection of macros to cast between various integer types that are
  * used differently between BoringSSL and OpenSSL:
@@ -52,4 +52,4 @@
 #define TSI_SIZE_AS_SIZE(x) ((int)(x))
 #endif
 
-#endif /* GRPC_CORE_LIB_TSI_SSL_TYPES_H */
+#endif /* GRPC_CORE_TSI_SSL_TYPES_H */
diff --git a/src/core/lib/tsi/test_creds/BUILD b/src/core/tsi/test_creds/BUILD
similarity index 100%
rename from src/core/lib/tsi/test_creds/BUILD
rename to src/core/tsi/test_creds/BUILD
diff --git a/src/core/lib/tsi/test_creds/README b/src/core/tsi/test_creds/README
similarity index 100%
rename from src/core/lib/tsi/test_creds/README
rename to src/core/tsi/test_creds/README
diff --git a/src/core/lib/tsi/test_creds/badclient.key b/src/core/tsi/test_creds/badclient.key
similarity index 100%
rename from src/core/lib/tsi/test_creds/badclient.key
rename to src/core/tsi/test_creds/badclient.key
diff --git a/src/core/lib/tsi/test_creds/badclient.pem b/src/core/tsi/test_creds/badclient.pem
similarity index 100%
rename from src/core/lib/tsi/test_creds/badclient.pem
rename to src/core/tsi/test_creds/badclient.pem
diff --git a/src/core/lib/tsi/test_creds/badserver.key b/src/core/tsi/test_creds/badserver.key
similarity index 100%
rename from src/core/lib/tsi/test_creds/badserver.key
rename to src/core/tsi/test_creds/badserver.key
diff --git a/src/core/lib/tsi/test_creds/badserver.pem b/src/core/tsi/test_creds/badserver.pem
similarity index 100%
rename from src/core/lib/tsi/test_creds/badserver.pem
rename to src/core/tsi/test_creds/badserver.pem
diff --git a/src/core/lib/tsi/test_creds/ca-openssl.cnf b/src/core/tsi/test_creds/ca-openssl.cnf
similarity index 100%
rename from src/core/lib/tsi/test_creds/ca-openssl.cnf
rename to src/core/tsi/test_creds/ca-openssl.cnf
diff --git a/src/core/lib/tsi/test_creds/ca.key b/src/core/tsi/test_creds/ca.key
similarity index 100%
rename from src/core/lib/tsi/test_creds/ca.key
rename to src/core/tsi/test_creds/ca.key
diff --git a/src/core/lib/tsi/test_creds/ca.pem b/src/core/tsi/test_creds/ca.pem
similarity index 100%
rename from src/core/lib/tsi/test_creds/ca.pem
rename to src/core/tsi/test_creds/ca.pem
diff --git a/src/core/lib/tsi/test_creds/client.key b/src/core/tsi/test_creds/client.key
similarity index 100%
rename from src/core/lib/tsi/test_creds/client.key
rename to src/core/tsi/test_creds/client.key
diff --git a/src/core/lib/tsi/test_creds/client.pem b/src/core/tsi/test_creds/client.pem
similarity index 100%
rename from src/core/lib/tsi/test_creds/client.pem
rename to src/core/tsi/test_creds/client.pem
diff --git a/src/core/lib/tsi/test_creds/server0.key b/src/core/tsi/test_creds/server0.key
similarity index 100%
rename from src/core/lib/tsi/test_creds/server0.key
rename to src/core/tsi/test_creds/server0.key
diff --git a/src/core/lib/tsi/test_creds/server0.pem b/src/core/tsi/test_creds/server0.pem
similarity index 100%
rename from src/core/lib/tsi/test_creds/server0.pem
rename to src/core/tsi/test_creds/server0.pem
diff --git a/src/core/lib/tsi/test_creds/server1-openssl.cnf b/src/core/tsi/test_creds/server1-openssl.cnf
similarity index 100%
rename from src/core/lib/tsi/test_creds/server1-openssl.cnf
rename to src/core/tsi/test_creds/server1-openssl.cnf
diff --git a/src/core/lib/tsi/test_creds/server1.key b/src/core/tsi/test_creds/server1.key
similarity index 100%
rename from src/core/lib/tsi/test_creds/server1.key
rename to src/core/tsi/test_creds/server1.key
diff --git a/src/core/lib/tsi/test_creds/server1.pem b/src/core/tsi/test_creds/server1.pem
similarity index 100%
rename from src/core/lib/tsi/test_creds/server1.pem
rename to src/core/tsi/test_creds/server1.pem
diff --git a/src/core/lib/tsi/transport_security.c b/src/core/tsi/transport_security.c
similarity index 74%
rename from src/core/lib/tsi/transport_security.c
rename to src/core/tsi/transport_security.c
index 2cbf381c88d6bd5fa92d40c5b1158e453e345787..b11c00c43c43434c21012fceed7f623ad59902f8 100644
--- a/src/core/lib/tsi/transport_security.c
+++ b/src/core/tsi/transport_security.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/lib/tsi/transport_security.h"
+#include "src/core/tsi/transport_security.h"
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
@@ -73,6 +73,8 @@ const char *tsi_result_to_string(tsi_result result) {
       return "TSI_HANDSHAKE_IN_PROGRESS";
     case TSI_OUT_OF_RESOURCES:
       return "TSI_OUT_OF_RESOURCES";
+    case TSI_ASYNC:
+      return "TSI_ASYNC";
     default:
       return "UNKNOWN";
   }
@@ -92,6 +94,9 @@ tsi_result tsi_frame_protector_protect(tsi_frame_protector *self,
       protected_output_frames_size == NULL) {
     return TSI_INVALID_ARGUMENT;
   }
+  if (self->vtable == NULL || self->vtable->protect == NULL) {
+    return TSI_UNIMPLEMENTED;
+  }
   return self->vtable->protect(self, unprotected_bytes, unprotected_bytes_size,
                                protected_output_frames,
                                protected_output_frames_size);
@@ -101,9 +106,12 @@ tsi_result tsi_frame_protector_protect_flush(
     tsi_frame_protector *self, unsigned char *protected_output_frames,
     size_t *protected_output_frames_size, size_t *still_pending_size) {
   if (self == NULL || protected_output_frames == NULL ||
-      protected_output_frames == NULL || still_pending_size == NULL) {
+      protected_output_frames_size == NULL || still_pending_size == NULL) {
     return TSI_INVALID_ARGUMENT;
   }
+  if (self->vtable == NULL || self->vtable->protect_flush == NULL) {
+    return TSI_UNIMPLEMENTED;
+  }
   return self->vtable->protect_flush(self, protected_output_frames,
                                      protected_output_frames_size,
                                      still_pending_size);
@@ -118,6 +126,9 @@ tsi_result tsi_frame_protector_unprotect(
       unprotected_bytes_size == NULL) {
     return TSI_INVALID_ARGUMENT;
   }
+  if (self->vtable == NULL || self->vtable->unprotect == NULL) {
+    return TSI_UNIMPLEMENTED;
+  }
   return self->vtable->unprotect(self, protected_frames_bytes,
                                  protected_frames_bytes_size, unprotected_bytes,
                                  unprotected_bytes_size);
@@ -139,6 +150,9 @@ tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self,
     return TSI_INVALID_ARGUMENT;
   }
   if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
+  if (self->vtable == NULL || self->vtable->get_bytes_to_send_to_peer == NULL) {
+    return TSI_UNIMPLEMENTED;
+  }
   return self->vtable->get_bytes_to_send_to_peer(self, bytes, bytes_size);
 }
 
@@ -149,12 +163,18 @@ tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker *self,
     return TSI_INVALID_ARGUMENT;
   }
   if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
+  if (self->vtable == NULL || self->vtable->process_bytes_from_peer == NULL) {
+    return TSI_UNIMPLEMENTED;
+  }
   return self->vtable->process_bytes_from_peer(self, bytes, bytes_size);
 }
 
 tsi_result tsi_handshaker_get_result(tsi_handshaker *self) {
   if (self == NULL) return TSI_INVALID_ARGUMENT;
   if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
+  if (self->vtable == NULL || self->vtable->get_result == NULL) {
+    return TSI_UNIMPLEMENTED;
+  }
   return self->vtable->get_result(self);
 }
 
@@ -165,6 +185,9 @@ tsi_result tsi_handshaker_extract_peer(tsi_handshaker *self, tsi_peer *peer) {
   if (tsi_handshaker_get_result(self) != TSI_OK) {
     return TSI_FAILED_PRECONDITION;
   }
+  if (self->vtable == NULL || self->vtable->extract_peer == NULL) {
+    return TSI_UNIMPLEMENTED;
+  }
   return self->vtable->extract_peer(self, peer);
 }
 
@@ -177,19 +200,77 @@ tsi_result tsi_handshaker_create_frame_protector(
   if (tsi_handshaker_get_result(self) != TSI_OK) {
     return TSI_FAILED_PRECONDITION;
   }
+  if (self->vtable == NULL || self->vtable->create_frame_protector == NULL) {
+    return TSI_UNIMPLEMENTED;
+  }
   result = self->vtable->create_frame_protector(self, max_protected_frame_size,
                                                 protector);
   if (result == TSI_OK) {
-    self->frame_protector_created = 1;
+    self->frame_protector_created = true;
   }
   return result;
 }
 
+tsi_result tsi_handshaker_next(
+    tsi_handshaker *self, const unsigned char *received_bytes,
+    size_t received_bytes_size, unsigned char **bytes_to_send,
+    size_t *bytes_to_send_size, tsi_handshaker_result **handshaker_result,
+    tsi_handshaker_on_next_done_cb cb, void *user_data) {
+  if (self == NULL) return TSI_INVALID_ARGUMENT;
+  if (self->handshaker_result_created) return TSI_FAILED_PRECONDITION;
+  if (self->vtable == NULL || self->vtable->next == NULL) {
+    return TSI_UNIMPLEMENTED;
+  }
+  return self->vtable->next(self, received_bytes, received_bytes_size,
+                            bytes_to_send, bytes_to_send_size,
+                            handshaker_result, cb, user_data);
+}
+
 void tsi_handshaker_destroy(tsi_handshaker *self) {
   if (self == NULL) return;
   self->vtable->destroy(self);
 }
 
+/* --- tsi_handshaker_result implementation. --- */
+
+tsi_result tsi_handshaker_result_extract_peer(const tsi_handshaker_result *self,
+                                              tsi_peer *peer) {
+  if (self == NULL || peer == NULL) return TSI_INVALID_ARGUMENT;
+  memset(peer, 0, sizeof(tsi_peer));
+  if (self->vtable == NULL || self->vtable->extract_peer == NULL) {
+    return TSI_UNIMPLEMENTED;
+  }
+  return self->vtable->extract_peer(self, peer);
+}
+
+tsi_result tsi_handshaker_result_create_frame_protector(
+    const tsi_handshaker_result *self, size_t *max_protected_frame_size,
+    tsi_frame_protector **protector) {
+  if (self == NULL || protector == NULL) return TSI_INVALID_ARGUMENT;
+  if (self->vtable == NULL || self->vtable->create_frame_protector == NULL) {
+    return TSI_UNIMPLEMENTED;
+  }
+  return self->vtable->create_frame_protector(self, max_protected_frame_size,
+                                              protector);
+}
+
+tsi_result tsi_handshaker_result_get_unused_bytes(
+    const tsi_handshaker_result *self, unsigned char **bytes,
+    size_t *bytes_size) {
+  if (self == NULL || bytes == NULL || bytes_size == NULL) {
+    return TSI_INVALID_ARGUMENT;
+  }
+  if (self->vtable == NULL || self->vtable->get_unused_bytes == NULL) {
+    return TSI_UNIMPLEMENTED;
+  }
+  return self->vtable->get_unused_bytes(self, bytes, bytes_size);
+}
+
+void tsi_handshaker_result_destroy(tsi_handshaker_result *self) {
+  if (self == NULL) return;
+  self->vtable->destroy(self);
+}
+
 /* --- tsi_peer implementation. --- */
 
 tsi_peer_property tsi_init_peer_property(void) {
diff --git a/src/core/lib/tsi/transport_security.h b/src/core/tsi/transport_security.h
similarity index 77%
rename from src/core/lib/tsi/transport_security.h
rename to src/core/tsi/transport_security.h
index aaf110ee0537891be32e02f3f615229a2461fb08..a4c9cbc00111e68238cb87ac38968f694796b2b2 100644
--- a/src/core/lib/tsi/transport_security.h
+++ b/src/core/tsi/transport_security.h
@@ -31,10 +31,12 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_H
-#define GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_H
+#ifndef GRPC_CORE_TSI_TRANSPORT_SECURITY_H
+#define GRPC_CORE_TSI_TRANSPORT_SECURITY_H
 
-#include "src/core/lib/tsi/transport_security_interface.h"
+#include <stdbool.h>
+
+#include "src/core/tsi/transport_security_interface.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -81,11 +83,33 @@ typedef struct {
                                        size_t *max_protected_frame_size,
                                        tsi_frame_protector **protector);
   void (*destroy)(tsi_handshaker *self);
+  tsi_result (*next)(tsi_handshaker *self, const unsigned char *received_bytes,
+                     size_t received_bytes_size, unsigned char **bytes_to_send,
+                     size_t *bytes_to_send_size,
+                     tsi_handshaker_result **handshaker_result,
+                     tsi_handshaker_on_next_done_cb cb, void *user_data);
 } tsi_handshaker_vtable;
 
 struct tsi_handshaker {
   const tsi_handshaker_vtable *vtable;
-  int frame_protector_created;
+  bool frame_protector_created;
+  bool handshaker_result_created;
+};
+
+/* Base for tsi_handshaker_result implementations.
+   See transport_security_interface.h for documentation. */
+typedef struct {
+  tsi_result (*extract_peer)(const tsi_handshaker_result *self, tsi_peer *peer);
+  tsi_result (*create_frame_protector)(const tsi_handshaker_result *self,
+                                       size_t *max_output_protected_frame_size,
+                                       tsi_frame_protector **protector);
+  tsi_result (*get_unused_bytes)(const tsi_handshaker_result *self,
+                                 unsigned char **bytes, size_t *bytes_size);
+  void (*destroy)(tsi_handshaker_result *self);
+} tsi_handshaker_result_vtable;
+
+struct tsi_handshaker_result {
+  const tsi_handshaker_result_vtable *vtable;
 };
 
 /* Peer and property construction/destruction functions. */
@@ -108,4 +132,4 @@ char *tsi_strdup(const char *src); /* Sadly, no strdup in C89. */
 }
 #endif
 
-#endif /* GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_H */
+#endif /* GRPC_CORE_TSI_TRANSPORT_SECURITY_H */
diff --git a/src/core/tsi/transport_security_adapter.c b/src/core/tsi/transport_security_adapter.c
new file mode 100644
index 0000000000000000000000000000000000000000..9f2147b53017376b6148d269166f04436558bf5a
--- /dev/null
+++ b/src/core/tsi/transport_security_adapter.c
@@ -0,0 +1,236 @@
+/*
+ *
+ * Copyright 2017, 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/tsi/transport_security_adapter.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include "src/core/tsi/transport_security.h"
+
+#define TSI_ADAPTER_INITIAL_BUFFER_SIZE 256
+
+/* --- tsi_adapter_handshaker_result implementation ---*/
+
+typedef struct {
+  tsi_handshaker_result base;
+  tsi_handshaker *wrapped;
+  unsigned char *unused_bytes;
+  size_t unused_bytes_size;
+} tsi_adapter_handshaker_result;
+
+static tsi_result adapter_result_extract_peer(const tsi_handshaker_result *self,
+                                              tsi_peer *peer) {
+  tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self;
+  return tsi_handshaker_extract_peer(impl->wrapped, peer);
+}
+
+static tsi_result adapter_result_create_frame_protector(
+    const tsi_handshaker_result *self, size_t *max_output_protected_frame_size,
+    tsi_frame_protector **protector) {
+  tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self;
+  return tsi_handshaker_create_frame_protector(
+      impl->wrapped, max_output_protected_frame_size, protector);
+}
+
+static tsi_result adapter_result_get_unused_bytes(
+    const tsi_handshaker_result *self, unsigned char **bytes,
+    size_t *byte_size) {
+  tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self;
+  *bytes = impl->unused_bytes;
+  *byte_size = impl->unused_bytes_size;
+  return TSI_OK;
+}
+
+static void adapter_result_destroy(tsi_handshaker_result *self) {
+  tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self;
+  tsi_handshaker_destroy(impl->wrapped);
+  gpr_free(impl->unused_bytes);
+  gpr_free(self);
+}
+
+static const tsi_handshaker_result_vtable result_vtable = {
+    adapter_result_extract_peer, adapter_result_create_frame_protector,
+    adapter_result_get_unused_bytes, adapter_result_destroy,
+};
+
+/* Ownership of wrapped tsi_handshaker is transferred to the result object.  */
+static tsi_result tsi_adapter_create_handshaker_result(
+    tsi_handshaker *wrapped, const unsigned char *unused_bytes,
+    size_t unused_bytes_size, tsi_handshaker_result **handshaker_result) {
+  if (wrapped == NULL || (unused_bytes_size > 0 && unused_bytes == NULL)) {
+    return TSI_INVALID_ARGUMENT;
+  }
+  tsi_adapter_handshaker_result *impl = gpr_zalloc(sizeof(*impl));
+  impl->base.vtable = &result_vtable;
+  impl->wrapped = wrapped;
+  impl->unused_bytes_size = unused_bytes_size;
+  if (unused_bytes_size > 0) {
+    impl->unused_bytes = gpr_malloc(unused_bytes_size);
+    memcpy(impl->unused_bytes, unused_bytes, unused_bytes_size);
+  } else {
+    impl->unused_bytes = NULL;
+  }
+  *handshaker_result = &impl->base;
+  return TSI_OK;
+}
+
+/* --- tsi_adapter_handshaker implementation ---*/
+
+typedef struct {
+  tsi_handshaker base;
+  tsi_handshaker *wrapped;
+  unsigned char *adapter_buffer;
+  size_t adapter_buffer_size;
+} tsi_adapter_handshaker;
+
+static tsi_result adapter_get_bytes_to_send_to_peer(tsi_handshaker *self,
+                                                    unsigned char *bytes,
+                                                    size_t *bytes_size) {
+  return tsi_handshaker_get_bytes_to_send_to_peer(
+      tsi_adapter_handshaker_get_wrapped(self), bytes, bytes_size);
+}
+
+static tsi_result adapter_process_bytes_from_peer(tsi_handshaker *self,
+                                                  const unsigned char *bytes,
+                                                  size_t *bytes_size) {
+  return tsi_handshaker_process_bytes_from_peer(
+      tsi_adapter_handshaker_get_wrapped(self), bytes, bytes_size);
+}
+
+static tsi_result adapter_get_result(tsi_handshaker *self) {
+  return tsi_handshaker_get_result(tsi_adapter_handshaker_get_wrapped(self));
+}
+
+static tsi_result adapter_extract_peer(tsi_handshaker *self, tsi_peer *peer) {
+  return tsi_handshaker_extract_peer(tsi_adapter_handshaker_get_wrapped(self),
+                                     peer);
+}
+
+static tsi_result adapter_create_frame_protector(
+    tsi_handshaker *self, size_t *max_protected_frame_size,
+    tsi_frame_protector **protector) {
+  return tsi_handshaker_create_frame_protector(
+      tsi_adapter_handshaker_get_wrapped(self), max_protected_frame_size,
+      protector);
+}
+
+static void adapter_destroy(tsi_handshaker *self) {
+  tsi_adapter_handshaker *impl = (tsi_adapter_handshaker *)self;
+  tsi_handshaker_destroy(impl->wrapped);
+  gpr_free(impl->adapter_buffer);
+  gpr_free(self);
+}
+
+static tsi_result adapter_next(
+    tsi_handshaker *self, const unsigned char *received_bytes,
+    size_t received_bytes_size, unsigned char **bytes_to_send,
+    size_t *bytes_to_send_size, tsi_handshaker_result **handshaker_result,
+    tsi_handshaker_on_next_done_cb cb, void *user_data) {
+  /* Input sanity check.  */
+  if ((received_bytes_size > 0 && received_bytes == NULL) ||
+      bytes_to_send == NULL || bytes_to_send_size == NULL ||
+      handshaker_result == NULL) {
+    return TSI_INVALID_ARGUMENT;
+  }
+
+  /* If there are received bytes, process them first.  */
+  tsi_adapter_handshaker *impl = (tsi_adapter_handshaker *)self;
+  tsi_result status = TSI_OK;
+  size_t bytes_consumed = received_bytes_size;
+  if (received_bytes_size > 0) {
+    status = tsi_handshaker_process_bytes_from_peer(
+        impl->wrapped, received_bytes, &bytes_consumed);
+    if (status != TSI_OK) return status;
+  }
+
+  /* Get bytes to send to the peer, if available.  */
+  size_t offset = 0;
+  do {
+    size_t to_send_size = impl->adapter_buffer_size - offset;
+    status = tsi_handshaker_get_bytes_to_send_to_peer(
+        impl->wrapped, impl->adapter_buffer + offset, &to_send_size);
+    offset += to_send_size;
+    if (status == TSI_INCOMPLETE_DATA) {
+      impl->adapter_buffer_size *= 2;
+      impl->adapter_buffer =
+          gpr_realloc(impl->adapter_buffer, impl->adapter_buffer_size);
+    }
+  } while (status == TSI_INCOMPLETE_DATA);
+  if (status != TSI_OK) return status;
+  *bytes_to_send = impl->adapter_buffer;
+  *bytes_to_send_size = offset;
+
+  /* If handshake completes, create tsi_handshaker_result.  */
+  if (tsi_handshaker_is_in_progress(impl->wrapped)) {
+    *handshaker_result = NULL;
+  } else {
+    size_t unused_bytes_size = received_bytes_size - bytes_consumed;
+    const unsigned char *unused_bytes =
+        unused_bytes_size == 0 ? NULL : received_bytes + bytes_consumed;
+    status = tsi_adapter_create_handshaker_result(
+        impl->wrapped, unused_bytes, unused_bytes_size, handshaker_result);
+    if (status == TSI_OK) {
+      impl->base.handshaker_result_created = true;
+      impl->wrapped = NULL;
+    }
+  }
+  return status;
+}
+
+static const tsi_handshaker_vtable handshaker_vtable = {
+    adapter_get_bytes_to_send_to_peer,
+    adapter_process_bytes_from_peer,
+    adapter_get_result,
+    adapter_extract_peer,
+    adapter_create_frame_protector,
+    adapter_destroy,
+    adapter_next,
+};
+
+tsi_handshaker *tsi_create_adapter_handshaker(tsi_handshaker *wrapped) {
+  GPR_ASSERT(wrapped != NULL);
+  tsi_adapter_handshaker *impl = gpr_zalloc(sizeof(*impl));
+  impl->base.vtable = &handshaker_vtable;
+  impl->wrapped = wrapped;
+  impl->adapter_buffer_size = TSI_ADAPTER_INITIAL_BUFFER_SIZE;
+  impl->adapter_buffer = gpr_malloc(impl->adapter_buffer_size);
+  return &impl->base;
+}
+
+tsi_handshaker *tsi_adapter_handshaker_get_wrapped(tsi_handshaker *adapter) {
+  if (adapter == NULL) return NULL;
+  tsi_adapter_handshaker *impl = (tsi_adapter_handshaker *)adapter;
+  return impl->wrapped;
+}
diff --git a/src/core/tsi/transport_security_adapter.h b/src/core/tsi/transport_security_adapter.h
new file mode 100644
index 0000000000000000000000000000000000000000..400df2f11bdb90e5d1ca63bb33d62100ff75f616
--- /dev/null
+++ b/src/core/tsi/transport_security_adapter.h
@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright 2017, 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_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H
+#define GRPC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H
+
+#include "src/core/tsi/transport_security_interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Create a tsi handshaker that takes an implementation of old interface and
+   converts into an implementation of new interface. In the old interface,
+   there are get_bytes_to_send_to_peer, process_bytes_from_peer, get_result,
+   extract_peer, and create_frame_protector. In the new interface, only next
+   method is needed. See transport_security_interface.h for details. Note that
+   this tsi adapter handshaker is temporary. It will be removed once TSI has
+   been fully migrated to the new interface.
+   Ownership of input tsi_handshaker is transferred to this new adapter.  */
+tsi_handshaker *tsi_create_adapter_handshaker(tsi_handshaker *wrapped);
+
+/* Given a tsi adapter handshaker, return the original wrapped handshaker. The
+   adapter still owns the wrapped handshaker which should not be destroyed by
+   the caller. */
+tsi_handshaker *tsi_adapter_handshaker_get_wrapped(tsi_handshaker *adapter);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H */
diff --git a/src/core/lib/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h
similarity index 60%
rename from src/core/lib/tsi/transport_security_interface.h
rename to src/core/tsi/transport_security_interface.h
index 3e8c9d7ffefc6a27a5c267951b4dd804b44fd1a4..f2112b62b6764e29dec1bcaee1b1425d50636d4c 100644
--- a/src/core/lib/tsi/transport_security_interface.h
+++ b/src/core/tsi/transport_security_interface.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_INTERFACE_H
-#define GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_INTERFACE_H
+#ifndef GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H
+#define GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H
 
 #include <stdint.h>
 #include <stdlib.h>
@@ -56,7 +56,8 @@ typedef enum {
   TSI_NOT_FOUND = 9,
   TSI_PROTOCOL_FAILURE = 10,
   TSI_HANDSHAKE_IN_PROGRESS = 11,
-  TSI_OUT_OF_RESOURCES = 12
+  TSI_OUT_OF_RESOURCES = 12,
+  TSI_ASYNC = 13
 } tsi_result;
 
 typedef enum {
@@ -208,76 +209,138 @@ typedef struct {
 /* Destructs the tsi_peer object. */
 void tsi_peer_destruct(tsi_peer *self);
 
+/*  --- tsi_handshaker_result object ---
+
+  This object contains all necessary handshake results and data such as peer
+  info, negotiated keys, unused handshake bytes, when the handshake completes.
+  Implementations of this object must be thread compatible.  */
+
+typedef struct tsi_handshaker_result tsi_handshaker_result;
+
+/* This method extracts tsi peer. It returns TSI_OK assuming there is no fatal
+   error.
+   The caller is responsible for destructing the peer.  */
+tsi_result tsi_handshaker_result_extract_peer(const tsi_handshaker_result *self,
+                                              tsi_peer *peer);
+
+/* This method creates a tsi_frame_protector object. It returns TSI_OK assuming
+   there is no fatal error.
+   The caller is responsible for destroying the protector.  */
+tsi_result tsi_handshaker_result_create_frame_protector(
+    const tsi_handshaker_result *self, size_t *max_output_protected_frame_size,
+    tsi_frame_protector **protector);
+
+/* This method returns the unused bytes from the handshake. It returns TSI_OK
+   assuming there is no fatal error.
+   Ownership of the bytes is retained by the handshaker result. As a
+   consequence, the caller must not free the bytes.  */
+tsi_result tsi_handshaker_result_get_unused_bytes(
+    const tsi_handshaker_result *self, unsigned char **bytes,
+    size_t *byte_size);
+
+/* This method releases the tsi_handshaker_handshaker object. After this method
+   is called, no other method can be called on the object.  */
+void tsi_handshaker_result_destroy(tsi_handshaker_result *self);
+
 /* --- tsi_handshaker objects ----
 
    Implementations of this object must be thread compatible.
 
-   A typical usage of this object would be:
+   ------------------------------------------------------------------------
+
+   A typical usage supporting both synchronous and asynchronous TSI handshaker
+   implementations would be:
 
    ------------------------------------------------------------------------
-   tsi_result result = TSI_OK;
-   unsigned char buf[4096];
-   size_t buf_offset;
-   size_t buf_size;
-   while (1) {
-     // See if we need to send some bytes to the peer.
-     do {
-       size_t buf_size_to_send = sizeof(buf);
-       result = tsi_handshaker_get_bytes_to_send_to_peer(handshaker, buf,
-                                                         &buf_size_to_send);
-       if (buf_size_to_send > 0) send_bytes_to_peer(buf, buf_size_to_send);
-     } while (result == TSI_INCOMPLETE_DATA);
-     if (result != TSI_OK) return result;
-     if (!tsi_handshaker_is_in_progress(handshaker)) break;
-
-     do {
-       // Read bytes from the peer.
-       buf_size = sizeof(buf);
-       buf_offset = 0;
-       read_bytes_from_peer(buf, &buf_size);
-       if (buf_size == 0) break;
-
-       // Process the bytes from the peer. We have to be careful as these bytes
-       // may contain non-handshake data (protected data). If this is the case,
-       // we will exit from the loop with buf_size > 0.
-       size_t consumed_by_handshaker = buf_size;
-       result = tsi_handshaker_process_bytes_from_peer(
-           handshaker, buf, &consumed_by_handshaker);
-       buf_size -= consumed_by_handshaker;
-       buf_offset += consumed_by_handshaker;
-     } while (result == TSI_INCOMPLETE_DATA);
-
-     if (result != TSI_OK) return result;
-     if (!tsi_handshaker_is_in_progress(handshaker)) break;
+
+   typedef struct {
+     tsi_handshaker *handshaker;
+     tsi_handshaker_result *handshaker_result;
+     unsigned char *handshake_buffer;
+     size_t handshake_buffer_size;
+     ...
+   } security_handshaker;
+
+   void do_handshake(security_handshaker *h, ...) {
+     // Start the handshake by the calling do_handshake_next.
+     do_handshake_next(h, NULL, 0);
+     ...
    }
 
-   // Check the Peer.
-   tsi_peer peer;
-   do {
-     result = tsi_handshaker_extract_peer(handshaker, &peer);
-     if (result != TSI_OK) break;
-     result = check_peer(&peer);
-   } while (0);
-   tsi_peer_destruct(&peer);
-   if (result != TSI_OK) return result;
-
-   // Create the protector.
-   tsi_frame_protector* protector = NULL;
-   result = tsi_handshaker_create_frame_protector(handshaker, NULL,
-                                                  &protector);
-   if (result != TSI_OK) return result;
-
-   // Do not forget to unprotect outstanding data if any.
-   if (buf_size > 0) {
-     result = tsi_frame_protector_unprotect(protector, buf + buf_offset,
-                                            buf_size, ..., ...);
-     ....
+   // This method is the callback function when data is received from the
+   // peer. This method will read bytes into the handshake buffer and call
+   // do_handshake_next.
+   void on_handshake_data_received_from_peer(void *user_data) {
+     security_handshaker *h = (security_handshaker *)user_data;
+     size_t bytes_received_size = h->handshake_buffer_size;
+     read_bytes_from_peer(h->handshake_buffer, &bytes_received_size);
+     do_handshake_next(h, h->handshake_buffer, bytes_received_size);
+   }
+
+   // This method processes a step of handshake, calling tsi_handshaker_next.
+   void do_handshake_next(security_handshaker *h,
+                          const unsigned char* bytes_received,
+                          size_t bytes_received_size) {
+     tsi_result status = TSI_OK;
+     unsigned char *bytes_to_send = NULL;
+     size_t bytes_to_send_size = 0;
+     tsi_handshaker_result *result = NULL;
+     status = tsi_handshaker_next(
+         handshaker, bytes_received, bytes_received_size, &bytes_to_send,
+         &bytes_to_send_size, &result, on_handshake_next_done, h);
+     // If TSI handshaker is asynchronous, on_handshake_next_done will be
+     // executed inside tsi_handshaker_next.
+     if (status == TSI_ASYNC) return;
+     // If TSI handshaker is synchronous, invoke callback directly in this
+     // thread.
+     on_handshake_next_done(status, (void *)h, bytes_to_send,
+                            bytes_to_send_size, result);
+   }
+
+   // This is the callback function to execute after tsi_handshaker_next.
+   // It is passed to tsi_handshaker_next as a function parameter.
+   void on_handshake_next_done(
+       tsi_result status, void *user_data, const unsigned char *bytes_to_send,
+       size_t bytes_to_send_size, tsi_handshaker_result *result) {
+     security_handshaker *h = (security_handshaker *)user_data;
+     if (status == TSI_INCOMPLETE_DATA) {
+       // Schedule an asynchronous read from the peer. If handshake data are
+       // received, on_handshake_data_received_from_peer will be called.
+       async_read_from_peer(..., ..., on_handshake_data_received_from_peer);
+       return;
+     }
+     if (status != TSI_OK) return;
+
+     if (bytes_to_send_size > 0) {
+       send_bytes_to_peer(bytes_to_send, bytes_to_send_size);
+     }
+
+     if (result != NULL) {
+       // Handshake completed.
+       h->result = result;
+       // Check the Peer.
+       tsi_peer peer;
+       status = tsi_handshaker_result_extract_peer(result, &peer);
+       if (status != TSI_OK) return;
+       status = check_peer(&peer);
+       tsi_peer_destruct(&peer);
+       if (status != TSI_OK) return;
+
+       // Create the protector.
+       tsi_frame_protector* protector = NULL;
+       status = tsi_handshaker_result_create_frame_protector(result, NULL,
+                                                             &protector);
+       if (status != TSI_OK) return;
+
+       // Do not forget to unprotect outstanding data if any.
+       ....
+     }
    }
-   ...
    ------------------------------------------------------------------------   */
 typedef struct tsi_handshaker tsi_handshaker;
 
-/* Gets bytes that need to be sent to the peer.
+/* TO BE DEPRECATED SOON. Use tsi_handshaker_next instead.
+   Gets bytes that need to be sent to the peer.
    - bytes is the buffer that will be written with the data to be sent to the
      peer.
    - bytes_size is an input/output parameter specifying the capacity of the
@@ -292,7 +355,8 @@ tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self,
                                                     unsigned char *bytes,
                                                     size_t *bytes_size);
 
-/* Processes bytes received from the peer.
+/* TO BE DEPRECATED SOON. Use tsi_handshaker_next instead.
+   Processes bytes received from the peer.
    - bytes is the buffer containing the data.
    - bytes_size is an input/output parameter specifying the size of the data as
      input and the number of bytes consumed as output.
@@ -305,24 +369,29 @@ tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker *self,
                                                   const unsigned char *bytes,
                                                   size_t *bytes_size);
 
-/* Gets the result of the handshaker.
+/* TO BE DEPRECATED SOON.
+   Gets the result of the handshaker.
    Returns TSI_OK if the hanshake completed successfully and there has been no
    errors. Returns TSI_HANDSHAKE_IN_PROGRESS if the handshaker is not done yet
    but no error has been encountered so far. Otherwise the handshaker failed
    with the returned error.  */
 tsi_result tsi_handshaker_get_result(tsi_handshaker *self);
 
-/* Returns 1 if the handshake is in progress, 0 otherwise.  */
+/* TO BE DEPRECATED SOON.
+   Returns 1 if the handshake is in progress, 0 otherwise.  */
 #define tsi_handshaker_is_in_progress(h) \
   (tsi_handshaker_get_result((h)) == TSI_HANDSHAKE_IN_PROGRESS)
 
-/* This method may return TSI_FAILED_PRECONDITION if
+/* TO BE DEPRECATED SOON. Use tsi_handshaker_result_extract_peer instead.
+   This method may return TSI_FAILED_PRECONDITION if
    tsi_handshaker_is_in_progress returns 1, it returns TSI_OK otherwise
    assuming the handshaker is not in a fatal error state.
    The caller is responsible for destructing the peer.  */
 tsi_result tsi_handshaker_extract_peer(tsi_handshaker *self, tsi_peer *peer);
 
-/* This method creates a tsi_frame_protector object after the handshake phase
+/* TO BE DEPRECATED SOON. Use tsi_handshaker_result_create_frame_protector
+   instead.
+   This method creates a tsi_frame_protector object after the handshake phase
    is done. After this method has been called successfully, the only method
    that can be called on this object is Destroy.
    - max_output_protected_frame_size is an input/output parameter specifying the
@@ -342,12 +411,55 @@ tsi_result tsi_handshaker_create_frame_protector(
     tsi_handshaker *self, size_t *max_output_protected_frame_size,
     tsi_frame_protector **protector);
 
+/* Callback function definition for tsi_handshaker_next.
+   - status indicates the status of the next operation.
+   - user_data is the argument to callback function passed from the caller.
+   - bytes_to_send is the data buffer to be sent to the peer.
+   - bytes_to_send_size is the size of data buffer to be sent to the peer.
+   - handshaker_result is the result of handshake when the handshake completes,
+     is NULL otherwise.  */
+typedef void (*tsi_handshaker_on_next_done_cb)(
+    tsi_result status, void *user_data, const unsigned char *bytes_to_send,
+    size_t bytes_to_send_size, tsi_handshaker_result *handshaker_result);
+
+/* Conduct a next step of the handshake.
+   - received_bytes is the buffer containing the data received from the peer.
+   - received_bytes_size is the size of the data received from the peer.
+   - bytes_to_send is the data buffer to be sent to the peer.
+   - bytes_to_send_size is the size of data buffer to be sent to the peer.
+   - handshaker_result is the result of handshake if the handshake completes.
+   - cb is the callback function defined above. It can be NULL for synchronous
+     TSI handshaker implementation.
+   - user_data is the argument to callback function passed from the caller.
+   This method returns TSI_ASYNC if the TSI handshaker implementation is
+   asynchronous, and in this case, the callback is guaranteed to run in another
+   thread owned by TSI. It returns TSI_OK if the handshake completes or if
+   there are data to send to the peer, otherwise returns TSI_INCOMPLETE_DATA
+   which indicates that this method needs to be called again with more data
+   from the peer. In case of a fatal error in the handshake, another specific
+   error code is returned.
+   The caller is responsible for destroying the handshaker_result. However,
+   the caller should not free bytes_to_send, as the buffer is owned by the
+   tsi_handshaker object.  */
+tsi_result tsi_handshaker_next(
+    tsi_handshaker *self, const unsigned char *received_bytes,
+    size_t received_bytes_size, unsigned char **bytes_to_send,
+    size_t *bytes_to_send_size, tsi_handshaker_result **handshaker_result,
+    tsi_handshaker_on_next_done_cb cb, void *user_data);
+
 /* This method releases the tsi_handshaker object. After this method is called,
    no other method can be called on the object.  */
 void tsi_handshaker_destroy(tsi_handshaker *self);
 
+/* This method initializes the necessary shared objects used for tsi
+   implementation.  */
+void tsi_init();
+
+/* This method destroys the shared objects created by tsi_init.  */
+void tsi_destroy();
+
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_INTERFACE_H */
+#endif /* GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H */
diff --git a/src/cpp/README.md b/src/cpp/README.md
index d9b521317a6ca18f9b8a7fe5e706a9792b0a97e9..e9ef489a7ca317fed2be1ee9113e7f5bd58ea6d8 100644
--- a/src/cpp/README.md
+++ b/src/cpp/README.md
@@ -1,17 +1,17 @@
 
-#Overview
+# Overview
 
 This directory contains source code for C++ implementation of gRPC.
 
-#Pre-requisites
+# Pre-requisites
 
-##Linux
+## Linux
 
 ```sh
  $ [sudo] apt-get install build-essential autoconf libtool
 ```
 
-##Mac OSX
+## Mac OSX
 
 For a Mac system, git is not available by default. You will first need to
 install Xcode from the Mac AppStore and then run the following command from a
@@ -21,7 +21,7 @@ terminal:
  $ [sudo] xcode-select --install
 ```
 
-##Protoc
+## Protoc
 
 By default gRPC uses [protocol buffers](https://github.com/google/protobuf),
 you will need the `protoc` compiler to generate stub server and client code.
@@ -39,12 +39,12 @@ $ sudo make install   # 'make' should have been run by core grpc
 Alternatively, you can download `protoc` binaries from
 [the protocol buffers Github repository](https://github.com/google/protobuf/releases).
 
-#Installation
+# Installation
 
 Currently to install gRPC for C++, you need to build from source as described
 below.
 
-#Build from Source
+# Build from Source
 
 ```sh
  $ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc
@@ -54,7 +54,7 @@ below.
  $ [sudo] make install
 ```
 
-#Documentation
+# Documentation
 
 You can find out how to build and run our simplest gRPC C++ example in our
 [C++ quick start](../../examples/cpp).
diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc
index c985183ae7600022d36bef593547202772ff76d8..fac1ba9d43c1691c0cdbd4bf156ab59f50e9f723 100644
--- a/src/cpp/client/channel_cc.cc
+++ b/src/cpp/client/channel_cc.cc
@@ -131,7 +131,7 @@ void Channel::PerformOpsOnCall(CallOpSetInterface* ops, Call* call) {
   static const size_t MAX_OPS = 8;
   size_t nops = 0;
   grpc_op cops[MAX_OPS];
-  ops->FillOps(cops, &nops);
+  ops->FillOps(call->call(), cops, &nops);
   GPR_ASSERT(GRPC_CALL_OK ==
              grpc_call_start_batch(call->call(), cops, nops, ops, nullptr));
 }
diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc
index c073741dac0a7bd23ff5cb824670f69f73fb1e19..251623284089e4afa130deaa23e09a8d53db37fd 100644
--- a/src/cpp/client/client_context.cc
+++ b/src/cpp/client/client_context.cc
@@ -67,13 +67,14 @@ ClientContext::ClientContext()
       call_canceled_(false),
       deadline_(gpr_inf_future(GPR_CLOCK_REALTIME)),
       census_context_(nullptr),
-      propagate_from_call_(nullptr) {
+      propagate_from_call_(nullptr),
+      initial_metadata_corked_(false) {
   g_client_callbacks->DefaultConstructor(this);
 }
 
 ClientContext::~ClientContext() {
   if (call_) {
-    grpc_call_destroy(call_);
+    grpc_call_unref(call_);
   }
   g_client_callbacks->Destructor(this);
 }
diff --git a/src/cpp/client/generic_stub.cc b/src/cpp/client/generic_stub.cc
index 7a2fdf941cec7ff29271b99bbce48afbcdcc5fd5..4adb2a53599d38a01af287067bc5ef5f2ce9f644 100644
--- a/src/cpp/client/generic_stub.cc
+++ b/src/cpp/client/generic_stub.cc
@@ -42,7 +42,7 @@ std::unique_ptr<GenericClientAsyncReaderWriter> GenericStub::Call(
     ClientContext* context, const grpc::string& method, CompletionQueue* cq,
     void* tag) {
   return std::unique_ptr<GenericClientAsyncReaderWriter>(
-      new GenericClientAsyncReaderWriter(
+      GenericClientAsyncReaderWriter::Create(
           channel_.get(), cq,
           RpcMethod(method.c_str(), RpcMethod::BIDI_STREAMING), context, tag));
 }
diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc
index 65f327749999493476cf9d61db3c49e67add9e3e..53e4a9c39c18ad5d39fc9105dda2bd286da89806 100644
--- a/src/cpp/common/channel_arguments.cc
+++ b/src/cpp/common/channel_arguments.cc
@@ -81,6 +81,16 @@ ChannelArguments::ChannelArguments(const ChannelArguments& other)
   }
 }
 
+ChannelArguments::~ChannelArguments() {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  for (auto it = args_.begin(); it != args_.end(); ++it) {
+    if (it->type == GRPC_ARG_POINTER) {
+      it->value.pointer.vtable->destroy(&exec_ctx, it->value.pointer.p);
+    }
+  }
+  grpc_exec_ctx_finish(&exec_ctx);
+}
+
 void ChannelArguments::Swap(ChannelArguments& other) {
   args_.swap(other.args_);
   strings_.swap(other.strings_);
@@ -101,8 +111,10 @@ void ChannelArguments::SetSocketMutator(grpc_socket_mutator* mutator) {
   for (auto it = args_.begin(); it != args_.end(); ++it) {
     if (it->type == mutator_arg.type &&
         grpc::string(it->key) == grpc::string(mutator_arg.key)) {
+      GPR_ASSERT(!replaced);
       it->value.pointer.vtable->destroy(&exec_ctx, it->value.pointer.p);
       it->value.pointer = mutator_arg.value.pointer;
+      replaced = true;
     }
   }
   grpc_exec_ctx_finish(&exec_ctx);
@@ -121,14 +133,19 @@ void ChannelArguments::SetUserAgentPrefix(
     return;
   }
   bool replaced = false;
+  auto strings_it = strings_.begin();
   for (auto it = args_.begin(); it != args_.end(); ++it) {
     const grpc_arg& arg = *it;
-    if (arg.type == GRPC_ARG_STRING &&
-        grpc::string(arg.key) == GRPC_ARG_PRIMARY_USER_AGENT_STRING) {
-      strings_.push_back(user_agent_prefix + " " + arg.value.string);
-      it->value.string = const_cast<char*>(strings_.back().c_str());
-      replaced = true;
-      break;
+    ++strings_it;
+    if (arg.type == GRPC_ARG_STRING) {
+      if (grpc::string(arg.key) == GRPC_ARG_PRIMARY_USER_AGENT_STRING) {
+        GPR_ASSERT(arg.value.string == strings_it->c_str());
+        *(strings_it) = user_agent_prefix + " " + arg.value.string;
+        it->value.string = const_cast<char*>(strings_it->c_str());
+        replaced = true;
+        break;
+      }
+      ++strings_it;
     }
   }
   if (!replaced) {
@@ -185,7 +202,7 @@ void ChannelArguments::SetPointerWithVtable(
   arg.type = GRPC_ARG_POINTER;
   strings_.push_back(key);
   arg.key = const_cast<char*>(strings_.back().c_str());
-  arg.value.pointer.p = value;
+  arg.value.pointer.p = vtable->copy(value);
   arg.value.pointer.vtable = vtable;
   args_.push_back(arg);
 }
diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc
index 253614ca9b408a44430238d3c993ecdd04fa1fb7..a7b3c2c0dac85933345005249eb893aec561513a 100644
--- a/src/cpp/common/channel_filter.cc
+++ b/src/cpp/common/channel_filter.cc
@@ -69,9 +69,9 @@ void ChannelData::GetInfo(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem,
 
 // CallData
 
-void CallData::StartTransportStreamOp(grpc_exec_ctx *exec_ctx,
-                                      grpc_call_element *elem,
-                                      TransportStreamOp *op) {
+void CallData::StartTransportStreamOpBatch(grpc_exec_ctx *exec_ctx,
+                                           grpc_call_element *elem,
+                                           TransportStreamOpBatch *op) {
   grpc_call_next_op(exec_ctx, elem, op->op());
 }
 
diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h
index 79c4bab985bac921734f08cd40af858d33ee69e9..8d800b87d9a3fd88d806a6c8f94e89e3f11b1e08 100644
--- a/src/cpp/common/channel_filter.h
+++ b/src/cpp/common/channel_filter.h
@@ -42,7 +42,6 @@
 #include <vector>
 
 #include "src/core/lib/channel/channel_stack.h"
-#include "src/core/lib/security/context/security_context.h"
 #include "src/core/lib/surface/channel_init.h"
 #include "src/core/lib/transport/metadata_batch.h"
 
@@ -141,73 +140,80 @@ class TransportOp {
   grpc_transport_op *op_;  // Not owned.
 };
 
-/// A C++ wrapper for the \c grpc_transport_stream_op struct.
-class TransportStreamOp {
+/// A C++ wrapper for the \c grpc_transport_stream_op_batch struct.
+class TransportStreamOpBatch {
  public:
   /// Borrows a pointer to \a op, but does NOT take ownership.
   /// The caller must ensure that \a op continues to exist for as
-  /// long as the TransportStreamOp object does.
-  explicit TransportStreamOp(grpc_transport_stream_op *op)
+  /// long as the TransportStreamOpBatch object does.
+  explicit TransportStreamOpBatch(grpc_transport_stream_op_batch *op)
       : op_(op),
-        send_initial_metadata_(op->send_initial_metadata),
-        send_trailing_metadata_(op->send_trailing_metadata),
-        recv_initial_metadata_(op->recv_initial_metadata),
-        recv_trailing_metadata_(op->recv_trailing_metadata) {}
-
-  grpc_transport_stream_op *op() const { return op_; }
+        send_initial_metadata_(
+            op->send_initial_metadata
+                ? op->payload->send_initial_metadata.send_initial_metadata
+                : nullptr),
+        send_trailing_metadata_(
+            op->send_trailing_metadata
+                ? op->payload->send_trailing_metadata.send_trailing_metadata
+                : nullptr),
+        recv_initial_metadata_(
+            op->recv_initial_metadata
+                ? op->payload->recv_initial_metadata.recv_initial_metadata
+                : nullptr),
+        recv_trailing_metadata_(
+            op->recv_trailing_metadata
+                ? op->payload->recv_trailing_metadata.recv_trailing_metadata
+                : nullptr) {}
+
+  grpc_transport_stream_op_batch *op() const { return op_; }
 
   grpc_closure *on_complete() const { return op_->on_complete; }
   void set_on_complete(grpc_closure *closure) { op_->on_complete = closure; }
 
   MetadataBatch *send_initial_metadata() {
-    return op_->send_initial_metadata == nullptr ? nullptr
-                                                 : &send_initial_metadata_;
+    return op_->send_initial_metadata ? &send_initial_metadata_ : nullptr;
   }
   MetadataBatch *send_trailing_metadata() {
-    return op_->send_trailing_metadata == nullptr ? nullptr
-                                                  : &send_trailing_metadata_;
+    return op_->send_trailing_metadata ? &send_trailing_metadata_ : nullptr;
   }
   MetadataBatch *recv_initial_metadata() {
-    return op_->recv_initial_metadata == nullptr ? nullptr
-                                                 : &recv_initial_metadata_;
+    return op_->recv_initial_metadata ? &recv_initial_metadata_ : nullptr;
   }
   MetadataBatch *recv_trailing_metadata() {
-    return op_->recv_trailing_metadata == nullptr ? nullptr
-                                                  : &recv_trailing_metadata_;
+    return op_->recv_trailing_metadata ? &recv_trailing_metadata_ : nullptr;
   }
 
   uint32_t *send_initial_metadata_flags() const {
-    return &op_->send_initial_metadata_flags;
+    return op_->send_initial_metadata
+               ? &op_->payload->send_initial_metadata
+                      .send_initial_metadata_flags
+               : nullptr;
   }
 
   grpc_closure *recv_initial_metadata_ready() const {
-    return op_->recv_initial_metadata_ready;
+    return op_->recv_initial_metadata
+               ? op_->payload->recv_initial_metadata.recv_initial_metadata_ready
+               : nullptr;
   }
   void set_recv_initial_metadata_ready(grpc_closure *closure) {
-    op_->recv_initial_metadata_ready = closure;
-  }
-
-  grpc_byte_stream *send_message() const { return op_->send_message; }
-  void set_send_message(grpc_byte_stream *send_message) {
-    op_->send_message = send_message;
+    op_->payload->recv_initial_metadata.recv_initial_metadata_ready = closure;
   }
 
-  /// To be called only on clients and servers, respectively.
-  grpc_client_security_context *client_security_context() const {
-    return (grpc_client_security_context *)op_->context[GRPC_CONTEXT_SECURITY]
-        .value;
+  grpc_byte_stream *send_message() const {
+    return op_->send_message ? op_->payload->send_message.send_message
+                             : nullptr;
   }
-  grpc_server_security_context *server_security_context() const {
-    return (grpc_server_security_context *)op_->context[GRPC_CONTEXT_SECURITY]
-        .value;
+  void set_send_message(grpc_byte_stream *send_message) {
+    op_->send_message = true;
+    op_->payload->send_message.send_message = send_message;
   }
 
   census_context *get_census_context() const {
-    return (census_context *)op_->context[GRPC_CONTEXT_TRACING].value;
+    return (census_context *)op_->payload->context[GRPC_CONTEXT_TRACING].value;
   }
 
  private:
-  grpc_transport_stream_op *op_;  // Not owned.
+  grpc_transport_stream_op_batch *op_;  // Not owned.
   MetadataBatch send_initial_metadata_;
   MetadataBatch send_trailing_metadata_;
   MetadataBatch recv_initial_metadata_;
@@ -251,9 +257,9 @@ class CallData {
   // TODO(roth): Find a way to avoid passing elem into these methods.
 
   /// Starts a new stream operation.
-  virtual void StartTransportStreamOp(grpc_exec_ctx *exec_ctx,
-                                      grpc_call_element *elem,
-                                      TransportStreamOp *op);
+  virtual void StartTransportStreamOpBatch(grpc_exec_ctx *exec_ctx,
+                                           grpc_call_element *elem,
+                                           TransportStreamOpBatch *op);
 
   /// Sets a pollset or pollset set.
   virtual void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx,
@@ -318,16 +324,17 @@ class ChannelFilter final {
   static void DestroyCallElement(grpc_exec_ctx *exec_ctx,
                                  grpc_call_element *elem,
                                  const grpc_call_final_info *final_info,
-                                 void *and_free_memory) {
+                                 grpc_closure *then_call_closure) {
+    GPR_ASSERT(then_call_closure == NULL);
     reinterpret_cast<CallDataType *>(elem->call_data)->~CallDataType();
   }
 
-  static void StartTransportStreamOp(grpc_exec_ctx *exec_ctx,
-                                     grpc_call_element *elem,
-                                     grpc_transport_stream_op *op) {
+  static void StartTransportStreamOpBatch(grpc_exec_ctx *exec_ctx,
+                                          grpc_call_element *elem,
+                                          grpc_transport_stream_op_batch *op) {
     CallDataType *call_data = (CallDataType *)elem->call_data;
-    TransportStreamOp op_wrapper(op);
-    call_data->StartTransportStreamOp(exec_ctx, elem, &op_wrapper);
+    TransportStreamOpBatch op_wrapper(op);
+    call_data->StartTransportStreamOpBatch(exec_ctx, elem, &op_wrapper);
   }
 
   static void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx,
@@ -379,7 +386,7 @@ void RegisterChannelFilter(
       stack_type,
       priority,
       include_filter,
-      {FilterType::StartTransportStreamOp, FilterType::StartTransportOp,
+      {FilterType::StartTransportStreamOpBatch, FilterType::StartTransportOp,
        FilterType::call_data_size, FilterType::InitCallElement,
        FilterType::SetPollsetOrPollsetSet, FilterType::DestroyCallElement,
        FilterType::channel_data_size, FilterType::InitChannelElement,
diff --git a/src/cpp/common/completion_queue_cc.cc b/src/cpp/common/completion_queue_cc.cc
index 0408a4108531b282663788c68349dd99a78d460c..14c51f63c5cd6a5cc434fce4c2690b80d425cce1 100644
--- a/src/cpp/common/completion_queue_cc.cc
+++ b/src/cpp/common/completion_queue_cc.cc
@@ -43,7 +43,12 @@ namespace grpc {
 
 static internal::GrpcLibraryInitializer g_gli_initializer;
 
-CompletionQueue::CompletionQueue(grpc_completion_queue* take) : cq_(take) {
+// 'CompletionQueue' constructor can safely call GrpcLibraryCodegen(false) here
+// i.e not have GrpcLibraryCodegen call grpc_init(). This is because, to create
+// a 'grpc_completion_queue' instance (which is being passed as the input to
+// this constructor), one must have already called grpc_init().
+CompletionQueue::CompletionQueue(grpc_completion_queue* take)
+    : GrpcLibraryCodegen(false), cq_(take) {
   InitialAvalanching();
 }
 
diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc
index 36e4c893540b2c277037c674d355d0e31032183a..f679a339456920d95f9b9e57e7268f98291b33b2 100644
--- a/src/cpp/common/core_codegen.cc
+++ b/src/cpp/common/core_codegen.cc
@@ -54,9 +54,26 @@ struct grpc_byte_buffer;
 
 namespace grpc {
 
+const grpc_completion_queue_factory*
+CoreCodegen::grpc_completion_queue_factory_lookup(
+    const grpc_completion_queue_attributes* attributes) {
+  return ::grpc_completion_queue_factory_lookup(attributes);
+}
+
 grpc_completion_queue* CoreCodegen::grpc_completion_queue_create(
+    const grpc_completion_queue_factory* factory,
+    const grpc_completion_queue_attributes* attributes, void* reserved) {
+  return ::grpc_completion_queue_create(factory, attributes, reserved);
+}
+
+grpc_completion_queue* CoreCodegen::grpc_completion_queue_create_for_next(
+    void* reserved) {
+  return ::grpc_completion_queue_create_for_next(reserved);
+}
+
+grpc_completion_queue* CoreCodegen::grpc_completion_queue_create_for_pluck(
     void* reserved) {
-  return ::grpc_completion_queue_create(reserved);
+  return ::grpc_completion_queue_create_for_pluck(reserved);
 }
 
 void CoreCodegen::grpc_completion_queue_destroy(grpc_completion_queue* cq) {
@@ -91,6 +108,12 @@ void CoreCodegen::grpc_byte_buffer_destroy(grpc_byte_buffer* bb) {
   ::grpc_byte_buffer_destroy(bb);
 }
 
+void CoreCodegen::grpc_call_ref(grpc_call* call) { ::grpc_call_ref(call); }
+void CoreCodegen::grpc_call_unref(grpc_call* call) { ::grpc_call_unref(call); }
+void* CoreCodegen::grpc_call_arena_alloc(grpc_call* call, size_t length) {
+  return ::grpc_call_arena_alloc(call, length);
+}
+
 int CoreCodegen::grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
                                               grpc_byte_buffer* buffer) {
   return ::grpc_byte_buffer_reader_init(reader, buffer);
@@ -111,6 +134,8 @@ grpc_byte_buffer* CoreCodegen::grpc_raw_byte_buffer_create(grpc_slice* slice,
   return ::grpc_raw_byte_buffer_create(slice, nslices);
 }
 
+grpc_slice CoreCodegen::grpc_empty_slice() { return ::grpc_empty_slice(); }
+
 grpc_slice CoreCodegen::grpc_slice_malloc(size_t length) {
   return ::grpc_slice_malloc(length);
 }
diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc
index 039c530cdc7364bb66d8cb32cf5b1d52be45133c..72a4c4cf94a2753f108835ba6cb35e5f400998f9 100644
--- a/src/cpp/common/version_cc.cc
+++ b/src/cpp/common/version_cc.cc
@@ -37,5 +37,5 @@
 #include <grpc++/grpc++.h>
 
 namespace grpc {
-grpc::string Version() { return "1.2.0-dev"; }
+grpc::string Version() { return "1.4.0-dev"; }
 }
diff --git a/include/grpc++/impl/codegen/thrift_utils.h b/src/cpp/server/channel_argument_option.cc
similarity index 52%
rename from include/grpc++/impl/codegen/thrift_utils.h
rename to src/cpp/server/channel_argument_option.cc
index 742d739703522f4fe5db83ec38d9812515647ce5..723f968ff86c5779d96269de2f61496bc9948063 100644
--- a/include/grpc++/impl/codegen/thrift_utils.h
+++ b/src/cpp/server/channel_argument_option.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2016, Google Inc.
+ * Copyright 2017, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,53 +31,48 @@
  *
  */
 
-#ifndef GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H
-#define GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H
-
-#include <grpc++/impl/codegen/config.h>
-#include <grpc++/impl/codegen/core_codegen_interface.h>
-#include <grpc++/impl/codegen/serialization_traits.h>
-#include <grpc++/impl/codegen/status.h>
-#include <grpc++/impl/codegen/status_code_enum.h>
-#include <grpc++/impl/codegen/thrift_serializer.h>
-#include <grpc/impl/codegen/byte_buffer_reader.h>
-#include <grpc/impl/codegen/slice.h>
-#include <cstdint>
-#include <cstdlib>
+#include <grpc++/impl/channel_argument_option.h>
 
 namespace grpc {
 
-using apache::thrift::util::ThriftSerializerCompact;
+std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
+    const grpc::string &name, const grpc::string &value) {
+  class StringOption final : public ServerBuilderOption {
+   public:
+    StringOption(const grpc::string &name, const grpc::string &value)
+        : name_(name), value_(value) {}
 
-template <class T>
-class SerializationTraits<T, typename std::enable_if<std::is_base_of<
-                                 apache::thrift::TBase, T>::value>::type> {
- public:
-  static Status Serialize(const T& msg, grpc_byte_buffer** bp,
-                          bool* own_buffer) {
-    *own_buffer = true;
+    virtual void UpdateArguments(ChannelArguments *args) override {
+      args->SetString(name_, value_);
+    }
+    virtual void UpdatePlugins(
+        std::vector<std::unique_ptr<ServerBuilderPlugin>> *plugins) override {}
 
-    ThriftSerializerCompact serializer;
-    serializer.Serialize(msg, bp);
+   private:
+    const grpc::string name_;
+    const grpc::string value_;
+  };
+  return std::unique_ptr<ServerBuilderOption>(new StringOption(name, value));
+}
 
-    return Status(StatusCode::OK, "ok");
-  }
+std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
+    const grpc::string &name, int value) {
+  class IntOption final : public ServerBuilderOption {
+   public:
+    IntOption(const grpc::string &name, int value)
+        : name_(name), value_(value) {}
 
-  static Status Deserialize(grpc_byte_buffer* buffer, T* msg,
-                            int max_receive_message_size) {
-    if (!buffer) {
-      return Status(StatusCode::INTERNAL, "No payload");
+    virtual void UpdateArguments(ChannelArguments *args) override {
+      args->SetInt(name_, value_);
     }
+    virtual void UpdatePlugins(
+        std::vector<std::unique_ptr<ServerBuilderPlugin>> *plugins) override {}
 
-    ThriftSerializerCompact deserializer;
-    deserializer.Deserialize(buffer, msg);
-
-    grpc_byte_buffer_destroy(buffer);
-
-    return Status(StatusCode::OK, "ok");
-  }
-};
+   private:
+    const grpc::string name_;
+    const int value_;
+  };
+  return std::unique_ptr<ServerBuilderOption>(new IntOption(name, value));
+}
 
 }  // namespace grpc
-
-#endif  // GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H
diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc
index 00a90bb184c6d6233d2871e4f1fe3478b69ca39c..2ead048a1ff14901c99d715229d20d6b4199d619 100644
--- a/src/cpp/server/server_builder.cc
+++ b/src/cpp/server/server_builder.cc
@@ -83,7 +83,8 @@ ServerBuilder::~ServerBuilder() {
 
 std::unique_ptr<ServerCompletionQueue> ServerBuilder::AddCompletionQueue(
     bool is_frequently_polled) {
-  ServerCompletionQueue* cq = new ServerCompletionQueue(is_frequently_polled);
+  ServerCompletionQueue* cq = new ServerCompletionQueue(
+      is_frequently_polled ? GRPC_CQ_DEFAULT_POLLING : GRPC_CQ_NON_LISTENING);
   cqs_.push_back(cq);
   return std::unique_ptr<ServerCompletionQueue>(cq);
 }
@@ -242,6 +243,16 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
       sync_server_cqs(std::make_shared<
                       std::vector<std::unique_ptr<ServerCompletionQueue>>>());
 
+  int num_frequently_polled_cqs = 0;
+  for (auto it = cqs_.begin(); it != cqs_.end(); ++it) {
+    if ((*it)->IsFrequentlyPolled()) {
+      num_frequently_polled_cqs++;
+    }
+  }
+
+  const bool is_hybrid_server =
+      has_sync_methods && num_frequently_polled_cqs > 0;
+
   if (has_sync_methods) {
     // This is a Sync server
     gpr_log(GPR_INFO,
@@ -251,9 +262,12 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
             sync_server_settings_.max_pollers,
             sync_server_settings_.cq_timeout_msec);
 
+    grpc_cq_polling_type polling_type =
+        is_hybrid_server ? GRPC_CQ_NON_POLLING : GRPC_CQ_DEFAULT_POLLING;
+
     // Create completion queues to listen to incoming rpc requests
     for (int i = 0; i < sync_server_settings_.num_cqs; i++) {
-      sync_server_cqs->emplace_back(new ServerCompletionQueue());
+      sync_server_cqs->emplace_back(new ServerCompletionQueue(polling_type));
     }
   }
 
@@ -269,12 +283,10 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
   //     server
   //  2. cqs_: Completion queues added via AddCompletionQueue() call
 
-  // All sync cqs (if any) are frequently polled by ThreadManager
-  int num_frequently_polled_cqs = sync_server_cqs->size();
-
   for (auto it = sync_server_cqs->begin(); it != sync_server_cqs->end(); ++it) {
     grpc_server_register_completion_queue(server->server_, (*it)->cq(),
                                           nullptr);
+    num_frequently_polled_cqs++;
   }
 
   // cqs_ contains the completion queue added by calling the ServerBuilder's
@@ -283,14 +295,8 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
   // listening to incoming channels. Such completion queues must be registered
   // as non-listening queues
   for (auto it = cqs_.begin(); it != cqs_.end(); ++it) {
-    if ((*it)->IsFrequentlyPolled()) {
-      grpc_server_register_completion_queue(server->server_, (*it)->cq(),
-                                            nullptr);
-      num_frequently_polled_cqs++;
-    } else {
-      grpc_server_register_non_listening_completion_queue(server->server_,
-                                                          (*it)->cq(), nullptr);
-    }
+    grpc_server_register_completion_queue(server->server_, (*it)->cq(),
+                                          nullptr);
   }
 
   if (num_frequently_polled_cqs == 0) {
@@ -323,18 +329,21 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
     }
   }
 
+  bool added_port = false;
   for (auto port = ports_.begin(); port != ports_.end(); port++) {
     int r = server->AddListeningPort(port->addr, port->creds.get());
-    if (!r) return nullptr;
+    if (!r) {
+      if (added_port) server->Shutdown();
+      return nullptr;
+    }
+    added_port = true;
     if (port->selected_port != nullptr) {
       *port->selected_port = r;
     }
   }
 
   auto cqs_data = cqs_.empty() ? nullptr : &cqs_[0];
-  if (!server->Start(cqs_data, cqs_.size())) {
-    return nullptr;
-  }
+  server->Start(cqs_data, cqs_.size());
 
   for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) {
     (*plugin)->Finish(initializer);
diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc
index 9e11a8a9e07a41420694f406d15a88fc49f4d4b5..b4d6961db890fdaa944e67d62ab5d8479083c633 100644
--- a/src/cpp/server/server_cc.cc
+++ b/src/cpp/server/server_cc.cc
@@ -124,6 +124,14 @@ class ShutdownTag : public CompletionQueueTag {
   bool FinalizeResult(void** tag, bool* status) { return false; }
 };
 
+class DummyTag : public CompletionQueueTag {
+ public:
+  bool FinalizeResult(void** tag, bool* status) {
+    *status = true;
+    return true;
+  }
+};
+
 class Server::SyncRequest final : public CompletionQueueTag {
  public:
   SyncRequest(RpcServiceMethod* method, void* tag)
@@ -145,7 +153,7 @@ class Server::SyncRequest final : public CompletionQueueTag {
     grpc_metadata_array_destroy(&request_metadata_);
   }
 
-  void SetupRequest() { cq_ = grpc_completion_queue_create(nullptr); }
+  void SetupRequest() { cq_ = grpc_completion_queue_create_for_pluck(nullptr); }
 
   void TeardownRequest() {
     grpc_completion_queue_destroy(cq_);
@@ -213,10 +221,15 @@ class Server::SyncRequest final : public CompletionQueueTag {
           MethodHandler::HandlerParameter(&call_, &ctx_, request_payload_));
       global_callbacks->PostSynchronousRequest(&ctx_);
       request_payload_ = nullptr;
-      void* ignored_tag;
-      bool ignored_ok;
+
       cq_.Shutdown();
-      GPR_ASSERT(cq_.Next(&ignored_tag, &ignored_ok) == false);
+
+      CompletionQueueTag* op_tag = ctx_.GetCompletionOpTag();
+      cq_.TryPluck(op_tag, gpr_inf_future(GPR_CLOCK_REALTIME));
+
+      /* Ensure the cq_ is shutdown */
+      DummyTag ignored_tag;
+      GPR_ASSERT(cq_.Pluck(&ignored_tag) == false);
     }
 
    private:
@@ -315,14 +328,18 @@ class Server::SyncRequestThreadManager : public ThreadManager {
     }
   }
 
-  void ShutdownAndDrainCompletionQueue() {
+  void Shutdown() override {
     server_cq_->Shutdown();
+    ThreadManager::Shutdown();
+  }
 
+  void Wait() override {
+    ThreadManager::Wait();
     // Drain any pending items from the queue
     void* tag;
     bool ok;
     while (server_cq_->Next(&tag, &ok)) {
-      // Nothing to be done here
+      // Do nothing
     }
   }
 
@@ -402,7 +419,7 @@ Server::~Server() {
     } else if (!started_) {
       // Shutdown the completion queues
       for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) {
-        (*it)->ShutdownAndDrainCompletionQueue();
+        (*it)->Shutdown();
       }
     }
   }
@@ -489,10 +506,12 @@ void Server::RegisterAsyncGenericService(AsyncGenericService* service) {
 int Server::AddListeningPort(const grpc::string& addr,
                              ServerCredentials* creds) {
   GPR_ASSERT(!started_);
-  return creds->AddPortToServer(addr, server_);
+  int port = creds->AddPortToServer(addr, server_);
+  global_callbacks_->AddPort(this, addr, creds, port);
+  return port;
 }
 
-bool Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) {
+void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) {
   GPR_ASSERT(!started_);
   global_callbacks_->PreServerStart(this);
   started_ = true;
@@ -528,13 +547,11 @@ bool Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) {
   for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) {
     (*it)->Start();
   }
-
-  return true;
 }
 
 void Server::ShutdownInternal(gpr_timespec deadline) {
   std::unique_lock<std::mutex> lock(mu_);
-  if (started_ && !shutdown_) {
+  if (!shutdown_) {
     shutdown_ = true;
 
     /// The completion queue to use for server shutdown completion notification
@@ -566,7 +583,6 @@ void Server::ShutdownInternal(gpr_timespec deadline) {
     // Wait for threads in all ThreadManagers to terminate
     for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) {
       (*it)->Wait();
-      (*it)->ShutdownAndDrainCompletionQueue();
     }
 
     // Drain the shutdown queue (if the previous call to AsyncNext() timed out
@@ -591,7 +607,7 @@ void Server::PerformOpsOnCall(CallOpSetInterface* ops, Call* call) {
   static const size_t MAX_OPS = 8;
   size_t nops = 0;
   grpc_op cops[MAX_OPS];
-  ops->FillOps(cops, &nops);
+  ops->FillOps(call->call(), cops, &nops);
   auto result = grpc_call_start_batch(call->call(), cops, nops, ops, nullptr);
   GPR_ASSERT(GRPC_CALL_OK == result);
 }
diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc
index 05c05c86953404223dcc28be79f046385bd639ea..923556413e2156042823c99dd541886111c62cf5 100644
--- a/src/cpp/server/server_context.cc
+++ b/src/cpp/server/server_context.cc
@@ -42,6 +42,7 @@
 #include <grpc++/support/time.h>
 #include <grpc/compression.h>
 #include <grpc/grpc.h>
+#include <grpc/load_reporting.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
@@ -61,7 +62,7 @@ class ServerContext::CompletionOp final : public CallOpSetInterface {
         finalized_(false),
         cancelled_(0) {}
 
-  void FillOps(grpc_op* ops, size_t* nops) override;
+  void FillOps(grpc_call* call, grpc_op* ops, size_t* nops) override;
   bool FinalizeResult(void** tag, bool* status) override;
 
   bool CheckCancelled(CompletionQueue* cq) {
@@ -99,7 +100,8 @@ void ServerContext::CompletionOp::Unref() {
   }
 }
 
-void ServerContext::CompletionOp::FillOps(grpc_op* ops, size_t* nops) {
+void ServerContext::CompletionOp::FillOps(grpc_call* call, grpc_op* ops,
+                                          size_t* nops) {
   ops->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   ops->data.recv_close_on_server.cancelled = &cancelled_;
   ops->flags = 0;
@@ -150,7 +152,7 @@ ServerContext::ServerContext(gpr_timespec deadline, grpc_metadata_array* arr)
 
 ServerContext::~ServerContext() {
   if (call_) {
-    grpc_call_destroy(call_);
+    grpc_call_unref(call_);
   }
   if (completion_op_) {
     completion_op_->Unref();
@@ -166,6 +168,10 @@ void ServerContext::BeginCompletionOp(Call* call) {
   call->PerformOps(completion_op_);
 }
 
+CompletionQueueTag* ServerContext::GetCompletionOpTag() {
+  return static_cast<CompletionQueueTag*>(completion_op_);
+}
+
 void ServerContext::AddInitialMetadata(const grpc::string& key,
                                        const grpc::string& value) {
   initial_metadata_.insert(std::make_pair(key, value));
@@ -224,17 +230,9 @@ const struct census_context* ServerContext::census_context() const {
 void ServerContext::SetLoadReportingCosts(
     const std::vector<grpc::string>& cost_data) {
   if (call_ == nullptr) return;
-  grpc_load_reporting_cost_context* cost_ctx =
-      static_cast<grpc_load_reporting_cost_context*>(
-          gpr_malloc(sizeof(*cost_ctx)));
-  cost_ctx->values_count = cost_data.size();
-  cost_ctx->values = static_cast<grpc_slice*>(
-      gpr_malloc(sizeof(*cost_ctx->values) * cost_ctx->values_count));
-  for (size_t i = 0; i < cost_ctx->values_count; ++i) {
-    cost_ctx->values[i] =
-        grpc_slice_from_copied_buffer(cost_data[i].data(), cost_data[i].size());
+  for (const auto& cost_datum : cost_data) {
+    AddTrailingMetadata(GRPC_LB_COST_MD_KEY, cost_datum);
   }
-  grpc_call_set_load_reporting_cost_context(call_, cost_ctx);
 }
 
 }  // namespace grpc
diff --git a/src/cpp/thread_manager/thread_manager.cc b/src/cpp/thread_manager/thread_manager.cc
index 1450d009e4f1c9929067aaa0054390245f68164d..a463a4388a4ba48517cb057c758dea72a00eb3e6 100644
--- a/src/cpp/thread_manager/thread_manager.cc
+++ b/src/cpp/thread_manager/thread_manager.cc
@@ -98,80 +98,78 @@ void ThreadManager::MarkAsCompleted(WorkerThread* thd) {
 }
 
 void ThreadManager::CleanupCompletedThreads() {
-  std::unique_lock<std::mutex> lock(list_mu_);
-  for (auto thd = completed_threads_.begin(); thd != completed_threads_.end();
-       thd = completed_threads_.erase(thd)) {
-    delete *thd;
+  std::list<WorkerThread*> completed_threads;
+  {
+    // swap out the completed threads list: allows other threads to clean up
+    // more quickly
+    std::unique_lock<std::mutex> lock(list_mu_);
+    completed_threads.swap(completed_threads_);
   }
+  for (auto thd : completed_threads) delete thd;
 }
 
 void ThreadManager::Initialize() {
-  for (int i = 0; i < min_pollers_; i++) {
-    MaybeCreatePoller();
-  }
-}
-
-// If the number of pollers (i.e threads currently blocked in PollForWork()) is
-// less than max threshold (i.e max_pollers_) and the total number of threads is
-// below the maximum threshold, we can let the current thread continue as poller
-bool ThreadManager::MaybeContinueAsPoller() {
-  std::unique_lock<std::mutex> lock(mu_);
-  if (shutdown_ || num_pollers_ > max_pollers_) {
-    return false;
+  {
+    std::unique_lock<std::mutex> lock(mu_);
+    num_pollers_ = min_pollers_;
+    num_threads_ = min_pollers_;
   }
 
-  num_pollers_++;
-  return true;
-}
-
-// Create a new poller if the current number of pollers i.e num_pollers_ (i.e
-// threads currently blocked in PollForWork()) is below the threshold (i.e
-// min_pollers_) and the total number of threads is below the maximum threshold
-void ThreadManager::MaybeCreatePoller() {
-  std::unique_lock<std::mutex> lock(mu_);
-  if (!shutdown_ && num_pollers_ < min_pollers_) {
-    num_pollers_++;
-    num_threads_++;
-
+  for (int i = 0; i < min_pollers_; i++) {
     // Create a new thread (which ends up calling the MainWorkLoop() function
     new WorkerThread(this);
   }
 }
 
 void ThreadManager::MainWorkLoop() {
-  void* tag;
-  bool ok;
-
-  /*
-   1. Poll for work (i.e PollForWork())
-   2. After returning from PollForWork, reduce the number of pollers by 1. If
-      PollForWork() returned a TIMEOUT, then it may indicate that we have more
-      polling threads than needed. Check if the number of pollers is greater
-      than min_pollers and if so, terminate the thread.
-   3. Since we are short of one poller now, see if a new poller has to be
-      created (i.e see MaybeCreatePoller() for more details)
-   4. Do the actual work (DoWork())
-   5. After doing the work, see it this thread can resume polling work (i.e
-      see MaybeContinueAsPoller() for more details) */
-  do {
+  while (true) {
+    void* tag;
+    bool ok;
     WorkStatus work_status = PollForWork(&tag, &ok);
 
-    {
-      std::unique_lock<std::mutex> lock(mu_);
-      num_pollers_--;
-
-      if (work_status == TIMEOUT && num_pollers_ > min_pollers_) {
+    std::unique_lock<std::mutex> lock(mu_);
+    // Reduce the number of pollers by 1 and check what happened with the poll
+    num_pollers_--;
+    bool done = false;
+    switch (work_status) {
+      case TIMEOUT:
+        // If we timed out and we have more pollers than we need (or we are
+        // shutdown), finish this thread
+        if (shutdown_ || num_pollers_ > max_pollers_) done = true;
+        break;
+      case SHUTDOWN:
+        // If the thread manager is shutdown, finish this thread
+        done = true;
+        break;
+      case WORK_FOUND:
+        // If we got work and there are now insufficient pollers, start a new
+        // one
+        if (!shutdown_ && num_pollers_ < min_pollers_) {
+          num_pollers_++;
+          num_threads_++;
+          // Drop lock before spawning thread to avoid contention
+          lock.unlock();
+          new WorkerThread(this);
+        } else {
+          // Drop lock for consistency with above branch
+          lock.unlock();
+        }
+        // Lock is always released at this point - do the application work
+        DoWork(tag, ok);
+        // Take the lock again to check post conditions
+        lock.lock();
+        // If we're shutdown, we should finish at this point.
+        if (shutdown_) done = true;
         break;
-      }
-    }
-
-    // Note that MaybeCreatePoller does check for shutdown and creates a new
-    // thread only if ThreadManager is not shutdown
-    if (work_status == WORK_FOUND) {
-      MaybeCreatePoller();
-      DoWork(tag, ok);
     }
-  } while (MaybeContinueAsPoller());
+    // If we decided to finish the thread, break out of the while loop
+    if (done) break;
+    // ... otherwise increase poller count and continue
+    // There's a chance that we'll exceed the max poller count: that is
+    // explicitly ok - we'll decrease after one poll timeout, and prevent
+    // some thrashing starting up and shutting down threads
+    num_pollers_++;
+  };
 
   CleanupCompletedThreads();
 
diff --git a/src/cpp/thread_manager/thread_manager.h b/src/cpp/thread_manager/thread_manager.h
index 9c0569c62c16048767f197c7aa10967640969d17..d1050f6dede0496593d4810b10d05430d300f9fa 100644
--- a/src/cpp/thread_manager/thread_manager.h
+++ b/src/cpp/thread_manager/thread_manager.h
@@ -89,14 +89,14 @@ class ThreadManager {
   // Mark the ThreadManager as shutdown and begin draining the work. This is a
   // non-blocking call and the caller should call Wait(), a blocking call which
   // returns only once the shutdown is complete
-  void Shutdown();
+  virtual void Shutdown();
 
   // Has Shutdown() been called
   bool IsShutdown();
 
   // A blocking call that returns only after the ThreadManager has shutdown and
   // all the threads have drained all the outstanding work
-  void Wait();
+  virtual void Wait();
 
  private:
   // Helper wrapper class around std::thread. This takes a ThreadManager object
@@ -122,14 +122,6 @@ class ThreadManager {
   // The main funtion in ThreadManager
   void MainWorkLoop();
 
-  // Create a new poller if the number of current pollers is less than the
-  // minimum number of pollers needed (i.e min_pollers).
-  void MaybeCreatePoller();
-
-  // Returns true if the current thread can resume as a poller. i.e if the
-  // current number of pollers is less than the max_pollers.
-  bool MaybeContinueAsPoller();
-
   void MarkAsCompleted(WorkerThread* thd);
   void CleanupCompletedThreads();
 
diff --git a/src/cpp/util/error_details.cc b/src/cpp/util/error_details.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8bba05ac7d6812cfe1093c2bb4bff805f6c1e708
--- /dev/null
+++ b/src/cpp/util/error_details.cc
@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright 2017, 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++/support/error_details.h>
+
+#include "src/proto/grpc/status/status.pb.h"
+
+namespace grpc {
+
+Status ExtractErrorDetails(const Status& from, ::google::rpc::Status* to) {
+  if (to == nullptr) {
+    return Status(StatusCode::FAILED_PRECONDITION, "");
+  }
+  if (!to->ParseFromString(from.error_details())) {
+    return Status(StatusCode::INVALID_ARGUMENT, "");
+  }
+  return Status::OK;
+}
+
+Status SetErrorDetails(const ::google::rpc::Status& from, Status* to) {
+  if (to == nullptr) {
+    return Status(StatusCode::FAILED_PRECONDITION, "");
+  }
+  StatusCode code = StatusCode::UNKNOWN;
+  if (from.code() >= StatusCode::OK && from.code() <= StatusCode::DATA_LOSS) {
+    code = static_cast<StatusCode>(from.code());
+  }
+  *to = Status(code, from.message(), from.SerializeAsString());
+  return Status::OK;
+}
+
+}  // namespace grpc
diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
old mode 100644
new mode 100755
index db55ed5a6c8a7a9bb05e4dcf301140e2d46dcfd9..6ac25aa1f02dfa152106864fd2861736e53dbffe
--- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj
+++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
@@ -1,84 +1,38 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+  <Import Project="..\Grpc.Core\Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <RootNamespace>Grpc.Auth</RootNamespace>
+    <Copyright>Copyright 2015, Google Inc.</Copyright>
+    <AssemblyTitle>gRPC C# Auth</AssemblyTitle>
+    <VersionPrefix>$(GrpcCsharpVersion)</VersionPrefix>
+    <Authors>Google Inc.</Authors>
+    <TargetFrameworks>net45;netstandard1.5</TargetFrameworks>
+    <DefineConstants>$(DefineConstants);SIGNED</DefineConstants>
     <AssemblyName>Grpc.Auth</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <DocumentationFile>bin\$(Configuration)\Grpc.Auth.Xml</DocumentationFile>
-    <NuGetPackageImportStamp>455903a2</NuGetPackageImportStamp>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <ConsolePause>false</ConsolePause>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <ConsolePause>false</ConsolePause>
+    <PackageId>Grpc.Auth</PackageId>
+    <PackageTags>gRPC RPC Protocol HTTP/2 Auth OAuth2</PackageTags>
+    <PackageProjectUrl>https://github.com/grpc/grpc</PackageProjectUrl>
+    <PackageLicenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</PackageLicenseUrl>
+    <NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.5' ">1.6.0</NetStandardImplicitPackageVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Net" />
-    <Reference Include="System.Net.Http" />
-    <Reference Include="System.Net.Http.WebRequest" />
-    <Reference Include="BouncyCastle.Crypto">
-      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
-    </Reference>
-    <Reference Include="Newtonsoft.Json">
-      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
-    </Reference>
-    <Reference Include="log4net">
-      <HintPath>..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Core">
-      <HintPath>..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="Zlib.Portable">
-      <HintPath>..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis">
-      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.PlatformServices">
-      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth">
-      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth.PlatformServices">
-      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
-    </Reference>
+    <Compile Include="..\Grpc.Core\Version.cs" />
   </ItemGroup>
+
   <ItemGroup>
-    <Compile Include="..\Grpc.Core\Version.cs">
-      <Link>Version.cs</Link>
-    </Compile>
-    <Compile Include="GoogleGrpcCredentials.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="GoogleAuthInterceptors.cs" />
+    <ProjectReference Include="../Grpc.Core/Grpc.Core.csproj" />
   </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+
   <ItemGroup>
-    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
-      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
-      <Name>Grpc.Core</Name>
-    </ProjectReference>
+    <PackageReference Include="Google.Apis.Auth" Version="1.21.0" />
   </ItemGroup>
-  <ItemGroup>
-    <None Include="Grpc.Auth.project.json" />
-    <None Include="packages.config" />
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+
+</Project>
diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.project.json b/src/csharp/Grpc.Auth/Grpc.Auth.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Auth/Grpc.Auth.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.xproj b/src/csharp/Grpc.Auth/Grpc.Auth.xproj
deleted file mode 100644
index dd3d94c574aab0ab6b5ca69bb7a82d889b75807c..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Auth/Grpc.Auth.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>c82631ed-06d1-4458-87bc-8257d12307a8</ProjectGuid>
-    <RootNamespace>Grpc.Auth</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\Grpc.Core\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Auth/packages.config b/src/csharp/Grpc.Auth/packages.config
deleted file mode 100644
index 11c6375c638d51d606fb23a2acf14d8dc54f8c1f..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Auth/packages.config
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
-  <package id="Google.Apis" version="1.16.0" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.16.0" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.16.0" targetFramework="net45" />
-  <package id="log4net" version="2.0.3" targetFramework="net45" />
-  <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
-  <package id="Zlib.Portable.Signed" version="1.11.0" targetFramework="net45" />
-</packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Auth/project.json b/src/csharp/Grpc.Auth/project.json
deleted file mode 100644
index 3805f4759e8e5633e82806e5fc03d8aa7093669e..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Auth/project.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
-  "version": "1.2.0-dev",
-  "title": "gRPC C# Auth",
-  "authors": [ "Google Inc." ],
-  "copyright": "Copyright 2015, Google Inc.",
-  "packOptions": {
-    "summary": "Auth library for C# implementation of gRPC - an RPC library and framework",
-    "description": "Auth library for C# implementation of gRPC - an RPC library and framework. See project site for more info.",
-    "owners": [ "grpc-packages" ],
-    "licenseUrl": "https://github.com/grpc/grpc/blob/master/LICENSE",
-    "projectUrl": "https://github.com/grpc/grpc",
-    "requireLicenseAcceptance": false,
-    "tags": [ "gRPC RPC Protocol HTTP/2 Auth OAuth2" ],
-  },
-  "buildOptions": {
-    "define": [ "SIGNED" ],
-    "keyFile": "../keys/Grpc.snk",
-    "xmlDoc": true,
-    "compile": {
-      "includeFiles": [ "../Grpc.Core/Version.cs" ]
-    }
-  },
-  "dependencies": {
-    "Grpc.Core": "1.2.0-dev",
-    "Google.Apis.Auth": "1.16.0"
-  },
-  "frameworks": {
-    "net45": { },
-    "netstandard1.5": {
-      "dependencies": {
-        "NETStandard.Library": "1.6.0"
-      }
-    }
-  }
-}
diff --git a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj
old mode 100644
new mode 100755
index 9b0b3abf107bc2ed18b5c279619a08deff67d289..f4dd5105fc77350ac4ed8156d0f701203482ea3a
--- a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj
+++ b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj
@@ -1,68 +1,36 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+  <Import Project="..\Grpc.Core\Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{3AB047CA-6CF9-435D-AA61-2D86C6FA2457}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Grpc.Core.Testing</RootNamespace>
+    <Copyright>Copyright 2017, Google Inc.</Copyright>
+    <AssemblyTitle>gRPC C# Core Testing</AssemblyTitle>
+    <VersionPrefix>$(GrpcCsharpVersion)</VersionPrefix>
+    <Authors>Google Inc.</Authors>
+    <TargetFrameworks>net45;netstandard1.5</TargetFrameworks>
+    <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <AssemblyName>Grpc.Core.Testing</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <DocumentationFile>bin\$(Configuration)\Grpc.Core.Testing.Xml</DocumentationFile>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+    <PackageId>Grpc.Core.Testing</PackageId>
+    <PackageTags>gRPC test testing</PackageTags>
+    <PackageProjectUrl>https://github.com/grpc/grpc</PackageProjectUrl>
+    <PackageLicenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</PackageLicenseUrl>
+    <NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.5' ">1.6.0</NetStandardImplicitPackageVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
-    </Reference>
+    <Compile Include="..\Grpc.Core\Version.cs" />
   </ItemGroup>
+
   <ItemGroup>
-    <Compile Include="..\Grpc.Core\Version.cs">
-      <Link>Version.cs</Link>
-    </Compile>
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="TestCalls.cs" />
+    <ProjectReference Include="../Grpc.Core/Grpc.Core.csproj" />
   </ItemGroup>
-  <ItemGroup>
-    <None Include="Grpc.Core.Testing.project.json" />
-    <None Include="packages.config" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
-      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
-      <Name>Grpc.Core</Name>
-    </ProjectReference>
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System.Runtime" />
+    <Reference Include="System.IO" />
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.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">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
\ No newline at end of file
+
+</Project>
diff --git a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.project.json b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.xproj b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.xproj
deleted file mode 100644
index c972387003350e5cb8df4a3217f44eaea5cd4ccd..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>2b372155-80ba-4cf9-82d6-4b938e8ec3a0</ProjectGuid>
-    <RootNamespace>Grpc.Core.Testing</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core.Testing/packages.config b/src/csharp/Grpc.Core.Testing/packages.config
deleted file mode 100644
index 53cfad52f0bca1b3d030ddd2f3266170dcbe6801..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Core.Testing/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
-</packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core.Testing/project.json b/src/csharp/Grpc.Core.Testing/project.json
deleted file mode 100644
index 02be95781262362defb42f2cf22dd83e78b67753..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Core.Testing/project.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-  "version": "1.2.0-dev",
-  "title": "gRPC C# Core Testing",
-  "authors": [ "Google Inc." ],
-  "copyright": "Copyright 2017, Google Inc.",
-  "packOptions": {
-    "summary": "Testing support for gRPC C#",
-    "description": "Useful when testing code that uses gRPC.",
-    "owners": [ "grpc-packages" ],
-    "licenseUrl": "https://github.com/grpc/grpc/blob/master/LICENSE",
-    "projectUrl": "https://github.com/grpc/grpc",
-    "requireLicenseAcceptance": false,
-    "tags": [ "gRPC test testing" ]
-  },
-  "buildOptions": {
-    "define": [ "SIGNED" ],
-    "keyFile": "../keys/Grpc.snk",
-    "xmlDoc": true,
-    "compile": {
-      "includeFiles": [ "../Grpc.Core/Version.cs" ]
-    }
-  },
-  "dependencies": {
-    "Grpc.Core": "1.2.0-dev"
-  },
-  "frameworks": {
-    "net45": {
-      "frameworkAssemblies": {
-        "System.Runtime": "",
-        "System.IO": ""
-      }
-    },
-    "netstandard1.5": {
-      "dependencies": {
-        "NETStandard.Library": "1.6.0"
-      }
-    }
-  }
-}
diff --git a/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs b/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs
index d7ebdb4201e7303e00fb829d5dc53cc716fed5ec..7858e77b2788c8cf528a06a24076f2c389ca0a76 100644
--- a/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs
+++ b/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs
@@ -72,10 +72,6 @@ namespace Grpc.Core.Tests
             public AppDomainTestClass()
             {
                 var helper = new MockServiceHelper(Host);
-                var server = helper.GetServer();
-                server.Start();
-                var channel = helper.GetChannel();
-
                 var readyToShutdown = new TaskCompletionSource<object>();
                 helper.DuplexStreamingHandler = new DuplexStreamingServerMethod<string, string>(async (requestStream, responseStream, context) =>
                 {
@@ -83,6 +79,10 @@ namespace Grpc.Core.Tests
                     await requestStream.ToListAsync();
                 });
 
+                var server = helper.GetServer();
+                server.Start();
+                var channel = helper.GetChannel();
+
                 var call = Calls.AsyncDuplexStreamingCall(helper.CreateDuplexStreamingCall());
                 readyToShutdown.Task.Wait();  // make sure handler is running
             }
diff --git a/src/csharp/Grpc.Core.Tests/AuthContextTest.cs b/src/csharp/Grpc.Core.Tests/AuthContextTest.cs
new file mode 100644
index 0000000000000000000000000000000000000000..f5fa469520cc84018e3c78c2b597eca4e1e36eb9
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/AuthContextTest.cs
@@ -0,0 +1,86 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using NUnit.Framework;
+using Grpc.Core;
+using System.Linq;
+
+namespace Grpc.Core.Tests
+{
+    public class AuthContextTest
+    {
+        [Test]
+        public void EmptyContext()
+        {
+            var context = new AuthContext(null, new Dictionary<string, List<AuthProperty>>());
+            Assert.IsFalse(context.IsPeerAuthenticated);
+            Assert.IsNull(context.PeerIdentityPropertyName);
+            Assert.AreEqual(0, context.PeerIdentity.Count());
+            Assert.AreEqual(0, context.Properties.Count());
+            Assert.AreEqual(0, context.FindPropertiesByName("nonexistent").Count());
+        }
+
+        [Test]
+        public void AuthenticatedContext()
+        {
+            var property1 = AuthProperty.Create("abc", new byte[] { 68, 69, 70 });
+            var context = new AuthContext("some_identity", new Dictionary<string, List<AuthProperty>>
+            {
+                {"some_identity", new List<AuthProperty> {property1}}
+            });
+            Assert.IsTrue(context.IsPeerAuthenticated);
+            Assert.AreEqual("some_identity", context.PeerIdentityPropertyName);
+            Assert.AreEqual(1, context.PeerIdentity.Count());
+        }
+
+        [Test]
+        public void FindPropertiesByName()
+        {
+            var property1 = AuthProperty.Create("abc", new byte[] {68, 69, 70});
+            var property2 = AuthProperty.Create("abc", new byte[] {71, 72, 73 });
+            var property3 = AuthProperty.Create("abc", new byte[] {});
+            var context = new AuthContext(null, new Dictionary<string, List<AuthProperty>>
+            {
+                {"existent", new List<AuthProperty> {property1, property2}},
+                {"foobar", new List<AuthProperty> {property3}},
+            });
+            Assert.AreEqual(3, context.Properties.Count());
+            Assert.AreEqual(0, context.FindPropertiesByName("nonexistent").Count());
+
+            var existentProperties = new List<AuthProperty>(context.FindPropertiesByName("existent"));
+            Assert.AreEqual(2, existentProperties.Count);
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Core.Tests/AuthPropertyTest.cs b/src/csharp/Grpc.Core.Tests/AuthPropertyTest.cs
new file mode 100644
index 0000000000000000000000000000000000000000..745191b80db0c248b8db82b6af8133e8292e94ed
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/AuthPropertyTest.cs
@@ -0,0 +1,82 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using NUnit.Framework;
+
+namespace Grpc.Core.Tests
+{
+    public class AuthPropertyTest
+    {
+        [Test]
+        public void Create_NameIsNotNull()
+        {
+            Assert.Throws(typeof(ArgumentNullException), () => AuthProperty.Create(null, new byte[0]));
+            Assert.Throws(typeof(ArgumentNullException), () => AuthProperty.CreateUnsafe(null, new byte[0]));
+        }
+
+        [Test]
+        public void Create_ValueIsNotNull()
+        {
+            Assert.Throws(typeof(ArgumentNullException), () => AuthProperty.Create("abc", null));
+            Assert.Throws(typeof(ArgumentNullException), () => AuthProperty.CreateUnsafe("abc", null));
+        }
+
+        [Test]
+        public void Create()
+        {
+            var valueBytes = new byte[] { 68, 69, 70 };
+            var authProperty = AuthProperty.Create("abc", valueBytes);
+
+            Assert.AreEqual("abc", authProperty.Name);
+            Assert.AreNotSame(valueBytes, authProperty.ValueBytesUnsafe);
+            CollectionAssert.AreEqual(valueBytes, authProperty.ValueBytes);
+            CollectionAssert.AreEqual(valueBytes, authProperty.ValueBytesUnsafe);
+            Assert.AreEqual("DEF", authProperty.Value);
+        }
+
+        [Test]
+        public void CreateUnsafe()
+        {
+            var valueBytes = new byte[] { 68, 69, 70 };
+            var authProperty = AuthProperty.CreateUnsafe("abc", valueBytes);
+
+            Assert.AreEqual("abc", authProperty.Name);
+            Assert.AreSame(valueBytes, authProperty.ValueBytesUnsafe);
+            Assert.AreNotSame(valueBytes, authProperty.ValueBytes);
+            CollectionAssert.AreEqual(valueBytes, authProperty.ValueBytes);
+            CollectionAssert.AreEqual(valueBytes, authProperty.ValueBytesUnsafe);
+            Assert.AreEqual("DEF", authProperty.Value);
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
index 6bf9756962ea8637b379ec438258c81a89cd0558..3a99107c422eea38eeb0c9b61c3d2ab0ce91c969 100644
--- a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
@@ -375,6 +375,18 @@ namespace Grpc.Core.Tests
             Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc"));
         }
 
+        [Test]
+        public void ServerCallContext_AuthContextNotPopulated()
+        {
+            helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
+            {
+                Assert.IsFalse(context.AuthContext.IsPeerAuthenticated);
+                Assert.AreEqual(0, context.AuthContext.Properties.Count());
+                return "PASS";
+            });
+            Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc"));
+        }
+
         [Test]
         public async Task Channel_WaitForStateChangedAsync()
         {
diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
old mode 100644
new mode 100755
index 646effe21a7c0eee42f48ff4bc0c70d749a05db7..9be77c8875dba18c15ead3465295d1f91d1fb210
--- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
+++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
@@ -1,102 +1,37 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+  <Import Project="..\Grpc.Core\Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{86EC5CB4-4EA2-40A2-8057-86542A0353BB}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>Grpc.Core.Tests</RootNamespace>
+    <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
     <AssemblyName>Grpc.Core.Tests</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+    <OutputType>Exe</OutputType>
+    <PackageId>Grpc.Core.Tests</PackageId>
+    <PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
+    <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="nunit.framework">
-      <HintPath>..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll</HintPath>
-    </Reference>
-    <Reference Include="nunitlite">
-      <HintPath>..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll</HintPath>
-    </Reference>
-    <Reference Include="Newtonsoft.Json">
-      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
-    </Reference>
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
-    </Reference>
+    <ProjectReference Include="../Grpc.Core/Grpc.Core.csproj" />
   </ItemGroup>
+
   <ItemGroup>
-    <Compile Include="..\Grpc.Core\Version.cs">
-      <Link>Version.cs</Link>
-    </Compile>
-    <Compile Include="CallCredentialsTest.cs" />
-    <Compile Include="CallOptionsTest.cs" />
-    <Compile Include="UserAgentStringTest.cs" />
-    <Compile Include="FakeCredentials.cs" />
-    <Compile Include="MarshallingErrorsTest.cs" />
-    <Compile Include="ChannelCredentialsTest.cs" />
-    <Compile Include="ShutdownTest.cs" />
-    <Compile Include="Internal\AsyncCallTest.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="ClientServerTest.cs" />
-    <Compile Include="ServerTest.cs" />
-    <Compile Include="GrpcEnvironmentTest.cs" />
-    <Compile Include="PInvokeTest.cs" />
-    <Compile Include="Internal\MetadataArraySafeHandleTest.cs" />
-    <Compile Include="Internal\CompletionQueueSafeHandleTest.cs" />
-    <Compile Include="Internal\CompletionQueueEventTest.cs" />
-    <Compile Include="Internal\ChannelArgsSafeHandleTest.cs" />
-    <Compile Include="ChannelOptionsTest.cs" />
-    <Compile Include="Internal\TimespecTest.cs" />
-    <Compile Include="TimeoutsTest.cs" />
-    <Compile Include="NUnitVersionTest.cs" />
-    <Compile Include="ChannelTest.cs" />
-    <Compile Include="MockServiceHelper.cs" />
-    <Compile Include="ResponseHeadersTest.cs" />
-    <Compile Include="CompressionTest.cs" />
-    <Compile Include="ContextPropagationTest.cs" />
-    <Compile Include="MetadataTest.cs" />
-    <Compile Include="PerformanceTest.cs" />
-    <Compile Include="SanityTest.cs" />
-    <Compile Include="HalfcloseTest.cs" />
-    <Compile Include="NUnitMain.cs" />
-    <Compile Include="Internal\FakeNativeCall.cs" />
-    <Compile Include="Internal\AsyncCallServerTest.cs" />
-    <Compile Include="ShutdownHookServerTest.cs" />
-    <Compile Include="ShutdownHookPendingCallTest.cs" />
-    <Compile Include="ShutdownHookClientTest.cs" />
-    <Compile Include="AppDomainUnloadTest.cs" />
+    <PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
+    <PackageReference Include="NUnit" Version="3.6.0" />
+    <PackageReference Include="NUnitLite" Version="3.6.0" />
+    <PackageReference Include="NUnit.ConsoleRunner" Version="3.6.0" />
+    <PackageReference Include="OpenCover" Version="4.6.519" />
+    <PackageReference Include="ReportGenerator" Version="2.4.4.0" />
   </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <ItemGroup>
-    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
-      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
-      <Name>Grpc.Core</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="Grpc.Core.Tests.project.json" />
-    <None Include="packages.config">
-      <SubType>Designer</SubType>
-    </None>
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
+
   <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+    <Compile Include="..\Grpc.Core\Version.cs" />
   </ItemGroup>
-  <ItemGroup />
+
 </Project>
diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.project.json b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.xproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.xproj
deleted file mode 100644
index 05823291542728459acbb90d04b099c42f12a295..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>759e23b2-fc04-4695-902d-b073cded3599</ProjectGuid>
-    <RootNamespace>Grpc.Core.Tests</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs b/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs
index e9ec59eb3db3052a00ee4c84c18736d73623355e..8649906becd5143355bdbb8e8df6b138ce17fbef 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs
@@ -43,19 +43,19 @@ namespace Grpc.Core.Internal.Tests
     public class CompletionQueueSafeHandleTest
     {
         [Test]
-        public void CreateAndDestroy()
+        public void CreateSyncAndDestroy()
         {
             GrpcEnvironment.AddRef();
-            var cq = CompletionQueueSafeHandle.Create();
+            var cq = CompletionQueueSafeHandle.CreateSync();
             cq.Dispose();
             GrpcEnvironment.ReleaseAsync().Wait();
         }
 
         [Test]
-        public void CreateAndShutdown()
+        public void CreateAsyncAndShutdown()
         {
-            GrpcEnvironment.AddRef();
-            var cq = CompletionQueueSafeHandle.Create();
+            var env = GrpcEnvironment.AddRef();
+            var cq = CompletionQueueSafeHandle.CreateAsync(new CompletionRegistry(env));
             cq.Shutdown();
             var ev = cq.Next();
             cq.Dispose();
diff --git a/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs b/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs
index 4d904700569220460580cd0ad5f129b53767aadc..c57c260c960e9976cf06082b9cc132f1d7865382 100644
--- a/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs
+++ b/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs
@@ -141,7 +141,8 @@ namespace Grpc.Core.Tests
         {
             if (server == null)
             {
-                server = new Server
+                // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755
+                server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
                 {
                     Services = { serviceDefinition },
                     Ports = { { Host, ServerPort.PickUnused, ServerCredentials.Insecure } }
diff --git a/src/csharp/Grpc.Core.Tests/PInvokeTest.cs b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
index d3735c78807bee4e8ed508c7966cc03c67594b97..d760717ba6f28df8da1fd09c5735a29799d54e14 100644
--- a/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
+++ b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
@@ -53,7 +53,7 @@ namespace Grpc.Core.Tests
         /// (~1.26us .NET Windows)
         /// </summary>
         [Test]
-        public void CompletionQueueCreateDestroyBenchmark()
+        public void CompletionQueueCreateSyncDestroyBenchmark()
         {
             GrpcEnvironment.AddRef();  // completion queue requires gRPC environment being initialized.
 
@@ -61,7 +61,7 @@ namespace Grpc.Core.Tests
                 10, 10,
                 () =>
                 {
-                    CompletionQueueSafeHandle cq = CompletionQueueSafeHandle.Create();
+                    CompletionQueueSafeHandle cq = CompletionQueueSafeHandle.CreateSync();
                     cq.Dispose();
                 });
 
diff --git a/src/csharp/Grpc.Core.Tests/SanityTest.cs b/src/csharp/Grpc.Core.Tests/SanityTest.cs
index 1c28277df55eb1a39f62f7008cb354fee56bb468..e02f2c9e5464379084d085212c2a90daf6a8f604 100644
--- a/src/csharp/Grpc.Core.Tests/SanityTest.cs
+++ b/src/csharp/Grpc.Core.Tests/SanityTest.cs
@@ -101,7 +101,7 @@ namespace Grpc.Core.Tests
         private string ReadTestsJson()
         {
             var assemblyDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
-            var testsJsonFile = Path.Combine(assemblyDir, "..", "..", "..", "tests.json");
+            var testsJsonFile = Path.Combine(assemblyDir, "..", "..", "..", "..", "tests.json");
             return File.ReadAllText(testsJsonFile);
         }
 
diff --git a/src/csharp/Grpc.Core.Tests/TestResult.xml b/src/csharp/Grpc.Core.Tests/TestResult.xml
deleted file mode 100644
index 13da80739ceead3bd6e8477089ed94a9165d0a9b..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Core.Tests/TestResult.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!--This file represents the results of running a test suite-->
-<test-results name="/usr/local/google/home/jtattermusch/github/grpc/src/csharp/GrpcCoreTests/bin/Debug/GrpcCoreTests.dll" total="3" errors="0" failures="0" not-run="0" inconclusive="0" ignored="0" skipped="0" invalid="0" date="2015-01-29" time="19:40:47">
-  <environment nunit-version="2.6.0.0" clr-version="4.0.30319.17020" os-version="Unix 3.13.0.43" platform="Unix" cwd="/usr/local/google/home/jtattermusch/github/grpc/src/csharp/GrpcCoreTests" machine-name="jtattermusch.mtv.corp.google.com" user="jtattermusch" user-domain="jtattermusch.mtv.corp.google.com" />
-  <culture-info current-culture="en-US" current-uiculture="en-US" />
-  <test-suite type="Assembly" name="/usr/local/google/home/jtattermusch/github/grpc/src/csharp/GrpcCoreTests/bin/Debug/GrpcCoreTests.dll" executed="True" result="Success" success="True" time="0.172" asserts="0">
-    <results>
-      <test-suite type="Namespace" name="Google" executed="True" result="Success" success="True" time="0.166" asserts="0">
-        <results>
-          <test-suite type="Namespace" name="GRPC" executed="True" result="Success" success="True" time="0.166" asserts="0">
-            <results>
-              <test-suite type="Namespace" name="Core" executed="True" result="Success" success="True" time="0.166" asserts="0">
-                <results>
-                  <test-suite type="Namespace" name="Tests" executed="True" result="Success" success="True" time="0.166" asserts="0">
-                    <results>
-                      <test-suite type="TestFixture" name="CallsTest" executed="True" result="Success" success="True" time="0.009" asserts="0">
-                        <results>
-                          <test-case name="Grpc.Core.Tests.CallsTest.Test1" executed="True" result="Success" success="True" time="0.004" asserts="0" />
-                        </results>
-                      </test-suite>
-                      <test-suite type="TestFixture" name="ClientServerTest" executed="True" result="Success" success="True" time="0.149" asserts="0">
-                        <results>
-                          <test-case name="Grpc.Core.Tests.ClientServerTest.EmptyCall" executed="True" result="Success" success="True" time="0.111" asserts="0" />
-                        </results>
-                      </test-suite>
-                      <test-suite type="TestFixture" name="ServerTest" executed="True" result="Success" success="True" time="0.001" asserts="0">
-                        <results>
-                          <test-case name="Grpc.Core.Tests.ServerTest.StartAndShutdownServer" executed="True" result="Success" success="True" time="0.001" asserts="0" />
-                        </results>
-                      </test-suite>
-                    </results>
-                  </test-suite>
-                </results>
-              </test-suite>
-            </results>
-          </test-suite>
-        </results>
-      </test-suite>
-    </results>
-  </test-suite>
-</test-results>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core.Tests/UserAgentStringTest.cs b/src/csharp/Grpc.Core.Tests/UserAgentStringTest.cs
index cc830086a67d3b7f4444262fe03bf0dbbc1154a0..74b4997f69e784af623cd1d98ef3ff58b1fb7d49 100644
--- a/src/csharp/Grpc.Core.Tests/UserAgentStringTest.cs
+++ b/src/csharp/Grpc.Core.Tests/UserAgentStringTest.cs
@@ -63,10 +63,6 @@ namespace Grpc.Core.Tests
         public void DefaultUserAgentString()
         {
             helper = new MockServiceHelper(Host);
-            server = helper.GetServer();
-            server.Start();
-            channel = helper.GetChannel();
-
             helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) =>
             {
                 var userAgentString = context.RequestHeaders.First(m => (m.Key == "user-agent")).Value;
@@ -75,6 +71,11 @@ namespace Grpc.Core.Tests
                 Assert.IsTrue(parts[1].StartsWith("grpc-c/"));
                 return Task.FromResult("PASS");
             });
+
+            server = helper.GetServer();
+            server.Start();
+            channel = helper.GetChannel();
+
             Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), ""));
         }
 
@@ -83,11 +84,6 @@ namespace Grpc.Core.Tests
         {
             helper = new MockServiceHelper(Host,
                 channelOptions: new[] { new ChannelOption(ChannelOptions.PrimaryUserAgentString, "XYZ") });
-            server = helper.GetServer();
-            server.Start();
-            channel = helper.GetChannel();
-            
-            channel = helper.GetChannel();
             helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) =>
             {
                 var userAgentString = context.RequestHeaders.First(m => (m.Key == "user-agent")).Value;
@@ -95,6 +91,11 @@ namespace Grpc.Core.Tests
                 Assert.AreEqual("XYZ", parts[0]);
                 return Task.FromResult("PASS");
             });
+
+            server = helper.GetServer();
+            server.Start();
+            channel = helper.GetChannel();
+
             Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), ""));
         }
     }
diff --git a/src/csharp/Grpc.Core.Tests/packages.config b/src/csharp/Grpc.Core.Tests/packages.config
deleted file mode 100644
index 4750735fadb859d7a8dfb1b6a981906d8c90ad91..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Core.Tests/packages.config
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
-  <package id="NUnit" version="3.2.0" targetFramework="net45" />
-  <package id="NUnit.ConsoleRunner" version="3.2.0" />
-  <package id="NUnitLite" version="3.2.0" targetFramework="net45" />
-  <package id="OpenCover" version="4.6.519" />
-  <package id="ReportGenerator" version="2.4.4.0" />
-  <package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
-</packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core.Tests/project.json b/src/csharp/Grpc.Core.Tests/project.json
deleted file mode 100644
index 045207a413dbb631504c1fffe581c954bbf21871..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Core.Tests/project.json
+++ /dev/null
@@ -1,69 +0,0 @@
-{
-  "buildOptions": {
-    "emitEntryPoint": true
-  },
-  "configurations": {
-    "Debug": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    },
-    "Release": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    }
-  },
-
-  "dependencies": {
-    "Grpc.Core": {
-      "target": "project"
-    },
-    "Newtonsoft.Json": "8.0.3",
-    "NUnit": "3.2.0",
-    "NUnitLite": "3.2.0-*",
-    "NUnit.ConsoleRunner": "3.2.0",
-    "OpenCover": "4.6.519",
-    "ReportGenerator": "2.4.4.0"
-  },
-  "frameworks": {
-    "net45": { },
-    "netcoreapp1.0": {
-      "imports": [
-        "portable-net45"
-      ],
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.0"
-        }
-      }
-    }
-  },
-}
diff --git a/src/csharp/Grpc.Core/AuthContext.cs b/src/csharp/Grpc.Core/AuthContext.cs
new file mode 100644
index 0000000000000000000000000000000000000000..340b2201c79f56f933b26ecd84b574a710f9c74d
--- /dev/null
+++ b/src/csharp/Grpc.Core/AuthContext.cs
@@ -0,0 +1,128 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core
+{
+    /// <summary>
+    /// Authentication context for a call.
+    /// AuthContext is the only reliable source of truth when it comes to authenticating calls.
+    /// Using any other call/context properties for authentication purposes is wrong and inherently unsafe.
+    /// Note: experimental API that can change or be removed without any prior notice.
+    /// </summary>
+    public class AuthContext
+    {
+        string peerIdentityPropertyName;
+        Dictionary<string, List<AuthProperty>> properties;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="T:Grpc.Core.AuthContext"/> class.
+        /// </summary>
+        /// <param name="peerIdentityPropertyName">Peer identity property name.</param>
+        /// <param name="properties">Multimap of auth properties by name.</param>
+        internal AuthContext(string peerIdentityPropertyName, Dictionary<string, List<AuthProperty>> properties)
+        {
+            this.peerIdentityPropertyName = peerIdentityPropertyName;
+            this.properties = GrpcPreconditions.CheckNotNull(properties);
+        }
+
+        /// <summary>
+        /// Returns <c>true</c> if the peer is authenticated.
+        /// </summary>
+        public bool IsPeerAuthenticated
+        {
+            get
+            {
+                return peerIdentityPropertyName != null;
+            }
+        }
+
+        /// <summary>
+        /// Gets the name of the property that indicates the peer identity. Returns <c>null</c>
+        /// if the peer is not authenticated.
+        /// </summary>
+        public string PeerIdentityPropertyName
+        {
+            get
+            {
+                return peerIdentityPropertyName;
+            }
+        }
+
+        /// <summary>
+        /// Gets properties that represent the peer identity (there can be more than one). Returns an empty collection
+        /// if the peer is not authenticated.
+        /// </summary>
+        public IEnumerable<AuthProperty> PeerIdentity
+        {
+            get
+            {
+                if (peerIdentityPropertyName == null)
+                {
+                    return Enumerable.Empty<AuthProperty>();
+                }
+                return properties[peerIdentityPropertyName];
+            }
+        }
+
+        /// <summary>
+        /// Gets the auth properties of this context.
+        /// </summary>
+        public IEnumerable<AuthProperty> Properties
+        {
+            get
+            {
+                return properties.Values.SelectMany(v => v);
+            }
+        }
+
+        /// <summary>
+        /// Returns the auth properties with given name (there can be more than one).
+        /// If no properties of given name exist, an empty collection will be returned.
+        /// </summary>
+        public IEnumerable<AuthProperty> FindPropertiesByName(string propertyName)
+        {
+            List<AuthProperty> result;
+            if (!properties.TryGetValue(propertyName, out result))
+            {
+                return Enumerable.Empty<AuthProperty>();
+            }
+            return result;
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Core/AuthProperty.cs b/src/csharp/Grpc.Core/AuthProperty.cs
new file mode 100644
index 0000000000000000000000000000000000000000..c7a132b09eb6895ed6f5c3aed1b2e932570ed77f
--- /dev/null
+++ b/src/csharp/Grpc.Core/AuthProperty.cs
@@ -0,0 +1,126 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core
+{
+    /// <summary>
+    /// A property of an <see cref="AuthContext"/>.
+    /// Note: experimental API that can change or be removed without any prior notice.
+    /// </summary>
+    public class AuthProperty
+    {
+        string name;
+        byte[] valueBytes;
+        Lazy<string> value;
+
+        private AuthProperty(string name, byte[] valueBytes)
+        {
+            this.name = GrpcPreconditions.CheckNotNull(name);
+            this.valueBytes = GrpcPreconditions.CheckNotNull(valueBytes);
+            this.value = new Lazy<string>(() => MarshalUtils.GetStringUTF8(this.valueBytes));
+        }
+
+        /// <summary>
+        /// Gets the name of the property.
+        /// </summary>
+        public string Name
+        {
+            get
+            {
+                return name;
+            }
+        }
+
+        /// <summary>
+        /// Gets the string value of the property.
+        /// </summary>
+        public string Value
+        {
+            get
+            {
+                return value.Value;
+            }
+        }
+
+        /// <summary>
+        /// Gets the binary value of the property.
+        /// </summary>
+        public byte[] ValueBytes
+        {
+            get
+            {
+                var valueCopy = new byte[valueBytes.Length];
+                Buffer.BlockCopy(valueBytes, 0, valueCopy, 0, valueBytes.Length);
+                return valueCopy;
+            }
+        }
+
+        /// <summary>
+        /// Creates an instance of <c>AuthProperty</c>.
+        /// </summary>
+        /// <param name="name">the name</param>
+        /// <param name="valueBytes">the binary value of the property</param>
+        public static AuthProperty Create(string name, byte[] valueBytes)
+        {
+            GrpcPreconditions.CheckNotNull(valueBytes);
+            var valueCopy = new byte[valueBytes.Length];
+            Buffer.BlockCopy(valueBytes, 0, valueCopy, 0, valueBytes.Length);
+            return new AuthProperty(name, valueCopy);
+        }
+
+        /// <summary>
+        /// Gets the binary value of the property (without making a defensive copy).
+        /// </summary>
+        internal byte[] ValueBytesUnsafe
+        {
+            get
+            {
+                return valueBytes;
+            }
+        }
+
+        /// <summary>
+        /// Creates and instance of <c>AuthProperty</c> without making a defensive copy of <c>valueBytes</c>.
+        /// </summary>
+        internal static AuthProperty CreateUnsafe(string name, byte[] valueBytes)
+        {
+            return new AuthProperty(name, valueBytes);
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Core/ChannelOptions.cs b/src/csharp/Grpc.Core/ChannelOptions.cs
index b6eeceabc4c2131091dd7826cd0552bc94a3baeb..5de9b1ee3c43e67067d28cd4297d093b990056cb 100644
--- a/src/csharp/Grpc.Core/ChannelOptions.cs
+++ b/src/csharp/Grpc.Core/ChannelOptions.cs
@@ -151,7 +151,14 @@ namespace Grpc.Core
         public const string MaxConcurrentStreams = "grpc.max_concurrent_streams";
 
         /// <summary>Maximum message length that the channel can receive</summary>
-        public const string MaxMessageLength = "grpc.max_message_length";
+        public const string MaxReceiveMessageLength = "grpc.max_receive_message_length";
+
+        /// <summary>Maximum message length that the channel can send</summary>
+        public const string MaxSendMessageLength = "grpc.max_send_message_length";
+
+        /// <summary>Obsolete, for backward compatibility only.</summary>
+        [Obsolete("Use MaxReceiveMessageLength instead.")]
+        public const string MaxMessageLength = MaxReceiveMessageLength;
 
         /// <summary>Initial sequence number for http2 transports</summary>
         public const string Http2InitialSequenceNumber = "grpc.http2.initial_sequence_number";
@@ -165,6 +172,9 @@ namespace Grpc.Core
         /// <summary>Secondary user agent: goes at the end of the user-agent metadata</summary>
         public const string SecondaryUserAgentString = "grpc.secondary_user_agent";
 
+        /// <summary>If non-zero, allow the use of SO_REUSEPORT for server if it's available (default 1)</summary>
+        public const string SoReuseport = "grpc.so_reuseport";
+
         /// <summary>
         /// Creates native object for a collection of channel options.
         /// </summary>
diff --git a/src/csharp/Grpc.Core/Common.csproj.include b/src/csharp/Grpc.Core/Common.csproj.include
new file mode 100755
index 0000000000000000000000000000000000000000..2cb990ba49ea8f1c07c623714e8f8b27b58c62d3
--- /dev/null
+++ b/src/csharp/Grpc.Core/Common.csproj.include
@@ -0,0 +1,32 @@
+<!-- Common definitions shared by all .csproj files -->
+<Project>
+  <PropertyGroup>
+    <GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
+    <GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
+    <GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute>
+    <GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
+    <GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
+    <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+    <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+    <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+    <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+  </PropertyGroup>
+
+  <PropertyGroup>
+    <GenerateDocumentationFile>true</GenerateDocumentationFile>
+  </PropertyGroup>
+
+  <PropertyGroup>
+    <DefineConstants>$(DefineConstants);SIGNED</DefineConstants>
+    <AssemblyOriginatorKeyFile>../keys/Grpc.snk</AssemblyOriginatorKeyFile>
+    <SignAssembly>true</SignAssembly>
+    <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
+  </PropertyGroup>
+
+  <PropertyGroup Condition="'$(OS)' != 'Windows_NT'">
+    <!-- Workaround for https://github.com/dotnet/sdk/issues/335 -->
+    <FrameworkPathOverride Condition="Exists('/usr/lib/mono/4.5-api')">/usr/lib/mono/4.5-api</FrameworkPathOverride>
+    <FrameworkPathOverride Condition="Exists('/usr/local/lib/mono/4.5-api')">/usr/local/lib/mono/4.5-api</FrameworkPathOverride>
+    <FrameworkPathOverride Condition="Exists('/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api')">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api</FrameworkPathOverride>
+  </PropertyGroup>
+</Project>
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
old mode 100644
new mode 100755
index 23e1ddcf7f70928c50af77ff7c77e975432a598f..7e0f3f053d073a464734f3bf4198afec331f51b8
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -1,147 +1,68 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="Version.csproj.include" />
+  <Import Project="Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <RootNamespace>Grpc.Core</RootNamespace>
+    <Copyright>Copyright 2015, Google Inc.</Copyright>
+    <AssemblyTitle>gRPC C# Core</AssemblyTitle>
+    <VersionPrefix>$(GrpcCsharpVersion)</VersionPrefix>
+    <Authors>Google Inc.</Authors>
+    <TargetFrameworks>net45;netstandard1.5</TargetFrameworks>
     <AssemblyName>Grpc.Core</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <NuGetPackageImportStamp>c0512805</NuGetPackageImportStamp>
-    <DocumentationFile>bin\$(Configuration)\Grpc.Core.Xml</DocumentationFile>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+    <PackageId>Grpc.Core</PackageId>
+    <PackageTags>gRPC RPC Protocol HTTP/2</PackageTags>
+    <PackageProjectUrl>https://github.com/grpc/grpc</PackageProjectUrl>
+    <PackageLicenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</PackageLicenseUrl>
+    <NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.5' ">1.6.0</NetStandardImplicitPackageVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
-    </Reference>
+    <EmbeddedResource Include="..\..\..\etc\roots.pem" />
+    <Content Include="..\nativelibs\macosx_x64\libgrpc_csharp_ext.dylib">
+      <PackagePath>runtimes/osx/native/libgrpc_csharp_ext.x64.dylib</PackagePath>
+      <Pack>true</Pack>
+    </Content>
+    <Content Include="..\nativelibs\macosx_x86\libgrpc_csharp_ext.dylib">
+      <PackagePath>runtimes/osx/native/libgrpc_csharp_ext.x86.dylib</PackagePath>
+      <Pack>true</Pack>
+    </Content>
+    <Content Include="..\nativelibs\linux_x64\libgrpc_csharp_ext.so">
+      <PackagePath>runtimes/linux/native/libgrpc_csharp_ext.x64.so</PackagePath>
+      <Pack>true</Pack>
+    </Content>
+    <Content Include="..\nativelibs\linux_x86\libgrpc_csharp_ext.so">
+      <PackagePath>runtimes/linux/native/libgrpc_csharp_ext.x86.so</PackagePath>
+      <Pack>true</Pack>
+    </Content>
+    <Content Include="..\nativelibs\windows_x64\grpc_csharp_ext.dll">
+      <PackagePath>runtimes/win/native/grpc_csharp_ext.x64.dll</PackagePath>
+      <Pack>true</Pack>
+    </Content>
+    <Content Include="..\nativelibs\windows_x86\grpc_csharp_ext.dll">
+      <PackagePath>runtimes/win/native/grpc_csharp_ext.x86.dll</PackagePath>
+      <Pack>true</Pack>
+    </Content>
+    <Content Include="Grpc.Core.targets">
+      <PackagePath>build/net45/</PackagePath>
+      <Pack>true</Pack>
+    </Content>
   </ItemGroup>
+
   <ItemGroup>
-    <Compile Include="AsyncDuplexStreamingCall.cs" />
-    <Compile Include="AsyncServerStreamingCall.cs" />
-    <Compile Include="AsyncAuthInterceptor.cs" />
-    <Compile Include="CallCredentials.cs" />
-    <Compile Include="IClientStreamWriter.cs" />
-    <Compile Include="Internal\NativeMethods.cs" />
-    <Compile Include="Internal\PlatformApis.cs" />
-    <Compile Include="Internal\NativeExtension.cs" />
-    <Compile Include="Internal\UnmanagedLibrary.cs" />
-    <Compile Include="Internal\NativeMetadataCredentialsPlugin.cs" />
-    <Compile Include="Internal\INativeCall.cs" />
-    <Compile Include="IServerStreamWriter.cs" />
-    <Compile Include="IAsyncStreamWriter.cs" />
-    <Compile Include="IAsyncStreamReader.cs" />
-    <Compile Include="Logging\TextWriterLogger.cs" />
-    <Compile Include="Logging\NullLogger.cs" />
-    <Compile Include="ServerPort.cs" />
-    <Compile Include="Version.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="RpcException.cs" />
-    <Compile Include="Calls.cs" />
-    <Compile Include="AsyncClientStreamingCall.cs" />
-    <Compile Include="GrpcEnvironment.cs" />
-    <Compile Include="Status.cs" />
-    <Compile Include="StatusCode.cs" />
-    <Compile Include="Server.cs" />
-    <Compile Include="Channel.cs" />
-    <Compile Include="Internal\CallSafeHandle.cs" />
-    <Compile Include="Internal\ChannelSafeHandle.cs" />
-    <Compile Include="Internal\CompletionQueueSafeHandle.cs" />
-    <Compile Include="Internal\SafeHandleZeroIsInvalid.cs" />
-    <Compile Include="Internal\Timespec.cs" />
-    <Compile Include="Internal\GrpcThreadPool.cs" />
-    <Compile Include="Internal\ServerSafeHandle.cs" />
-    <Compile Include="Method.cs" />
-    <Compile Include="Internal\ServerCallHandler.cs" />
-    <Compile Include="Marshaller.cs" />
-    <Compile Include="ServerServiceDefinition.cs" />
-    <Compile Include="Utils\AsyncStreamExtensions.cs" />
-    <Compile Include="Utils\BenchmarkUtil.cs" />
-    <Compile Include="ChannelCredentials.cs" />
-    <Compile Include="Internal\ChannelArgsSafeHandle.cs" />
-    <Compile Include="Internal\AsyncCallBase.cs" />
-    <Compile Include="Internal\AsyncCallServer.cs" />
-    <Compile Include="Internal\AsyncCall.cs" />
-    <Compile Include="Internal\ServerCredentialsSafeHandle.cs" />
-    <Compile Include="ServerCredentials.cs" />
-    <Compile Include="Metadata.cs" />
-    <Compile Include="Internal\MetadataArraySafeHandle.cs" />
-    <Compile Include="ClientBase.cs" />
-    <Compile Include="Internal\ServerCalls.cs" />
-    <Compile Include="ServerMethods.cs" />
-    <Compile Include="Internal\ClientRequestStream.cs" />
-    <Compile Include="Internal\ClientResponseStream.cs" />
-    <Compile Include="Internal\ServerRequestStream.cs" />
-    <Compile Include="Internal\ServerResponseStream.cs" />
-    <Compile Include="Internal\AtomicCounter.cs" />
-    <Compile Include="Internal\DebugStats.cs" />
-    <Compile Include="ServerCallContext.cs" />
-    <Compile Include="Internal\CompletionQueueEvent.cs" />
-    <Compile Include="Internal\CompletionRegistry.cs" />
-    <Compile Include="Internal\BatchContextSafeHandle.cs" />
-    <Compile Include="ChannelOptions.cs" />
-    <Compile Include="AsyncUnaryCall.cs" />
-    <Compile Include="VersionInfo.cs" />
-    <Compile Include="Internal\CStringSafeHandle.cs" />
-    <Compile Include="KeyCertificatePair.cs" />
-    <Compile Include="Logging\ILogger.cs" />
-    <Compile Include="Logging\ConsoleLogger.cs" />
-    <Compile Include="Internal\NativeLogRedirector.cs" />
-    <Compile Include="ChannelState.cs" />
-    <Compile Include="CallInvocationDetails.cs" />
-    <Compile Include="CallOptions.cs" />
-    <Compile Include="CompressionLevel.cs" />
-    <Compile Include="WriteOptions.cs" />
-    <Compile Include="ContextPropagationToken.cs" />
-    <Compile Include="Internal\CallCredentialsSafeHandle.cs" />
-    <Compile Include="Internal\ChannelCredentialsSafeHandle.cs" />
-    <Compile Include="Profiling\ProfilerEntry.cs" />
-    <Compile Include="Profiling\ProfilerScope.cs" />
-    <Compile Include="Profiling\IProfiler.cs" />
-    <Compile Include="Profiling\Profilers.cs" />
-    <Compile Include="Internal\DefaultSslRootsOverride.cs" />
-    <Compile Include="Utils\GrpcPreconditions.cs" />
-    <Compile Include="CallInvoker.cs" />
-    <Compile Include="DefaultCallInvoker.cs" />
-    <Compile Include="Internal\UnimplementedCallInvoker.cs" />
-    <Compile Include="Internal\InterceptingCallInvoker.cs" />
-    <Compile Include="Internal\ServerRpcNew.cs" />
-    <Compile Include="Internal\ClientSideStatus.cs" />
-    <Compile Include="Internal\ClockType.cs" />
-    <Compile Include="Internal\CallError.cs" />
-    <Compile Include="Logging\LogLevel.cs" />
-    <Compile Include="Logging\LogLevelFilterLogger.cs" />
-    <Compile Include="Internal\RequestCallContextSafeHandle.cs" />
-    <Compile Include="Utils\TaskUtils.cs" />
-    <Compile Include="Internal\CallFlags.cs" />
+    <PackageReference Include="System.Interactive.Async" Version="3.1.1" />
   </ItemGroup>
-  <ItemGroup>
-    <None Include="Grpc.Core.project.json" />
-    <None Include="packages.config" />
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
-  <Import Project="NativeDeps.targets" />
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <ItemGroup />
-  <ItemGroup>
-    <EmbeddedResource Include="..\..\..\etc\roots.pem">
-      <Link>roots.pem</Link>
-    </EmbeddedResource>
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.5' ">
+    <PackageReference Include="System.Runtime.Loader" Version="4.0.0" />
+    <PackageReference Include="System.Threading.Thread" Version="4.0.0" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+
+  <Import Project="NativeDeps.csproj.include" />
+
+</Project>
diff --git a/src/csharp/Grpc.Core/Grpc.Core.project.json b/src/csharp/Grpc.Core/Grpc.Core.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Core/Grpc.Core.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.Core/Grpc.Core.xproj b/src/csharp/Grpc.Core/Grpc.Core.xproj
deleted file mode 100644
index 137236ffdb61daa99a602132898d869bb2c35f14..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Core/Grpc.Core.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>dc9908b6-f291-4fc8-a46d-2ea2551790ec</ProjectGuid>
-    <RootNamespace>Grpc.Core</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index 1f738a3b6f9995e5f236674718df7a2905f9c067..f037b2351af1ff989383024b171a9d3165ca7dc0 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -87,7 +87,7 @@ namespace Grpc.Core.Internal
             var profiler = Profilers.ForCurrentThread();
 
             using (profiler.NewScope("AsyncCall.UnaryCall"))
-            using (CompletionQueueSafeHandle cq = CompletionQueueSafeHandle.Create())
+            using (CompletionQueueSafeHandle cq = CompletionQueueSafeHandle.CreateSync())
             {
                 byte[] payload = UnsafeSerialize(msg);
 
diff --git a/src/csharp/Grpc.Core/Internal/AuthContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/AuthContextSafeHandle.cs
new file mode 100644
index 0000000000000000000000000000000000000000..59e33a0fdf16472e79c2f8ba4d487d2eeafc3d73
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/AuthContextSafeHandle.cs
@@ -0,0 +1,119 @@
+#region Copyright notice and license
+
+// Copyright 2017, 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.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+using Grpc.Core;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core.Internal
+{
+    /// <summary>
+    /// grpc_auth_context
+    /// </summary>
+    internal class AuthContextSafeHandle : SafeHandleZeroIsInvalid
+    {
+        static readonly NativeMethods Native = NativeMethods.Get();
+
+        private AuthContextSafeHandle()
+        {
+        }
+
+        /// <summary>
+        /// Copies contents of the native auth context into a new <c>AuthContext</c> instance.
+        /// </summary>
+        public AuthContext ToAuthContext()
+        {
+            if (IsInvalid)
+            {
+                return new AuthContext(null, new Dictionary<string, List<AuthProperty>>());
+            }
+
+            var peerIdentityPropertyName = Marshal.PtrToStringAnsi(Native.grpcsharp_auth_context_peer_identity_property_name(this));
+
+            var propertiesDict = new Dictionary<string, List<AuthProperty>>();
+
+            var it = Native.grpcsharp_auth_context_property_iterator(this);
+            IntPtr authPropertyPtr = IntPtr.Zero;
+            while ((authPropertyPtr = Native.grpcsharp_auth_property_iterator_next(ref it)) != IntPtr.Zero)
+            {
+                var authProperty = PtrToAuthProperty(authPropertyPtr);
+
+                if (!propertiesDict.ContainsKey(authProperty.Name))
+                {
+                    propertiesDict[authProperty.Name] = new List<AuthProperty>();
+                }
+                propertiesDict[authProperty.Name].Add(authProperty);
+            }
+
+            return new AuthContext(peerIdentityPropertyName, propertiesDict);
+        }
+
+        protected override bool ReleaseHandle()
+        {
+            Native.grpcsharp_auth_context_release(handle);
+            return true;
+        }
+
+        private AuthProperty PtrToAuthProperty(IntPtr authPropertyPtr)
+        {
+            var nativeAuthProperty = (NativeAuthProperty) Marshal.PtrToStructure(authPropertyPtr, typeof(NativeAuthProperty));
+            var name = Marshal.PtrToStringAnsi(nativeAuthProperty.Name);
+            var valueBytes = new byte[(int) nativeAuthProperty.ValueLength];
+            Marshal.Copy(nativeAuthProperty.Value, valueBytes, 0, (int)nativeAuthProperty.ValueLength);
+            return AuthProperty.CreateUnsafe(name, valueBytes);
+        }
+
+        /// <summary>
+        /// grpc_auth_property
+        /// </summary>
+        internal struct NativeAuthProperty
+        {
+            public IntPtr Name;
+            public IntPtr Value;
+            public UIntPtr ValueLength;
+        }
+
+        /// <summary>
+        /// grpc_auth_property_iterator
+        /// </summary>
+        internal struct NativeAuthPropertyIterator
+        {
+            public IntPtr AuthContext;
+            public UIntPtr Index;
+            public IntPtr Name;
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
index efae149f09818f1b1bdca2b0b9759f18d31f776a..6dee6d8c352436432c140a7aeec7b85a15d0f159 100644
--- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
@@ -43,7 +43,6 @@ namespace Grpc.Core.Internal
     /// </summary>
     internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid
     {
-        static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8;
         static readonly NativeMethods Native = NativeMethods.Get();
 
         private BatchContextSafeHandle()
@@ -75,7 +74,7 @@ namespace Grpc.Core.Internal
         {
             UIntPtr detailsLength;
             IntPtr detailsPtr = Native.grpcsharp_batch_context_recv_status_on_client_details(this, out detailsLength);
-            string details = PtrToStringUtf8(detailsPtr, (int) detailsLength.ToUInt32());
+            string details = MarshalUtils.PtrToStringUTF8(detailsPtr, (int) detailsLength.ToUInt32());
             var status = new Status(Native.grpcsharp_batch_context_recv_status_on_client_status(this), details);
 
             IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this);
@@ -108,12 +107,5 @@ namespace Grpc.Core.Internal
             Native.grpcsharp_batch_context_destroy(handle);
             return true;
         }
-
-        string PtrToStringUtf8(IntPtr ptr, int len)
-        {
-            var bytes = new byte[len];
-            Marshal.Copy(ptr, bytes, 0, len);
-            return EncodingUTF8.GetString(bytes);
-        }
     }
 }
diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
index 710ca480e88b7f2362eb4018d82b7548eeae1e9a..3c368fbc6cd9e132ab152efc894276862ee9604a 100644
--- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
@@ -45,7 +45,6 @@ namespace Grpc.Core.Internal
     internal class CallSafeHandle : SafeHandleZeroIsInvalid, INativeCall
     {
         public static readonly CallSafeHandle NullInstance = new CallSafeHandle();
-        static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8;
         static readonly NativeMethods Native = NativeMethods.Get();
 
         const uint GRPC_WRITE_BUFFER_HINT = 1;
@@ -140,7 +139,7 @@ namespace Grpc.Core.Internal
                 var ctx = BatchContextSafeHandle.Create();
                 var optionalPayloadLength = optionalPayload != null ? new UIntPtr((ulong)optionalPayload.Length) : UIntPtr.Zero;
                 completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
-                var statusDetailBytes = EncodingUTF8.GetBytes(status.Detail);
+                var statusDetailBytes = MarshalUtils.GetBytesUTF8(status.Detail);
                 Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, statusDetailBytes, new UIntPtr((ulong)statusDetailBytes.Length), metadataArray, sendEmptyInitialMetadata,
                     optionalPayload, optionalPayloadLength, writeFlags).CheckOk();
             }
@@ -204,6 +203,11 @@ namespace Grpc.Core.Internal
             }
         }
 
+        public AuthContextSafeHandle GetAuthContext()
+        {
+            return Native.grpcsharp_call_auth_context(this);
+        }
+
         protected override bool ReleaseHandle()
         {
             Native.grpcsharp_call_destroy(handle);
diff --git a/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
index 6c9a31921ebf8245114fe4aca1f7e7251233c1f5..577d7044a578fdc45ce3c69148940ada39af6f8e 100644
--- a/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
@@ -51,14 +51,20 @@ namespace Grpc.Core.Internal
         {
         }
 
-        public static CompletionQueueSafeHandle Create()
+        /// <summary>
+        /// Create a completion queue that can only be used for Pluck operations.
+        /// </summary>
+        public static CompletionQueueSafeHandle CreateSync()
         {
-            return Native.grpcsharp_completion_queue_create();
+            return Native.grpcsharp_completion_queue_create_sync();
         }
 
-        public static CompletionQueueSafeHandle Create(CompletionRegistry completionRegistry)
+        /// <summary>
+        /// Create a completion queue that can only be used for Next operations.
+        /// </summary>
+        public static CompletionQueueSafeHandle CreateAsync(CompletionRegistry completionRegistry)
         {
-            var cq = Native.grpcsharp_completion_queue_create();
+            var cq = Native.grpcsharp_completion_queue_create_async();
             cq.completionRegistry = completionRegistry;
             return cq;
         }
diff --git a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
index 7e2f0e9c6c9ed4803309e76e1a2cdc459d9ae892..a4aa8d3ffe42b37d6ca6234e2480be18f783cb71 100644
--- a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
+++ b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
@@ -51,7 +51,7 @@ namespace Grpc.Core.Internal
         static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<CompletionRegistry>();
 
         readonly GrpcEnvironment environment;
-        readonly ConcurrentDictionary<IntPtr, OpCompletionDelegate> dict = new ConcurrentDictionary<IntPtr, OpCompletionDelegate>();
+        readonly ConcurrentDictionary<IntPtr, OpCompletionDelegate> dict = new ConcurrentDictionary<IntPtr, OpCompletionDelegate>(new IntPtrComparer());
 
         public CompletionRegistry(GrpcEnvironment environment)
         {
@@ -121,5 +121,21 @@ namespace Grpc.Core.Internal
                 }
             }
         }
+
+        /// <summary>
+        /// IntPtr doesn't implement <c>IEquatable{IntPtr}</c> so we need to use custom comparer to avoid boxing.
+        /// </summary>
+        private class IntPtrComparer : IEqualityComparer<IntPtr>
+        {
+            public bool Equals(IntPtr x, IntPtr y)
+            {
+                return x == y;
+            }
+
+            public int GetHashCode(IntPtr obj)
+            {
+                return obj.GetHashCode();
+            }
+        }
     }
 }
diff --git a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
index 25a6589f115e9bf2315901a7dda7b7d708010a19..07fea812b2ad083d8b5a24370c0e27422c9fdb57 100644
--- a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
+++ b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
@@ -197,7 +197,7 @@ namespace Grpc.Core.Internal
             for (int i = 0; i < completionQueueCount; i++)
             {
                 var completionRegistry = new CompletionRegistry(environment);
-                list.Add(CompletionQueueSafeHandle.Create(completionRegistry));
+                list.Add(CompletionQueueSafeHandle.CreateAsync(completionRegistry));
             }
             return list.AsReadOnly();
         }
diff --git a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs
new file mode 100644
index 0000000000000000000000000000000000000000..897e2f70bb47d65ba75de419107dda193f843b13
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs
@@ -0,0 +1,90 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Grpc.Core.Internal
+{
+    /// <summary>
+    /// Useful methods for native/managed marshalling.
+    /// </summary>
+    internal static class MarshalUtils
+    {
+        static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8;
+        static readonly Encoding EncodingASCII = System.Text.Encoding.ASCII;
+
+        /// <summary>
+        /// Converts <c>IntPtr</c> pointing to a UTF-8 encoded byte array to <c>string</c>.
+        /// </summary>
+        public static string PtrToStringUTF8(IntPtr ptr, int len)
+        {
+            var bytes = new byte[len];
+            Marshal.Copy(ptr, bytes, 0, len);
+            return EncodingUTF8.GetString(bytes);
+        }
+
+        /// <summary>
+        /// Returns byte array containing UTF-8 encoding of given string.
+        /// </summary>
+        public static byte[] GetBytesUTF8(string str)
+        {
+            return EncodingUTF8.GetBytes(str);
+        }
+
+        /// <summary>
+        /// Get string from a UTF8 encoded byte array.
+        /// </summary>
+        public static string GetStringUTF8(byte[] bytes)
+        {
+            return EncodingUTF8.GetString(bytes);
+        }
+
+        /// <summary>
+        /// Returns byte array containing ASCII encoding of given string.
+        /// </summary>
+        public static byte[] GetBytesASCII(string str)
+        {
+            return EncodingASCII.GetBytes(str);
+        }
+
+        /// <summary>
+        /// Get string from an ASCII encoded byte array.
+        /// </summary>
+        public static string GetStringASCII(byte[] bytes)
+        {
+            return EncodingASCII.GetString(bytes);
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.cs
index aff9550e8d24b6612be00815f025e4a3d18e489c..a98861af616390c3595fec12d98bfbf4c3a21782 100644
--- a/src/csharp/Grpc.Core/Internal/NativeMethods.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeMethods.cs
@@ -115,7 +115,8 @@ namespace Grpc.Core.Internal
 
         public readonly Delegates.grpcsharp_sizeof_grpc_event_delegate grpcsharp_sizeof_grpc_event;
 
-        public readonly Delegates.grpcsharp_completion_queue_create_delegate grpcsharp_completion_queue_create;
+        public readonly Delegates.grpcsharp_completion_queue_create_async_delegate grpcsharp_completion_queue_create_async;
+        public readonly Delegates.grpcsharp_completion_queue_create_sync_delegate grpcsharp_completion_queue_create_sync;
         public readonly Delegates.grpcsharp_completion_queue_shutdown_delegate grpcsharp_completion_queue_shutdown;
         public readonly Delegates.grpcsharp_completion_queue_next_delegate grpcsharp_completion_queue_next;
         public readonly Delegates.grpcsharp_completion_queue_pluck_delegate grpcsharp_completion_queue_pluck;
@@ -148,6 +149,12 @@ namespace Grpc.Core.Internal
         public readonly Delegates.grpcsharp_server_shutdown_and_notify_callback_delegate grpcsharp_server_shutdown_and_notify_callback;
         public readonly Delegates.grpcsharp_server_destroy_delegate grpcsharp_server_destroy;
 
+        public readonly Delegates.grpcsharp_call_auth_context_delegate grpcsharp_call_auth_context;
+        public readonly Delegates.grpcsharp_auth_context_peer_identity_property_name_delegate grpcsharp_auth_context_peer_identity_property_name;
+        public readonly Delegates.grpcsharp_auth_context_property_iterator_delegate grpcsharp_auth_context_property_iterator;
+        public readonly Delegates.grpcsharp_auth_property_iterator_next_delegate grpcsharp_auth_property_iterator_next;
+        public readonly Delegates.grpcsharp_auth_context_release_delegate grpcsharp_auth_context_release;
+
         public readonly Delegates.gprsharp_now_delegate gprsharp_now;
         public readonly Delegates.gprsharp_inf_future_delegate gprsharp_inf_future;
         public readonly Delegates.gprsharp_inf_past_delegate gprsharp_inf_past;
@@ -223,7 +230,8 @@ namespace Grpc.Core.Internal
 
             this.grpcsharp_sizeof_grpc_event = GetMethodDelegate<Delegates.grpcsharp_sizeof_grpc_event_delegate>(library);
 
-            this.grpcsharp_completion_queue_create = GetMethodDelegate<Delegates.grpcsharp_completion_queue_create_delegate>(library);
+            this.grpcsharp_completion_queue_create_async = GetMethodDelegate<Delegates.grpcsharp_completion_queue_create_async_delegate>(library);
+            this.grpcsharp_completion_queue_create_sync = GetMethodDelegate<Delegates.grpcsharp_completion_queue_create_sync_delegate>(library);
             this.grpcsharp_completion_queue_shutdown = GetMethodDelegate<Delegates.grpcsharp_completion_queue_shutdown_delegate>(library);
             this.grpcsharp_completion_queue_next = GetMethodDelegate<Delegates.grpcsharp_completion_queue_next_delegate>(library);
             this.grpcsharp_completion_queue_pluck = GetMethodDelegate<Delegates.grpcsharp_completion_queue_pluck_delegate>(library);
@@ -256,6 +264,12 @@ namespace Grpc.Core.Internal
             this.grpcsharp_server_shutdown_and_notify_callback = GetMethodDelegate<Delegates.grpcsharp_server_shutdown_and_notify_callback_delegate>(library);
             this.grpcsharp_server_destroy = GetMethodDelegate<Delegates.grpcsharp_server_destroy_delegate>(library);
 
+            this.grpcsharp_call_auth_context = GetMethodDelegate<Delegates.grpcsharp_call_auth_context_delegate>(library);
+            this.grpcsharp_auth_context_peer_identity_property_name = GetMethodDelegate<Delegates.grpcsharp_auth_context_peer_identity_property_name_delegate>(library);
+            this.grpcsharp_auth_context_property_iterator = GetMethodDelegate<Delegates.grpcsharp_auth_context_property_iterator_delegate>(library);
+            this.grpcsharp_auth_property_iterator_next = GetMethodDelegate<Delegates.grpcsharp_auth_property_iterator_next_delegate>(library);
+            this.grpcsharp_auth_context_release = GetMethodDelegate<Delegates.grpcsharp_auth_context_release_delegate>(library);
+
             this.gprsharp_now = GetMethodDelegate<Delegates.gprsharp_now_delegate>(library);
             this.gprsharp_inf_future = GetMethodDelegate<Delegates.gprsharp_inf_future_delegate>(library);
             this.gprsharp_inf_past = GetMethodDelegate<Delegates.gprsharp_inf_past_delegate>(library);
@@ -371,7 +385,8 @@ namespace Grpc.Core.Internal
 
             public delegate int grpcsharp_sizeof_grpc_event_delegate();
 
-            public delegate CompletionQueueSafeHandle grpcsharp_completion_queue_create_delegate();
+            public delegate CompletionQueueSafeHandle grpcsharp_completion_queue_create_async_delegate();
+            public delegate CompletionQueueSafeHandle grpcsharp_completion_queue_create_sync_delegate();
             public delegate void grpcsharp_completion_queue_shutdown_delegate(CompletionQueueSafeHandle cq);
             public delegate CompletionQueueEvent grpcsharp_completion_queue_next_delegate(CompletionQueueSafeHandle cq);
             public delegate CompletionQueueEvent grpcsharp_completion_queue_pluck_delegate(CompletionQueueSafeHandle cq, IntPtr tag);
@@ -404,6 +419,12 @@ namespace Grpc.Core.Internal
             public delegate void grpcsharp_server_shutdown_and_notify_callback_delegate(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
             public delegate void grpcsharp_server_destroy_delegate(IntPtr server);
 
+            public delegate AuthContextSafeHandle grpcsharp_call_auth_context_delegate(CallSafeHandle call);
+            public delegate IntPtr grpcsharp_auth_context_peer_identity_property_name_delegate(AuthContextSafeHandle authContext);  // returns const char*
+            public delegate AuthContextSafeHandle.NativeAuthPropertyIterator grpcsharp_auth_context_property_iterator_delegate(AuthContextSafeHandle authContext);
+            public delegate IntPtr grpcsharp_auth_property_iterator_next_delegate(ref AuthContextSafeHandle.NativeAuthPropertyIterator iterator);  // returns const auth_property*
+            public delegate void grpcsharp_auth_context_release_delegate(IntPtr authContext);
+
             public delegate Timespec gprsharp_now_delegate(ClockType clockType);
             public delegate Timespec gprsharp_inf_future_delegate(ClockType clockType);
             public delegate Timespec gprsharp_inf_past_delegate(ClockType clockType);
diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core/Metadata.cs
index 6fc715d6ee1a8c75a935044f194faf25bd7ba476..6e195b49ccd5dc7ab6855e12145c41a8e036f673 100644
--- a/src/csharp/Grpc.Core/Metadata.cs
+++ b/src/csharp/Grpc.Core/Metadata.cs
@@ -32,12 +32,10 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Globalization;
-using System.Runtime.InteropServices;
 using System.Text;
 using System.Text.RegularExpressions;
 
+using Grpc.Core.Internal;
 using Grpc.Core.Utils;
 
 namespace Grpc.Core
@@ -242,7 +240,6 @@ namespace Grpc.Core
         /// </summary>
         public class Entry
         {
-            private static readonly Encoding Encoding = Encoding.ASCII;
             private static readonly Regex ValidKeyRegex = new Regex("^[a-z0-9_-]+$");
 
             readonly string key;
@@ -306,7 +303,7 @@ namespace Grpc.Core
                 {
                     if (valueBytes == null)
                     {
-                        return Encoding.GetBytes(value);
+                        return MarshalUtils.GetBytesASCII(value);
                     }
 
                     // defensive copy to guarantee immutability
@@ -324,7 +321,7 @@ namespace Grpc.Core
                 get
                 {
                     GrpcPreconditions.CheckState(!IsBinary, "Cannot access string value of a binary metadata entry");
-                    return value ?? Encoding.GetString(valueBytes);
+                    return value ?? MarshalUtils.GetStringASCII(valueBytes);
                 }
             }
 
@@ -358,7 +355,7 @@ namespace Grpc.Core
             /// </summary>
             internal byte[] GetSerializedValueUnsafe()
             {
-                return valueBytes ?? Encoding.GetBytes(value);
+                return valueBytes ?? MarshalUtils.GetBytesASCII(value);
             }
 
             /// <summary>
@@ -371,7 +368,7 @@ namespace Grpc.Core
                 {
                     return new Entry(key, null, valueBytes);
                 }
-                return new Entry(key, Encoding.GetString(valueBytes), null);
+                return new Entry(key, MarshalUtils.GetStringASCII(valueBytes), null);
             }
 
             private static string NormalizeKey(string key)
diff --git a/src/csharp/Grpc.Core/NativeDeps.Linux.targets b/src/csharp/Grpc.Core/NativeDeps.Linux.csproj.include
similarity index 63%
rename from src/csharp/Grpc.Core/NativeDeps.Linux.targets
rename to src/csharp/Grpc.Core/NativeDeps.Linux.csproj.include
index e0c9132b1d5fe4db01aa01c8038ff5b5e5d0d7e8..e3bbeb071e758cefd9d71e4e213a7aa0ce404c26 100644
--- a/src/csharp/Grpc.Core/NativeDeps.Linux.targets
+++ b/src/csharp/Grpc.Core/NativeDeps.Linux.csproj.include
@@ -1,9 +1,9 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project>
   <ItemGroup>
     <Content Include="..\..\..\libs\$(NativeDependenciesConfigurationUnix)\libgrpc_csharp_ext.so">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
       <Link>libgrpc_csharp_ext.x64.so</Link>
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+      <Pack>false</Pack>
     </Content>
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core/NativeDeps.Mac.csproj.include b/src/csharp/Grpc.Core/NativeDeps.Mac.csproj.include
new file mode 100644
index 0000000000000000000000000000000000000000..f1b85c3730e49dd64a85f2c5739f6b9dd8ab5cee
--- /dev/null
+++ b/src/csharp/Grpc.Core/NativeDeps.Mac.csproj.include
@@ -0,0 +1,17 @@
+<Project>
+  <ItemGroup>
+    <!-- We are relying on run_tests.py to build grpc_csharp_ext with the right bitness
+    and we copy it as both x86 (needed by net45) and x64 (needed by netcoreapp1.0) as we don't
+    know which one will be needed to run the tests. -->
+    <Content Include="..\..\..\libs\$(NativeDependenciesConfigurationUnix)\libgrpc_csharp_ext.dylib">
+      <Link>libgrpc_csharp_ext.x86.dylib</Link>
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+      <Pack>false</Pack>
+    </Content>
+    <Content Include="..\..\..\libs\$(NativeDependenciesConfigurationUnix)\libgrpc_csharp_ext.dylib">
+      <Link>libgrpc_csharp_ext.x64.dylib</Link>
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+      <Pack>false</Pack>
+    </Content>
+  </ItemGroup>
+</Project>
diff --git a/src/csharp/Grpc.Core/NativeDeps.Mac.targets b/src/csharp/Grpc.Core/NativeDeps.Mac.targets
deleted file mode 100644
index e22c7384fc5b8680870ef6da43884ea80133a47c..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Core/NativeDeps.Mac.targets
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Content Include="..\..\..\libs\$(NativeDependenciesConfigurationUnix)\libgrpc_csharp_ext.dylib">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-      <Link>libgrpc_csharp_ext.x86.dylib</Link>
-    </Content>
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core/NativeDeps.Windows.csproj.include b/src/csharp/Grpc.Core/NativeDeps.Windows.csproj.include
new file mode 100644
index 0000000000000000000000000000000000000000..04f3b077ace0d8d28c2361ad7bc148e6c4d7122c
--- /dev/null
+++ b/src/csharp/Grpc.Core/NativeDeps.Windows.csproj.include
@@ -0,0 +1,9 @@
+<Project>
+  <ItemGroup>
+    <Content Include="..\..\..\cmake\build\x64\$(NativeDependenciesConfiguration)\grpc_csharp_ext.dll">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+      <Link>grpc_csharp_ext.x64.dll</Link>
+      <Pack>false</Pack>
+    </Content>
+  </ItemGroup>
+</Project>
diff --git a/src/csharp/Grpc.Core/NativeDeps.Windows.targets b/src/csharp/Grpc.Core/NativeDeps.Windows.targets
deleted file mode 100644
index 623f58b95b0b9353b6b5df86d4f6a68d7dc15c4a..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Core/NativeDeps.Windows.targets
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Content Include="..\..\..\cmake\build\Win32\$(NativeDependenciesConfiguration)\grpc_csharp_ext.dll">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-      <Link>grpc_csharp_ext.x86.dll</Link>
-    </Content>
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core/NativeDeps.targets b/src/csharp/Grpc.Core/NativeDeps.csproj.include
old mode 100644
new mode 100755
similarity index 83%
rename from src/csharp/Grpc.Core/NativeDeps.targets
rename to src/csharp/Grpc.Core/NativeDeps.csproj.include
index e187f72d266bd46d5f5ce0385926c7d1a53ee942..a62c63e11d09d2548ce2441cf6a46486f6d8f6c7
--- a/src/csharp/Grpc.Core/NativeDeps.targets
+++ b/src/csharp/Grpc.Core/NativeDeps.csproj.include
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<!-- Ensures that native libraries are copied to the output directory for Exe targets -->
+<Project>
 
   <PropertyGroup Condition=" '$(NativeDependenciesConfiguration)' == '' ">
     <NativeDependenciesConfiguration Condition=" '$(Configuration)' == 'Debug' ">Debug</NativeDependenciesConfiguration>
@@ -22,5 +22,6 @@
     <NativeDepsPlatform>Linux</NativeDepsPlatform>
   </PropertyGroup>
 
-  <Import Project="NativeDeps.$(NativeDepsPlatform).targets" />
-</Project>
\ No newline at end of file
+  <Import Project="NativeDeps.$(NativeDepsPlatform).csproj.include" />
+
+</Project>
diff --git a/src/csharp/Grpc.Core/ServerCallContext.cs b/src/csharp/Grpc.Core/ServerCallContext.cs
index 8f28fbc045339a2ddc59d8529cc25e4722443423..c8950b7677930782e7ab5e63136df96f6fe44a2a 100644
--- a/src/csharp/Grpc.Core/ServerCallContext.cs
+++ b/src/csharp/Grpc.Core/ServerCallContext.cs
@@ -32,7 +32,6 @@
 #endregion
 
 using System;
-using System.Runtime.CompilerServices;
 using System.Threading;
 using System.Threading.Tasks;
 
@@ -56,6 +55,7 @@ namespace Grpc.Core
         private Status status = Status.DefaultSuccess;
         private Func<Metadata, Task> writeHeadersFunc;
         private IHasWriteOptions writeOptionsHolder;
+        private Lazy<AuthContext> authContext;
 
         internal ServerCallContext(CallSafeHandle callHandle, string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken,
             Func<Metadata, Task> writeHeadersFunc, IHasWriteOptions writeOptionsHolder)
@@ -68,6 +68,7 @@ namespace Grpc.Core
             this.cancellationToken = cancellationToken;
             this.writeHeadersFunc = writeHeadersFunc;
             this.writeOptionsHolder = writeOptionsHolder;
+            this.authContext = new Lazy<AuthContext>(GetAuthContextEager);
         }
 
         /// <summary>
@@ -187,6 +188,26 @@ namespace Grpc.Core
                 writeOptionsHolder.WriteOptions = value;
             }
         }
+
+        /// <summary>
+        /// Gets the <c>AuthContext</c> associated with this call.
+        /// Note: Access to AuthContext is an experimental API that can change without any prior notice.
+        /// </summary>
+        public AuthContext AuthContext
+        {
+            get
+            {
+                return authContext.Value;
+            }
+        }
+
+        private AuthContext GetAuthContextEager()
+        {
+            using (var authContextNative = callHandle.GetAuthContext())
+            {
+                return authContextNative.ToAuthContext();
+            }
+        }
     }
 
     /// <summary>
diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include
new file mode 100755
index 0000000000000000000000000000000000000000..6af2af10bd00cc6d67c0ff88968acfc6b61c2d01
--- /dev/null
+++ b/src/csharp/Grpc.Core/Version.csproj.include
@@ -0,0 +1,7 @@
+<!-- This file is generated -->
+<Project>
+  <PropertyGroup>
+    <GrpcCsharpVersion>1.4.0-dev</GrpcCsharpVersion>
+    <GoogleProtobufVersion>3.2.0</GoogleProtobufVersion>
+  </PropertyGroup>
+</Project>
diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs
index f01a024db43f52c50ba1198e8230df452115cb4b..2e55d9d80eb45365b732c8995efe181670d9b653 100644
--- a/src/csharp/Grpc.Core/VersionInfo.cs
+++ b/src/csharp/Grpc.Core/VersionInfo.cs
@@ -48,11 +48,11 @@ namespace Grpc.Core
         /// <summary>
         /// Current <c>AssemblyFileVersion</c> of gRPC C# assemblies
         /// </summary>
-        public const string CurrentAssemblyFileVersion = "1.2.0.0";
+        public const string CurrentAssemblyFileVersion = "1.4.0.0";
 
         /// <summary>
         /// Current version of gRPC C#
         /// </summary>
-        public const string CurrentVersion = "1.2.0-dev";
+        public const string CurrentVersion = "1.4.0-dev";
     }
 }
diff --git a/src/csharp/Grpc.Core/packages.config b/src/csharp/Grpc.Core/packages.config
deleted file mode 100644
index 53cfad52f0bca1b3d030ddd2f3266170dcbe6801..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Core/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
-</packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core/project.json b/src/csharp/Grpc.Core/project.json
deleted file mode 100644
index 0e37ec8927f88b6524d64642d5f7eb22eafa4170..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Core/project.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
-  "version": "1.2.0-dev",
-  "title": "gRPC C# Core",
-  "authors": [ "Google Inc." ],
-  "copyright": "Copyright 2015, Google Inc.",
-  "packOptions": {
-    "summary": "Core C# implementation of gRPC - an RPC library and framework",
-    "description": "Core C# implementation of gRPC - an RPC library and framework. See project site for more info.",
-    "owners": [ "grpc-packages" ],
-    "licenseUrl": "https://github.com/grpc/grpc/blob/master/LICENSE",
-    "projectUrl": "https://github.com/grpc/grpc",
-    "requireLicenseAcceptance": false,
-    "tags": [ "gRPC RPC Protocol HTTP/2" ],
-    "files": {
-      "mappings": {
-        "build/net45/": "Grpc.Core.targets",
-        "runtimes/win/native/grpc_csharp_ext.x86.dll": "../nativelibs/windows_x86/grpc_csharp_ext.dll",
-        "runtimes/win/native/grpc_csharp_ext.x64.dll": "../nativelibs/windows_x64/grpc_csharp_ext.dll",
-        "runtimes/linux/native/libgrpc_csharp_ext.x86.so": "../nativelibs/linux_x86/libgrpc_csharp_ext.so",
-        "runtimes/linux/native/libgrpc_csharp_ext.x64.so": "../nativelibs/linux_x64/libgrpc_csharp_ext.so",
-        "runtimes/osx/native/libgrpc_csharp_ext.x86.dylib": "../nativelibs/macosx_x86/libgrpc_csharp_ext.dylib",
-        "runtimes/osx/native/libgrpc_csharp_ext.x64.dylib": "../nativelibs/macosx_x64/libgrpc_csharp_ext.dylib"
-      }
-    }
-  },
-  "buildOptions": {
-    "embed": [ "../../../etc/roots.pem" ],
-    "define": [ "SIGNED" ],
-    "keyFile": "../keys/Grpc.snk",
-    "xmlDoc": true
-  },
-  "dependencies": {
-    "System.Interactive.Async": "3.1.1"
-  },
-  "frameworks": {
-    "net45": { },
-    "netstandard1.5": {
-      "dependencies": {
-        "NETStandard.Library": "1.6.0",
-        "System.Runtime.Loader": "4.0.0",
-        "System.Threading.Thread": "4.0.0"
-      }
-    }
-  }
-}
diff --git a/src/csharp/Grpc.Dotnet.sln b/src/csharp/Grpc.Dotnet.sln
deleted file mode 100644
index 824c6822f7e9aec2a634f2b1739c2f1630af2a6a..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Dotnet.sln
+++ /dev/null
@@ -1,112 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25420.1
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.Core", "Grpc.Core\Grpc.Core.xproj", "{DC9908B6-F291-4FC8-A46D-2EA2551790EC}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.Auth", "Grpc.Auth\Grpc.Auth.xproj", "{C82631ED-06D1-4458-87BC-8257D12307A8}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.Core.Tests", "Grpc.Core.Tests\Grpc.Core.Tests.xproj", "{759E23B2-FC04-4695-902D-B073CDED3599}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.Examples", "Grpc.Examples\Grpc.Examples.xproj", "{C77B792D-FC78-4CE2-9522-B40B0803C636}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.Examples.MathClient", "Grpc.Examples.MathClient\Grpc.Examples.MathClient.xproj", "{FD48DECA-1622-4173-B1D9-2101CF5E7C5F}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.Examples.MathServer", "Grpc.Examples.MathServer\Grpc.Examples.MathServer.xproj", "{58579368-5372-4E67-ACD6-9B59CB9FA698}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.Examples.Tests", "Grpc.Examples.Tests\Grpc.Examples.Tests.xproj", "{C61714A6-F633-44FB-97F4-C91F425C1D15}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.HealthCheck", "Grpc.HealthCheck\Grpc.HealthCheck.xproj", "{3BE4AD0B-2BF0-4D68-B625-F6018EF0DCFA}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.HealthCheck.Tests", "Grpc.HealthCheck.Tests\Grpc.HealthCheck.Tests.xproj", "{43DAFAC6-5343-4621-960E-A8A977EA3F0B}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.IntegrationTesting", "Grpc.IntegrationTesting\Grpc.IntegrationTesting.xproj", "{20354386-3E71-4046-A269-3BC2A06F3EC8}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.IntegrationTesting.Client", "Grpc.IntegrationTesting.Client\Grpc.IntegrationTesting.Client.xproj", "{48EA5BBE-70E2-4198-869D-D7E59C45F30D}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.IntegrationTesting.QpsWorker", "Grpc.IntegrationTesting.QpsWorker\Grpc.IntegrationTesting.QpsWorker.xproj", "{661B70D7-F56A-46E0-9B81-6227B591B5E7}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.IntegrationTesting.Server", "Grpc.IntegrationTesting.Server\Grpc.IntegrationTesting.Server.xproj", "{881F7AD1-A84E-47A2-9402-115C63C4031E}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.IntegrationTesting.StressClient", "Grpc.IntegrationTesting.StressClient\Grpc.IntegrationTesting.StressClient.xproj", "{0EBC910B-8867-4D3E-8686-91F34183D839}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.Reflection", "Grpc.Reflection\Grpc.Reflection.xproj", "{2B372155-80BA-4CF9-82D6-4B938E8EC3A0}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.Reflection.Tests", "Grpc.Reflection.Tests\Grpc.Reflection.Tests.xproj", "{FE90181D-A4B3-4A5C-8490-F07561E18E3B}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
-		Release|Any CPU = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{DC9908B6-F291-4FC8-A46D-2EA2551790EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{DC9908B6-F291-4FC8-A46D-2EA2551790EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{DC9908B6-F291-4FC8-A46D-2EA2551790EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{DC9908B6-F291-4FC8-A46D-2EA2551790EC}.Release|Any CPU.Build.0 = Release|Any CPU
-		{C82631ED-06D1-4458-87BC-8257D12307A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{C82631ED-06D1-4458-87BC-8257D12307A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{C82631ED-06D1-4458-87BC-8257D12307A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{C82631ED-06D1-4458-87BC-8257D12307A8}.Release|Any CPU.Build.0 = Release|Any CPU
-		{759E23B2-FC04-4695-902D-B073CDED3599}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{759E23B2-FC04-4695-902D-B073CDED3599}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{759E23B2-FC04-4695-902D-B073CDED3599}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{759E23B2-FC04-4695-902D-B073CDED3599}.Release|Any CPU.Build.0 = Release|Any CPU
-		{C77B792D-FC78-4CE2-9522-B40B0803C636}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{C77B792D-FC78-4CE2-9522-B40B0803C636}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{C77B792D-FC78-4CE2-9522-B40B0803C636}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{C77B792D-FC78-4CE2-9522-B40B0803C636}.Release|Any CPU.Build.0 = Release|Any CPU
-		{FD48DECA-1622-4173-B1D9-2101CF5E7C5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{FD48DECA-1622-4173-B1D9-2101CF5E7C5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{FD48DECA-1622-4173-B1D9-2101CF5E7C5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{FD48DECA-1622-4173-B1D9-2101CF5E7C5F}.Release|Any CPU.Build.0 = Release|Any CPU
-		{58579368-5372-4E67-ACD6-9B59CB9FA698}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{58579368-5372-4E67-ACD6-9B59CB9FA698}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{58579368-5372-4E67-ACD6-9B59CB9FA698}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{58579368-5372-4E67-ACD6-9B59CB9FA698}.Release|Any CPU.Build.0 = Release|Any CPU
-		{C61714A6-F633-44FB-97F4-C91F425C1D15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{C61714A6-F633-44FB-97F4-C91F425C1D15}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{C61714A6-F633-44FB-97F4-C91F425C1D15}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{C61714A6-F633-44FB-97F4-C91F425C1D15}.Release|Any CPU.Build.0 = Release|Any CPU
-		{3BE4AD0B-2BF0-4D68-B625-F6018EF0DCFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{3BE4AD0B-2BF0-4D68-B625-F6018EF0DCFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{3BE4AD0B-2BF0-4D68-B625-F6018EF0DCFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{3BE4AD0B-2BF0-4D68-B625-F6018EF0DCFA}.Release|Any CPU.Build.0 = Release|Any CPU
-		{43DAFAC6-5343-4621-960E-A8A977EA3F0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{43DAFAC6-5343-4621-960E-A8A977EA3F0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{43DAFAC6-5343-4621-960E-A8A977EA3F0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{43DAFAC6-5343-4621-960E-A8A977EA3F0B}.Release|Any CPU.Build.0 = Release|Any CPU
-		{20354386-3E71-4046-A269-3BC2A06F3EC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{20354386-3E71-4046-A269-3BC2A06F3EC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{20354386-3E71-4046-A269-3BC2A06F3EC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{20354386-3E71-4046-A269-3BC2A06F3EC8}.Release|Any CPU.Build.0 = Release|Any CPU
-		{48EA5BBE-70E2-4198-869D-D7E59C45F30D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{48EA5BBE-70E2-4198-869D-D7E59C45F30D}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{48EA5BBE-70E2-4198-869D-D7E59C45F30D}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{48EA5BBE-70E2-4198-869D-D7E59C45F30D}.Release|Any CPU.Build.0 = Release|Any CPU
-		{661B70D7-F56A-46E0-9B81-6227B591B5E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{661B70D7-F56A-46E0-9B81-6227B591B5E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{661B70D7-F56A-46E0-9B81-6227B591B5E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{661B70D7-F56A-46E0-9B81-6227B591B5E7}.Release|Any CPU.Build.0 = Release|Any CPU
-		{881F7AD1-A84E-47A2-9402-115C63C4031E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{881F7AD1-A84E-47A2-9402-115C63C4031E}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{881F7AD1-A84E-47A2-9402-115C63C4031E}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{881F7AD1-A84E-47A2-9402-115C63C4031E}.Release|Any CPU.Build.0 = Release|Any CPU
-		{0EBC910B-8867-4D3E-8686-91F34183D839}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{0EBC910B-8867-4D3E-8686-91F34183D839}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{0EBC910B-8867-4D3E-8686-91F34183D839}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{0EBC910B-8867-4D3E-8686-91F34183D839}.Release|Any CPU.Build.0 = Release|Any CPU
-		{2B372155-80BA-4CF9-82D6-4B938E8EC3A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{2B372155-80BA-4CF9-82D6-4B938E8EC3A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{2B372155-80BA-4CF9-82D6-4B938E8EC3A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{2B372155-80BA-4CF9-82D6-4B938E8EC3A0}.Release|Any CPU.Build.0 = Release|Any CPU
-		{FE90181D-A4B3-4A5C-8490-F07561E18E3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{FE90181D-A4B3-4A5C-8490-F07561E18E3B}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{FE90181D-A4B3-4A5C-8490-F07561E18E3B}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{FE90181D-A4B3-4A5C-8490-F07561E18E3B}.Release|Any CPU.Build.0 = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj
old mode 100644
new mode 100755
index de4005c2f660f587142335883661ae1409c57279..08df026a53a417eb2496e7f8855c9c2942c2f0c8
--- a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj
+++ b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj
@@ -1,54 +1,27 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+  <Import Project="..\Grpc.Core\Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>10.0.0</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}</ProjectGuid>
+    <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
+    <AssemblyName>Grpc.Examples.MathClient</AssemblyName>
     <OutputType>Exe</OutputType>
-    <RootNamespace>math</RootNamespace>
-    <AssemblyName>MathClient</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+    <PackageId>Grpc.Examples.MathClient</PackageId>
+    <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
+    <ProjectReference Include="../Grpc.Examples/Grpc.Examples.csproj" />
   </ItemGroup>
-  <ItemGroup>
-    <Compile Include="..\Grpc.Core\Version.cs">
-      <Link>Version.cs</Link>
-    </Compile>
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="MathClient.cs" />
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <ItemGroup>
-    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
-      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
-      <Name>Grpc.Core</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Grpc.Examples\Grpc.Examples.csproj">
-      <Project>{7DC1433E-3225-42C7-B7EA-546D56E27A4B}</Project>
-      <Name>Grpc.Examples</Name>
-    </ProjectReference>
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
+
   <ItemGroup>
-    <None Include="Grpc.Examples.MathClient.project.json" />
+    <Compile Include="..\Grpc.Core\Version.cs" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+
+</Project>
diff --git a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.project.json b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.xproj b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.xproj
deleted file mode 100644
index 4655bd4377432ec5bf52f1884f7f3bf142dfc171..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>fd48deca-1622-4173-b1d9-2101cf5e7c5f</ProjectGuid>
-    <RootNamespace>Grpc.Examples.MathClient</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Examples.MathClient/packages.config b/src/csharp/Grpc.Examples.MathClient/packages.config
deleted file mode 100644
index 79ece06bef6a23c7f75492ed821f546d8bd403e2..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Examples.MathClient/packages.config
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-</packages>
diff --git a/src/csharp/Grpc.Examples.MathClient/project.json b/src/csharp/Grpc.Examples.MathClient/project.json
deleted file mode 100644
index 81c17151aa5441569e09aba68d695ba9d0144c26..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Examples.MathClient/project.json
+++ /dev/null
@@ -1,60 +0,0 @@
-{
-  "buildOptions": {
-    "emitEntryPoint": true
-  },
-  "configurations": {
-    "Debug": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    },
-    "Release": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    }
-  },
-
-  "dependencies": {
-    "Grpc.Examples": {
-      "target": "project"
-    }
-  },
-  "frameworks": {
-    "net45": { },
-    "netcoreapp1.0": {
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.0"
-        }
-      }
-    }
-  }
-}
diff --git a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj
old mode 100644
new mode 100755
index 3f38de2b714293834d76690835304fd5f8298f9d..a02937474a18f0f2d2dc0fa92cadfb8d5c8ae041
--- a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj
+++ b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj
@@ -1,54 +1,27 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+  <Import Project="..\Grpc.Core\Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>10.0.0</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{BF62FE08-373A-43D6-9D73-41CAA38B7011}</ProjectGuid>
+    <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
+    <AssemblyName>Grpc.Examples.MathServer</AssemblyName>
     <OutputType>Exe</OutputType>
-    <RootNamespace>Grpc.Examples.MathServer</RootNamespace>
-    <AssemblyName>MathServer</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+    <PackageId>Grpc.Examples.MathServer</PackageId>
+    <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
+    <ProjectReference Include="../Grpc.Examples/Grpc.Examples.csproj" />
   </ItemGroup>
-  <ItemGroup>
-    <Compile Include="..\Grpc.Core\Version.cs">
-      <Link>Version.cs</Link>
-    </Compile>
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="MathServer.cs" />
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <ItemGroup>
-    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
-      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
-      <Name>Grpc.Core</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Grpc.Examples\Grpc.Examples.csproj">
-      <Project>{7DC1433E-3225-42C7-B7EA-546D56E27A4B}</Project>
-      <Name>Grpc.Examples</Name>
-    </ProjectReference>
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
+
   <ItemGroup>
-    <None Include="Grpc.Examples.MathServer.project.json" />
+    <Compile Include="..\Grpc.Core\Version.cs" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+
+</Project>
diff --git a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.project.json b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.xproj b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.xproj
deleted file mode 100644
index 38a449e8f29823936d4eebc6523bcd587641fbff..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>58579368-5372-4e67-acd6-9b59cb9fa698</ProjectGuid>
-    <RootNamespace>Grpc.Examples.MathServer</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Examples.MathServer/packages.config b/src/csharp/Grpc.Examples.MathServer/packages.config
deleted file mode 100644
index 79ece06bef6a23c7f75492ed821f546d8bd403e2..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Examples.MathServer/packages.config
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-</packages>
diff --git a/src/csharp/Grpc.Examples.MathServer/project.json b/src/csharp/Grpc.Examples.MathServer/project.json
deleted file mode 100644
index 81c17151aa5441569e09aba68d695ba9d0144c26..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Examples.MathServer/project.json
+++ /dev/null
@@ -1,60 +0,0 @@
-{
-  "buildOptions": {
-    "emitEntryPoint": true
-  },
-  "configurations": {
-    "Debug": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    },
-    "Release": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    }
-  },
-
-  "dependencies": {
-    "Grpc.Examples": {
-      "target": "project"
-    }
-  },
-  "frameworks": {
-    "net45": { },
-    "netcoreapp1.0": {
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.0"
-        }
-      }
-    }
-  }
-}
diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
old mode 100644
new mode 100755
index d22fe87825959451659af2988d3c0861ecf5fcca..9a8e62cc8be628f2134a00a10a6435837a912628
--- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
+++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
@@ -1,69 +1,33 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+  <Import Project="..\Grpc.Core\Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{143B1C29-C442-4BE0-BF3F-A8F92288AC9F}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>Grpc.Examples.Tests</RootNamespace>
+    <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
     <AssemblyName>Grpc.Examples.Tests</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+    <OutputType>Exe</OutputType>
+    <PackageId>Grpc.Examples.Tests</PackageId>
+    <PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
+    <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="nunit.framework">
-      <HintPath>..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll</HintPath>
-    </Reference>
-    <Reference Include="nunitlite">
-      <HintPath>..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Protobuf">
-      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
-    </Reference>
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
-    </Reference>
+    <ProjectReference Include="../Grpc.Examples/Grpc.Examples.csproj" />
   </ItemGroup>
+
   <ItemGroup>
-    <Compile Include="..\Grpc.Core\Version.cs">
-      <Link>Version.cs</Link>
-    </Compile>
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="MathClientServerTests.cs" />
-    <Compile Include="NUnitMain.cs" />
+    <PackageReference Include="NUnit" Version="3.6.0" />
+    <PackageReference Include="NUnitLite" Version="3.6.0" />
   </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <ItemGroup>
-    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
-      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
-      <Name>Grpc.Core</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Grpc.Examples\Grpc.Examples.csproj">
-      <Project>{7DC1433E-3225-42C7-B7EA-546D56E27A4B}</Project>
-      <Name>Grpc.Examples</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="Grpc.Examples.Tests.project.json" />
-    <None Include="packages.config" />
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
+
   <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+    <Compile Include="..\Grpc.Core\Version.cs" />
   </ItemGroup>
+
 </Project>
diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.project.json b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.xproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.xproj
deleted file mode 100644
index 9cecd18b2e4f2a52d92dbc9024c01ec99fe0b367..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>c61714a6-f633-44fb-97f4-c91f425c1d15</ProjectGuid>
-    <RootNamespace>Grpc.Examples.Tests</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
index 50dacc2eaaf258ad28a01518e1afb59653f4e49c..02bcd18cb5573dbcc69468b637637722e3809361 100644
--- a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
+++ b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
@@ -55,7 +55,8 @@ namespace Math.Tests
         [TestFixtureSetUp]
         public void Init()
         {
-            server = new Server
+            // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755
+            server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
             {
                 Services = { Math.BindService(new MathServiceImpl()) },
                 Ports = { { Host, ServerPort.PickUnused, ServerCredentials.Insecure } }
diff --git a/src/csharp/Grpc.Examples.Tests/packages.config b/src/csharp/Grpc.Examples.Tests/packages.config
deleted file mode 100644
index 0fed4dbd415340511d18512507e9925e704c8879..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Examples.Tests/packages.config
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="NUnit" version="3.2.0" targetFramework="net45" />
-  <package id="NUnitLite" version="3.2.0" targetFramework="net45" />
-  <package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
-</packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Examples.Tests/project.json b/src/csharp/Grpc.Examples.Tests/project.json
deleted file mode 100644
index e509621a293218e967582c0baac423bb3c6ac385..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Examples.Tests/project.json
+++ /dev/null
@@ -1,65 +0,0 @@
-{
-  "buildOptions": {
-    "emitEntryPoint": true
-  },
-  "configurations": {
-    "Debug": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    },
-    "Release": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    }
-  },
-
-  "dependencies": {
-    "Grpc.Examples": {
-      "target": "project"
-    },
-    "NUnit": "3.2.0",
-    "NUnitLite": "3.2.0-*"
-  },
-  "frameworks": {
-    "net45": { },
-    "netcoreapp1.0": {
-      "imports": [
-        "portable-net45"
-      ],
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.0"
-        }
-      }
-    }
-  }
-}
diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj
old mode 100644
new mode 100755
index 44acb6c2e3a2a029b4eb335431a68d90671884a2..625c1723bc835b119a8ebca41374c4513e122fab
--- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj
+++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj
@@ -1,64 +1,30 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+  <Import Project="..\Grpc.Core\Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>10.0.0</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{7DC1433E-3225-42C7-B7EA-546D56E27A4B}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <RootNamespace>Grpc.Examples</RootNamespace>
+    <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
     <AssemblyName>Grpc.Examples</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+    <PackageId>Grpc.Examples</PackageId>
+    <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="nunit.framework">
-      <HintPath>..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Data.Linq" />
-    <Reference Include="Google.Protobuf">
-      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
-    </Reference>
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
-    </Reference>
+    <Compile Include="..\Grpc.Core\Version.cs" />
   </ItemGroup>
+
   <ItemGroup>
-    <Compile Include="..\Grpc.Core\Version.cs">
-      <Link>Version.cs</Link>
-    </Compile>
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Math.cs" />
-    <Compile Include="MathGrpc.cs" />
-    <Compile Include="MathServiceImpl.cs" />
-    <Compile Include="MathExamples.cs" />
+    <ProjectReference Include="../Grpc.Core/Grpc.Core.csproj" />
   </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+
   <ItemGroup>
-    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
-      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
-      <Name>Grpc.Core</Name>
-    </ProjectReference>
+    <PackageReference Include="Google.Protobuf" Version="$(GoogleProtobufVersion)" />
   </ItemGroup>
-  <ItemGroup>
-    <None Include="Grpc.Examples.project.json" />
-    <None Include="packages.config" />
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
+
 </Project>
diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.project.json b/src/csharp/Grpc.Examples/Grpc.Examples.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Examples/Grpc.Examples.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.xproj b/src/csharp/Grpc.Examples/Grpc.Examples.xproj
deleted file mode 100644
index d1d7e6d981633fad59d3113d581f86a9a91facfd..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Examples/Grpc.Examples.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>c77b792d-fc78-4ce2-9522-b40b0803c636</ProjectGuid>
-    <RootNamespace>Grpc.Examples</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index 3364b8ce8ecabcfb0d8404a5011f45d283f363a5..1f2e67d916dae166a9b22d162fd7eb60970b7f7b 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -35,41 +35,41 @@
 using System;
 using System.Threading;
 using System.Threading.Tasks;
-using Grpc.Core;
+using grpc = global::Grpc.Core;
 
 namespace Math {
   public static partial class Math
   {
     static readonly string __ServiceName = "math.Math";
 
-    static readonly Marshaller<global::Math.DivArgs> __Marshaller_DivArgs = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.DivArgs.Parser.ParseFrom);
-    static readonly Marshaller<global::Math.DivReply> __Marshaller_DivReply = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.DivReply.Parser.ParseFrom);
-    static readonly Marshaller<global::Math.FibArgs> __Marshaller_FibArgs = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.FibArgs.Parser.ParseFrom);
-    static readonly Marshaller<global::Math.Num> __Marshaller_Num = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.Num.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Math.DivArgs> __Marshaller_DivArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.DivArgs.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Math.DivReply> __Marshaller_DivReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.DivReply.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Math.FibArgs> __Marshaller_FibArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.FibArgs.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Math.Num> __Marshaller_Num = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.Num.Parser.ParseFrom);
 
-    static readonly Method<global::Math.DivArgs, global::Math.DivReply> __Method_Div = new Method<global::Math.DivArgs, global::Math.DivReply>(
-        MethodType.Unary,
+    static readonly grpc::Method<global::Math.DivArgs, global::Math.DivReply> __Method_Div = new grpc::Method<global::Math.DivArgs, global::Math.DivReply>(
+        grpc::MethodType.Unary,
         __ServiceName,
         "Div",
         __Marshaller_DivArgs,
         __Marshaller_DivReply);
 
-    static readonly Method<global::Math.DivArgs, global::Math.DivReply> __Method_DivMany = new Method<global::Math.DivArgs, global::Math.DivReply>(
-        MethodType.DuplexStreaming,
+    static readonly grpc::Method<global::Math.DivArgs, global::Math.DivReply> __Method_DivMany = new grpc::Method<global::Math.DivArgs, global::Math.DivReply>(
+        grpc::MethodType.DuplexStreaming,
         __ServiceName,
         "DivMany",
         __Marshaller_DivArgs,
         __Marshaller_DivReply);
 
-    static readonly Method<global::Math.FibArgs, global::Math.Num> __Method_Fib = new Method<global::Math.FibArgs, global::Math.Num>(
-        MethodType.ServerStreaming,
+    static readonly grpc::Method<global::Math.FibArgs, global::Math.Num> __Method_Fib = new grpc::Method<global::Math.FibArgs, global::Math.Num>(
+        grpc::MethodType.ServerStreaming,
         __ServiceName,
         "Fib",
         __Marshaller_FibArgs,
         __Marshaller_Num);
 
-    static readonly Method<global::Math.Num, global::Math.Num> __Method_Sum = new Method<global::Math.Num, global::Math.Num>(
-        MethodType.ClientStreaming,
+    static readonly grpc::Method<global::Math.Num, global::Math.Num> __Method_Sum = new grpc::Method<global::Math.Num, global::Math.Num>(
+        grpc::MethodType.ClientStreaming,
         __ServiceName,
         "Sum",
         __Marshaller_Num,
@@ -91,9 +91,9 @@ namespace Math {
       /// <param name="request">The request received from the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task<global::Math.DivReply> Div(global::Math.DivArgs request, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
@@ -106,9 +106,9 @@ namespace Math {
       /// <param name="responseStream">Used for sending responses back to the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>A task indicating completion of the handler.</returns>
-      public virtual global::System.Threading.Tasks.Task DivMany(IAsyncStreamReader<global::Math.DivArgs> requestStream, IServerStreamWriter<global::Math.DivReply> responseStream, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task DivMany(grpc::IAsyncStreamReader<global::Math.DivArgs> requestStream, grpc::IServerStreamWriter<global::Math.DivReply> responseStream, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
@@ -120,9 +120,9 @@ namespace Math {
       /// <param name="responseStream">Used for sending responses back to the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>A task indicating completion of the handler.</returns>
-      public virtual global::System.Threading.Tasks.Task Fib(global::Math.FibArgs request, IServerStreamWriter<global::Math.Num> responseStream, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task Fib(global::Math.FibArgs request, grpc::IServerStreamWriter<global::Math.Num> responseStream, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
@@ -132,24 +132,24 @@ namespace Math {
       /// <param name="requestStream">Used for reading requests from the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Math.Num> Sum(IAsyncStreamReader<global::Math.Num> requestStream, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task<global::Math.Num> Sum(grpc::IAsyncStreamReader<global::Math.Num> requestStream, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
     }
 
     /// <summary>Client for Math</summary>
-    public partial class MathClient : ClientBase<MathClient>
+    public partial class MathClient : grpc::ClientBase<MathClient>
     {
       /// <summary>Creates a new client for Math</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
-      public MathClient(Channel channel) : base(channel)
+      public MathClient(grpc::Channel channel) : base(channel)
       {
       }
       /// <summary>Creates a new client for Math that uses a custom <c>CallInvoker</c>.</summary>
       /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
-      public MathClient(CallInvoker callInvoker) : base(callInvoker)
+      public MathClient(grpc::CallInvoker callInvoker) : base(callInvoker)
       {
       }
       /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
@@ -171,9 +171,9 @@ namespace Math {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Math.DivReply Div(global::Math.DivArgs request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return Div(request, new CallOptions(headers, deadline, cancellationToken));
+        return Div(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
@@ -182,7 +182,7 @@ namespace Math {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options)
+      public virtual global::Math.DivReply Div(global::Math.DivArgs request, grpc::CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_Div, null, options, request);
       }
@@ -195,9 +195,9 @@ namespace Math {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return DivAsync(request, new CallOptions(headers, deadline, cancellationToken));
+        return DivAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
@@ -206,7 +206,7 @@ namespace Math {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options)
+      public virtual grpc::AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_Div, null, options, request);
       }
@@ -220,9 +220,9 @@ namespace Math {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return DivMany(new CallOptions(headers, deadline, cancellationToken));
+        return DivMany(new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// DivMany accepts an arbitrary number of division args from the client stream
@@ -232,7 +232,7 @@ namespace Math {
       /// </summary>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(CallOptions options)
+      public virtual grpc::AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(grpc::CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_DivMany, null, options);
       }
@@ -246,9 +246,9 @@ namespace Math {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return Fib(request, new CallOptions(headers, deadline, cancellationToken));
+        return Fib(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
@@ -258,7 +258,7 @@ namespace Math {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, CallOptions options)
+      public virtual grpc::AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncServerStreamingCall(__Method_Fib, null, options, request);
       }
@@ -270,9 +270,9 @@ namespace Math {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return Sum(new CallOptions(headers, deadline, cancellationToken));
+        return Sum(new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// Sum sums a stream of numbers, returning the final result once the stream
@@ -280,7 +280,7 @@ namespace Math {
       /// </summary>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(CallOptions options)
+      public virtual grpc::AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(grpc::CallOptions options)
       {
         return CallInvoker.AsyncClientStreamingCall(__Method_Sum, null, options);
       }
@@ -293,9 +293,9 @@ namespace Math {
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
-    public static ServerServiceDefinition BindService(MathBase serviceImpl)
+    public static grpc::ServerServiceDefinition BindService(MathBase serviceImpl)
     {
-      return ServerServiceDefinition.CreateBuilder()
+      return grpc::ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_Div, serviceImpl.Div)
           .AddMethod(__Method_DivMany, serviceImpl.DivMany)
           .AddMethod(__Method_Fib, serviceImpl.Fib)
diff --git a/src/csharp/Grpc.Examples/packages.config b/src/csharp/Grpc.Examples/packages.config
deleted file mode 100644
index c7db26bd64b777725bd403766cd6df3bd261a8e9..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Examples/packages.config
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="NUnit" version="3.2.0" targetFramework="net45" />
-  <package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
-</packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Examples/project.json b/src/csharp/Grpc.Examples/project.json
deleted file mode 100644
index 21a730cb229d6e71b9e3aa65fbfc74db92c25aff..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Examples/project.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
-  "buildOptions": {
-  },
-
-  "dependencies": {
-    "Grpc.Core": {
-      "target": "project"
-    },
-    "Google.Protobuf": "3.0.0"
-  },
-  "frameworks": {
-    "net45": {
-      "frameworkAssemblies": {
-        "System.Runtime": "",
-        "System.IO": ""
-      }
-    },
-    "netcoreapp1.0": {
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.0"
-        }
-      }
-    }
-  }
-}
diff --git a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
old mode 100644
new mode 100755
index b82f9768612eefc211c4faa212d3a51920df599c..b0e2716e7e5d7d72cabce989ba56efd91ac14e02
--- a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
+++ b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
@@ -1,82 +1,33 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+  <Import Project="..\Grpc.Core\Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Grpc.HealthCheck.Tests</RootNamespace>
+    <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
     <AssemblyName>Grpc.HealthCheck.Tests</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+    <OutputType>Exe</OutputType>
+    <PackageId>Grpc.HealthCheck.Tests</PackageId>
+    <PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
+    <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-    <Reference Include="nunit.framework">
-      <HintPath>..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll</HintPath>
-    </Reference>
-    <Reference Include="nunitlite">
-      <HintPath>..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Protobuf">
-      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
-    </Reference>
+    <ProjectReference Include="../Grpc.HealthCheck/Grpc.HealthCheck.csproj" />
   </ItemGroup>
+
   <ItemGroup>
-    <Compile Include="..\Grpc.Core\Version.cs">
-      <Link>Version.cs</Link>
-    </Compile>
-    <Compile Include="HealthServiceImplTest.cs" />
-    <Compile Include="HealthClientServerTest.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="NUnitMain.cs" />
+    <PackageReference Include="NUnit" Version="3.6.0" />
+    <PackageReference Include="NUnitLite" Version="3.6.0" />
   </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
-      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
-      <Name>Grpc.Core</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Grpc.HealthCheck\Grpc.HealthCheck.csproj">
-      <Project>{AA5E328A-8835-49D7-98ED-C29F2B3049F0}</Project>
-      <Name>Grpc.HealthCheck</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="Grpc.HealthCheck.Tests.project.json" />
-    <None Include="packages.config" />
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
+
   <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+    <Compile Include="..\Grpc.Core\Version.cs" />
   </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.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">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
\ No newline at end of file
+
+</Project>
diff --git a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.project.json b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.xproj b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.xproj
deleted file mode 100644
index 724c5b2a160503866b01320b904fa151e660b6de..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>43dafac6-5343-4621-960e-a8a977ea3f0b</ProjectGuid>
-    <RootNamespace>Grpc.HealthCheck.Tests</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
index 25a58fb3864a67281cf0140d9d7ed3e7607b6322..0ebc3c33700ab4630c23033d71acf3b290798788 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
+++ b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
@@ -57,7 +57,8 @@ namespace Grpc.HealthCheck.Tests
         {
             serviceImpl = new HealthServiceImpl();
 
-            server = new Server
+            // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755
+            server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
             {
                 Services = { Grpc.Health.V1.Health.BindService(serviceImpl) },
                 Ports = { { Host, ServerPort.PickUnused, ServerCredentials.Insecure } }
diff --git a/src/csharp/Grpc.HealthCheck.Tests/packages.config b/src/csharp/Grpc.HealthCheck.Tests/packages.config
deleted file mode 100644
index e796d6b13589346c659659a30d6f0b76cf646dbc..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.HealthCheck.Tests/packages.config
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="NUnit" version="3.2.0" targetFramework="net45" />
-  <package id="NUnitLite" version="3.2.0" targetFramework="net45" />
-</packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.HealthCheck.Tests/project.json b/src/csharp/Grpc.HealthCheck.Tests/project.json
deleted file mode 100644
index 654454d1cb7fcfa6fce71756da6bb2f72c18e1bd..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.HealthCheck.Tests/project.json
+++ /dev/null
@@ -1,65 +0,0 @@
-{
-  "buildOptions": {
-    "emitEntryPoint": true
-  },
-  "configurations": {
-    "Debug": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    },
-    "Release": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    }
-  },
-
-  "dependencies": {
-    "Grpc.HealthCheck": {
-      "target": "project"
-    },
-    "NUnit": "3.2.0",
-    "NUnitLite": "3.2.0-*"
-  },
-  "frameworks": {
-    "net45": { },
-    "netcoreapp1.0": {
-      "imports": [
-        "portable-net45"
-      ],
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.0"
-        }
-      }
-    }
-  }
-}
diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
old mode 100644
new mode 100755
index 63aa18584d8d074ba72f8ffa9e823ce57b0728d7..eac6e1fc95ff6d2cd348f18f9d4836293e0945ea
--- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
+++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
@@ -1,73 +1,37 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+  <Import Project="..\Grpc.Core\Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{AA5E328A-8835-49D7-98ED-C29F2B3049F0}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Grpc.HealthCheck</RootNamespace>
+    <Copyright>Copyright 2015, Google Inc.</Copyright>
+    <AssemblyTitle>gRPC C# Healthchecking</AssemblyTitle>
+    <VersionPrefix>$(GrpcCsharpVersion)</VersionPrefix>
+    <Authors>Google Inc.</Authors>
+    <TargetFrameworks>net45;netstandard1.5</TargetFrameworks>
     <AssemblyName>Grpc.HealthCheck</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <DocumentationFile>bin\$(Configuration)\Grpc.HealthCheck.Xml</DocumentationFile>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+    <PackageId>Grpc.HealthCheck</PackageId>
+    <PackageTags>gRPC health check</PackageTags>
+    <PackageProjectUrl>https://github.com/grpc/grpc</PackageProjectUrl>
+    <PackageLicenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</PackageLicenseUrl>
+    <NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.5' ">1.6.0</NetStandardImplicitPackageVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-    <Reference Include="Google.Protobuf">
-      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
-    </Reference>
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
-    </Reference>
+    <Compile Include="..\Grpc.Core\Version.cs" />
   </ItemGroup>
+
   <ItemGroup>
-    <Compile Include="..\Grpc.Core\Version.cs">
-      <Link>Version.cs</Link>
-    </Compile>
-    <Compile Include="HealthServiceImpl.cs" />
-    <Compile Include="Health.cs" />
-    <Compile Include="HealthGrpc.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
+    <ProjectReference Include="../Grpc.Core/Grpc.Core.csproj" />
   </ItemGroup>
+
   <ItemGroup>
-    <None Include="Grpc.HealthCheck.project.json" />
-    <None Include="packages.config" />
+    <PackageReference Include="Google.Protobuf" Version="$(GoogleProtobufVersion)" />
   </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
-      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
-      <Name>Grpc.Core</Name>
-    </ProjectReference>
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.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">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+
 </Project>
diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.project.json b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.xproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.xproj
deleted file mode 100644
index 5806a7af979bb71350fdbb8c3e741387f6c756c4..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>3be4ad0b-2bf0-4d68-b625-f6018ef0dcfa</ProjectGuid>
-    <RootNamespace>Grpc.HealthCheck</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index 020c2df5657361428a974e9cb89578010078f39c..d3115f3da1615d482acce149952000e77742bdf8 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -35,18 +35,18 @@
 using System;
 using System.Threading;
 using System.Threading.Tasks;
-using Grpc.Core;
+using grpc = global::Grpc.Core;
 
 namespace Grpc.Health.V1 {
   public static partial class Health
   {
     static readonly string __ServiceName = "grpc.health.v1.Health";
 
-    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 grpc::Marshaller<global::Grpc.Health.V1.HealthCheckRequest> __Marshaller_HealthCheckRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Health.V1.HealthCheckRequest.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Health.V1.HealthCheckResponse> __Marshaller_HealthCheckResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Health.V1.HealthCheckResponse.Parser.ParseFrom);
 
-    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,
+    static readonly grpc::Method<global::Grpc.Health.V1.HealthCheckRequest, global::Grpc.Health.V1.HealthCheckResponse> __Method_Check = new grpc::Method<global::Grpc.Health.V1.HealthCheckRequest, global::Grpc.Health.V1.HealthCheckResponse>(
+        grpc::MethodType.Unary,
         __ServiceName,
         "Check",
         __Marshaller_HealthCheckRequest,
@@ -61,24 +61,24 @@ namespace Grpc.Health.V1 {
     /// <summary>Base class for server-side implementations of Health</summary>
     public abstract partial class HealthBase
     {
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
     }
 
     /// <summary>Client for Health</summary>
-    public partial class HealthClient : ClientBase<HealthClient>
+    public partial class HealthClient : grpc::ClientBase<HealthClient>
     {
       /// <summary>Creates a new client for Health</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
-      public HealthClient(Channel channel) : base(channel)
+      public HealthClient(grpc::Channel channel) : base(channel)
       {
       }
       /// <summary>Creates a new client for Health that uses a custom <c>CallInvoker</c>.</summary>
       /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
-      public HealthClient(CallInvoker callInvoker) : base(callInvoker)
+      public HealthClient(grpc::CallInvoker callInvoker) : base(callInvoker)
       {
       }
       /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
@@ -91,19 +91,19 @@ namespace Grpc.Health.V1 {
       {
       }
 
-      public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return Check(request, new CallOptions(headers, deadline, cancellationToken));
+        return Check(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
-      public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
+      public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, grpc::CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_Check, null, options, request);
       }
-      public virtual AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return CheckAsync(request, new CallOptions(headers, deadline, cancellationToken));
+        return CheckAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
-      public virtual AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_Check, null, options, request);
       }
@@ -116,9 +116,9 @@ namespace Grpc.Health.V1 {
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
-    public static ServerServiceDefinition BindService(HealthBase serviceImpl)
+    public static grpc::ServerServiceDefinition BindService(HealthBase serviceImpl)
     {
-      return ServerServiceDefinition.CreateBuilder()
+      return grpc::ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_Check, serviceImpl.Check).Build();
     }
 
diff --git a/src/csharp/Grpc.HealthCheck/packages.config b/src/csharp/Grpc.HealthCheck/packages.config
deleted file mode 100644
index 5ab40b7a8ced7fa54ff91552d9e3f885d337b237..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.HealthCheck/packages.config
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
-</packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.HealthCheck/project.json b/src/csharp/Grpc.HealthCheck/project.json
deleted file mode 100644
index 5d3b2f554b1222ff5251be42557a1d648be4639c..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.HealthCheck/project.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
-  "version": "1.2.0-dev",
-  "title": "gRPC C# Healthchecking",
-  "authors": [ "Google Inc." ],
-  "copyright": "Copyright 2015, Google Inc.",
-  "packOptions": {
-    "summary": "Implementation of gRPC health service",
-    "description": "Example implementation of grpc.health.v1 service that can be used for health-checking.",
-    "owners": [ "grpc-packages" ],
-    "licenseUrl": "https://github.com/grpc/grpc/blob/master/LICENSE",
-    "projectUrl": "https://github.com/grpc/grpc",
-    "requireLicenseAcceptance": false,
-    "tags": [ "gRPC health check" ]
-  },
-  "buildOptions": {
-    "define": [ "SIGNED" ],
-    "keyFile": "../keys/Grpc.snk",
-    "xmlDoc": true,
-    "compile": {
-      "includeFiles": [ "../Grpc.Core/Version.cs" ]
-    }
-  },
-  "dependencies": {
-    "Grpc.Core": "1.2.0-dev",
-    "Google.Protobuf": "3.0.0"
-  },
-  "frameworks": {
-    "net45": {
-      "frameworkAssemblies": {
-        "System.Runtime": "",
-        "System.IO": ""
-      }
-    },
-    "netstandard1.5": {
-      "dependencies": {
-        "NETStandard.Library": "1.6.0"
-      }
-    }
-  }
-}
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
old mode 100644
new mode 100755
index 6bb5f33966ea094e539d351aac21960673294475..dcb24c721668b3380829c903ffc020ff508fd3ca
--- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
@@ -1,87 +1,28 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+  <Import Project="..\Grpc.Core\Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{3D166931-BA2D-416E-95A3-D36E8F6E90B9}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>Grpc.IntegrationTesting.Client</RootNamespace>
+    <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
     <AssemblyName>Grpc.IntegrationTesting.Client</AssemblyName>
-    <StartupObject>Grpc.IntegrationTesting.Client.Program</StartupObject>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <NuGetPackageImportStamp>dfa56e6c</NuGetPackageImportStamp>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>AnyCPU</PlatformTarget>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>AnyCPU</PlatformTarget>
+    <OutputType>Exe</OutputType>
+    <PackageId>Grpc.IntegrationTesting.Client</PackageId>
+    <PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
+    <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Net" />
-    <Reference Include="System.Net.Http" />
-    <Reference Include="System.Net.Http.WebRequest" />
-    <Reference Include="BouncyCastle.Crypto">
-      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
-    </Reference>
-    <Reference Include="Newtonsoft.Json">
-      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
-    </Reference>
-    <Reference Include="log4net">
-      <HintPath>..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Core">
-      <HintPath>..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="Zlib.Portable">
-      <HintPath>..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis">
-      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.PlatformServices">
-      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth">
-      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth.PlatformServices">
-      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
-    </Reference>
+    <ProjectReference Include="../Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj" />
   </ItemGroup>
-  <ItemGroup>
-    <Compile Include="..\Grpc.Core\Version.cs">
-      <Link>Version.cs</Link>
-    </Compile>
-    <Compile Include="Program.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <ItemGroup>
-    <ProjectReference Include="..\Grpc.IntegrationTesting\Grpc.IntegrationTesting.csproj">
-      <Project>{C61154BA-DD4A-4838-8420-0162A28925E0}</Project>
-      <Name>Grpc.IntegrationTesting</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
-      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
-      <Name>Grpc.Core</Name>
-    </ProjectReference>
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
+
   <ItemGroup>
-    <None Include="Grpc.IntegrationTesting.Client.project.json" />
-    <None Include="packages.config" />
+    <Compile Include="..\Grpc.Core\Version.cs" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+
+</Project>
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.project.json b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.xproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.xproj
deleted file mode 100644
index 7f456cfaef1f6af687091aa05bdb0672c211227c..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>48ea5bbe-70e2-4198-869d-d7e59c45f30d</ProjectGuid>
-    <RootNamespace>Grpc.IntegrationTesting.Client</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/packages.config b/src/csharp/Grpc.IntegrationTesting.Client/packages.config
deleted file mode 100644
index 11c6375c638d51d606fb23a2acf14d8dc54f8c1f..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting.Client/packages.config
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
-  <package id="Google.Apis" version="1.16.0" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.16.0" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.16.0" targetFramework="net45" />
-  <package id="log4net" version="2.0.3" targetFramework="net45" />
-  <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
-  <package id="Zlib.Portable.Signed" version="1.11.0" targetFramework="net45" />
-</packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/project.json b/src/csharp/Grpc.IntegrationTesting.Client/project.json
deleted file mode 100644
index f90528151b4519b9dd5a63660fc71e157d0052a2..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting.Client/project.json
+++ /dev/null
@@ -1,69 +0,0 @@
-{
-  "buildOptions": {
-    "emitEntryPoint": true
-  },
-  "configurations": {
-    "Debug": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
-            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
-            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    },
-    "Release": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
-            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
-            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    }
-  },
-
-  "dependencies": {
-    "Grpc.IntegrationTesting": {
-      "target": "project"
-    }
-  },
-  "frameworks": {
-    "net45": { },
-    "netcoreapp1.0": {
-      "imports": [
-        "portable-net45"
-      ],
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.0"
-        }
-      }
-    }
-  }
-}
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj
old mode 100644
new mode 100755
index 3b9587e31518a35e117e193d2bb769304311c1f1..43772020d6f105b20d9346d7d61a4f71ae8b7aeb
--- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj
@@ -1,54 +1,29 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+  <Import Project="..\Grpc.Core\Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>Grpc.IntegrationTesting.QpsWorker</RootNamespace>
+    <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
     <AssemblyName>Grpc.IntegrationTesting.QpsWorker</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>AnyCPU</PlatformTarget>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>AnyCPU</PlatformTarget>
+    <OutputType>Exe</OutputType>
+    <PackageId>Grpc.IntegrationTesting.QpsWorker</PackageId>
+    <ServerGarbageCollection>true</ServerGarbageCollection>
+    <PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
+    <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
+    <ProjectReference Include="../Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj" />
   </ItemGroup>
-  <ItemGroup>
-    <Compile Include="..\Grpc.Core\Version.cs">
-      <Link>Version.cs</Link>
-    </Compile>
-    <Compile Include="Program.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <ItemGroup>
-    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
-      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
-      <Name>Grpc.Core</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Grpc.IntegrationTesting\Grpc.IntegrationTesting.csproj">
-      <Project>{C61154BA-DD4A-4838-8420-0162A28925E0}</Project>
-      <Name>Grpc.IntegrationTesting</Name>
-    </ProjectReference>
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
+
   <ItemGroup>
-    <None Include="Grpc.IntegrationTesting.QpsWorker.project.json" />
+    <Compile Include="..\Grpc.Core\Version.cs" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+
+</Project>
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.project.json b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.xproj b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.xproj
deleted file mode 100644
index 15bec443d6c0d332e2f17ba80df1cf923aac02ed..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>661b70d7-f56a-46e0-9b81-6227b591b5e7</ProjectGuid>
-    <RootNamespace>Grpc.IntegrationTesting.QpsWorker</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/packages.config b/src/csharp/Grpc.IntegrationTesting.QpsWorker/packages.config
deleted file mode 100644
index 79ece06bef6a23c7f75492ed821f546d8bd403e2..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/packages.config
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-</packages>
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
deleted file mode 100644
index 161e602abcab260288517890dee18588721ce455..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
+++ /dev/null
@@ -1,74 +0,0 @@
-{
-  "buildOptions": {
-    "emitEntryPoint": true
-  },
-  "configurations": {
-    "Debug": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
-            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
-            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    },
-    "Release": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
-            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
-            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    }
-  },
-
-  "dependencies": {
-    "Grpc.IntegrationTesting": {
-      "target": "project"
-    }
-  },
-  "frameworks": {
-    "net45": { },
-    "netcoreapp1.0": {
-      "imports": [
-        "portable-net45"
-      ],
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.0"
-        }
-      }
-    }
-  },
-  "runtimeOptions": {
-    "configProperties": {
-      "System.GC.Server": true
-    }
-  }
-}
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
old mode 100644
new mode 100755
index 081dc24fbf19ecaa07a82591b8e4d81e58cd6acd..db736baed0556a309f8f0b0c9e0b588c9d661ce5
--- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
@@ -1,87 +1,28 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+  <Import Project="..\Grpc.Core\Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{A654F3B8-E859-4E6A-B30D-227527DBEF0D}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>Grpc.IntegrationTesting.Server</RootNamespace>
+    <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
     <AssemblyName>Grpc.IntegrationTesting.Server</AssemblyName>
-    <StartupObject>Grpc.IntegrationTesting.Server.Program</StartupObject>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <NuGetPackageImportStamp>7ceb739e</NuGetPackageImportStamp>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>AnyCPU</PlatformTarget>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>AnyCPU</PlatformTarget>
+    <OutputType>Exe</OutputType>
+    <PackageId>Grpc.IntegrationTesting.Server</PackageId>
+    <PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
+    <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Net" />
-    <Reference Include="System.Net.Http" />
-    <Reference Include="System.Net.Http.WebRequest" />
-    <Reference Include="BouncyCastle.Crypto">
-      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
-    </Reference>
-    <Reference Include="Newtonsoft.Json">
-      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
-    </Reference>
-    <Reference Include="log4net">
-      <HintPath>..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Core">
-      <HintPath>..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="Zlib.Portable">
-      <HintPath>..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis">
-      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.PlatformServices">
-      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth">
-      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth.PlatformServices">
-      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
-    </Reference>
+    <ProjectReference Include="../Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj" />
   </ItemGroup>
-  <ItemGroup>
-    <Compile Include="..\Grpc.Core\Version.cs">
-      <Link>Version.cs</Link>
-    </Compile>
-    <Compile Include="Program.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <ItemGroup>
-    <ProjectReference Include="..\Grpc.IntegrationTesting\Grpc.IntegrationTesting.csproj">
-      <Project>{C61154BA-DD4A-4838-8420-0162A28925E0}</Project>
-      <Name>Grpc.IntegrationTesting</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
-      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
-      <Name>Grpc.Core</Name>
-    </ProjectReference>
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
+  
   <ItemGroup>
-    <None Include="Grpc.IntegrationTesting.Server.project.json" />
-    <None Include="packages.config" />
+    <Compile Include="..\Grpc.Core\Version.cs" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+
+</Project>
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.project.json b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.xproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.xproj
deleted file mode 100644
index 689eb0b842544740f2b3d7d2998eb9ff91008c51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>881f7ad1-a84e-47a2-9402-115c63c4031e</ProjectGuid>
-    <RootNamespace>Grpc.IntegrationTesting.Server</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/packages.config b/src/csharp/Grpc.IntegrationTesting.Server/packages.config
deleted file mode 100644
index 11c6375c638d51d606fb23a2acf14d8dc54f8c1f..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting.Server/packages.config
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
-  <package id="Google.Apis" version="1.16.0" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.16.0" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.16.0" targetFramework="net45" />
-  <package id="log4net" version="2.0.3" targetFramework="net45" />
-  <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
-  <package id="Zlib.Portable.Signed" version="1.11.0" targetFramework="net45" />
-</packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/project.json b/src/csharp/Grpc.IntegrationTesting.Server/project.json
deleted file mode 100644
index f90528151b4519b9dd5a63660fc71e157d0052a2..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting.Server/project.json
+++ /dev/null
@@ -1,69 +0,0 @@
-{
-  "buildOptions": {
-    "emitEntryPoint": true
-  },
-  "configurations": {
-    "Debug": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
-            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
-            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    },
-    "Release": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
-            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
-            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    }
-  },
-
-  "dependencies": {
-    "Grpc.IntegrationTesting": {
-      "target": "project"
-    }
-  },
-  "frameworks": {
-    "net45": { },
-    "netcoreapp1.0": {
-      "imports": [
-        "portable-net45"
-      ],
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.0"
-        }
-      }
-    }
-  }
-}
diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj b/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj
old mode 100644
new mode 100755
index 0f283404504062a78ec89efae62f17661c826d65..fe4e0da41717498cd2b2f48b8a278eb57bcc8d15
--- a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj
@@ -1,54 +1,28 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+  <Import Project="..\Grpc.Core\Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{ADEBA147-80AE-4710-82E9-5B7F93690266}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>Grpc.IntegrationTesting.StressClient</RootNamespace>
+    <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
     <AssemblyName>Grpc.IntegrationTesting.StressClient</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>AnyCPU</PlatformTarget>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>AnyCPU</PlatformTarget>
+    <OutputType>Exe</OutputType>
+    <PackageId>Grpc.IntegrationTesting.StressClient</PackageId>
+    <PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
+    <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
+    <ProjectReference Include="../Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj" />
   </ItemGroup>
-  <ItemGroup>
-    <Compile Include="..\Grpc.Core\Version.cs">
-      <Link>Version.cs</Link>
-    </Compile>
-    <Compile Include="Program.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <ItemGroup>
-    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
-      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
-      <Name>Grpc.Core</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Grpc.IntegrationTesting\Grpc.IntegrationTesting.csproj">
-      <Project>{C61154BA-DD4A-4838-8420-0162A28925E0}</Project>
-      <Name>Grpc.IntegrationTesting</Name>
-    </ProjectReference>
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
+
   <ItemGroup>
-    <None Include="Grpc.IntegrationTesting.StressClient.project.json" />
+    <Compile Include="..\Grpc.Core\Version.cs" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+
+</Project>
diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.project.json b/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.xproj b/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.xproj
deleted file mode 100644
index 2f4fdcbb4709a3c652ae16a17004fab733239247..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.xproj
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>0ebc910b-8867-4d3e-8686-91f34183d839</ProjectGuid>
-    <RootNamespace>Grpc.IntegrationTesting.StressClient</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/packages.config b/src/csharp/Grpc.IntegrationTesting.StressClient/packages.config
deleted file mode 100644
index 79ece06bef6a23c7f75492ed821f546d8bd403e2..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting.StressClient/packages.config
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-</packages>
diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
deleted file mode 100644
index f90528151b4519b9dd5a63660fc71e157d0052a2..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
+++ /dev/null
@@ -1,69 +0,0 @@
-{
-  "buildOptions": {
-    "emitEntryPoint": true
-  },
-  "configurations": {
-    "Debug": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
-            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
-            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    },
-    "Release": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
-            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
-            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    }
-  },
-
-  "dependencies": {
-    "Grpc.IntegrationTesting": {
-      "target": "project"
-    }
-  },
-  "frameworks": {
-    "net45": { },
-    "netcoreapp1.0": {
-      "imports": [
-        "portable-net45"
-      ],
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.0"
-        }
-      }
-    }
-  }
-}
diff --git a/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs b/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
index b9c0fe6d0d847e70c7523f02590b94c02c979e04..c9f7c42b71db98d40471206af68b459b9713e07c 100644
--- a/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
@@ -179,6 +179,9 @@ namespace Grpc.IntegrationTesting
                 statsResetCount.Increment();
             }
 
+            GrpcEnvironment.Logger.Info("[ClientRunnerImpl.GetStats] GC collection counts: gen0 {0}, gen1 {1}, gen2 {2}, gen3 {3} (histogram reset count:{4}, seconds since reset: {5})",
+                GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2), GC.CollectionCount(3), statsResetCount.Count, secondsElapsed);
+
             // TODO: populate user time and system time
             return new ClientStats
             {
diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs
index 3f4862d5671cb0d530bcd280b8f008085202e656..6c0176fb43ffaee258275e00e30de6977b4a9df0 100644
--- a/src/csharp/Grpc.IntegrationTesting/Control.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Control.cs
@@ -30,63 +30,66 @@ namespace Grpc.Testing {
             "cnBjLnRlc3RpbmcuQ2xvc2VkTG9vcFBhcmFtc0gAEi4KB3BvaXNzb24YAiAB",
             "KAsyGy5ncnBjLnRlc3RpbmcuUG9pc3NvblBhcmFtc0gAQgYKBGxvYWQiQwoO",
             "U2VjdXJpdHlQYXJhbXMSEwoLdXNlX3Rlc3RfY2EYASABKAgSHAoUc2VydmVy",
-            "X2hvc3Rfb3ZlcnJpZGUYAiABKAki8AMKDENsaWVudENvbmZpZxIWCg5zZXJ2",
-            "ZXJfdGFyZ2V0cxgBIAMoCRItCgtjbGllbnRfdHlwZRgCIAEoDjIYLmdycGMu",
-            "dGVzdGluZy5DbGllbnRUeXBlEjUKD3NlY3VyaXR5X3BhcmFtcxgDIAEoCzIc",
-            "LmdycGMudGVzdGluZy5TZWN1cml0eVBhcmFtcxIkChxvdXRzdGFuZGluZ19y",
-            "cGNzX3Blcl9jaGFubmVsGAQgASgFEhcKD2NsaWVudF9jaGFubmVscxgFIAEo",
-            "BRIcChRhc3luY19jbGllbnRfdGhyZWFkcxgHIAEoBRInCghycGNfdHlwZRgI",
-            "IAEoDjIVLmdycGMudGVzdGluZy5ScGNUeXBlEi0KC2xvYWRfcGFyYW1zGAog",
-            "ASgLMhguZ3JwYy50ZXN0aW5nLkxvYWRQYXJhbXMSMwoOcGF5bG9hZF9jb25m",
-            "aWcYCyABKAsyGy5ncnBjLnRlc3RpbmcuUGF5bG9hZENvbmZpZxI3ChBoaXN0",
-            "b2dyYW1fcGFyYW1zGAwgASgLMh0uZ3JwYy50ZXN0aW5nLkhpc3RvZ3JhbVBh",
-            "cmFtcxIRCgljb3JlX2xpc3QYDSADKAUSEgoKY29yZV9saW1pdBgOIAEoBRIY",
-            "ChBvdGhlcl9jbGllbnRfYXBpGA8gASgJIjgKDENsaWVudFN0YXR1cxIoCgVz",
-            "dGF0cxgBIAEoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cyIVCgRNYXJr",
-            "Eg0KBXJlc2V0GAEgASgIImgKCkNsaWVudEFyZ3MSKwoFc2V0dXAYASABKAsy",
-            "Gi5ncnBjLnRlc3RpbmcuQ2xpZW50Q29uZmlnSAASIgoEbWFyaxgCIAEoCzIS",
-            "LmdycGMudGVzdGluZy5NYXJrSABCCQoHYXJndHlwZSK0AgoMU2VydmVyQ29u",
-            "ZmlnEi0KC3NlcnZlcl90eXBlGAEgASgOMhguZ3JwYy50ZXN0aW5nLlNlcnZl",
-            "clR5cGUSNQoPc2VjdXJpdHlfcGFyYW1zGAIgASgLMhwuZ3JwYy50ZXN0aW5n",
-            "LlNlY3VyaXR5UGFyYW1zEgwKBHBvcnQYBCABKAUSHAoUYXN5bmNfc2VydmVy",
-            "X3RocmVhZHMYByABKAUSEgoKY29yZV9saW1pdBgIIAEoBRIzCg5wYXlsb2Fk",
-            "X2NvbmZpZxgJIAEoCzIbLmdycGMudGVzdGluZy5QYXlsb2FkQ29uZmlnEhEK",
-            "CWNvcmVfbGlzdBgKIAMoBRIYChBvdGhlcl9zZXJ2ZXJfYXBpGAsgASgJEhwK",
-            "E3Jlc291cmNlX3F1b3RhX3NpemUY6QcgASgFImgKClNlcnZlckFyZ3MSKwoF",
-            "c2V0dXAYASABKAsyGi5ncnBjLnRlc3RpbmcuU2VydmVyQ29uZmlnSAASIgoE",
-            "bWFyaxgCIAEoCzISLmdycGMudGVzdGluZy5NYXJrSABCCQoHYXJndHlwZSJV",
-            "CgxTZXJ2ZXJTdGF0dXMSKAoFc3RhdHMYASABKAsyGS5ncnBjLnRlc3Rpbmcu",
-            "U2VydmVyU3RhdHMSDAoEcG9ydBgCIAEoBRINCgVjb3JlcxgDIAEoBSINCgtD",
-            "b3JlUmVxdWVzdCIdCgxDb3JlUmVzcG9uc2USDQoFY29yZXMYASABKAUiBgoE",
-            "Vm9pZCL9AQoIU2NlbmFyaW8SDAoEbmFtZRgBIAEoCRIxCg1jbGllbnRfY29u",
-            "ZmlnGAIgASgLMhouZ3JwYy50ZXN0aW5nLkNsaWVudENvbmZpZxITCgtudW1f",
-            "Y2xpZW50cxgDIAEoBRIxCg1zZXJ2ZXJfY29uZmlnGAQgASgLMhouZ3JwYy50",
-            "ZXN0aW5nLlNlcnZlckNvbmZpZxITCgtudW1fc2VydmVycxgFIAEoBRIWCg53",
-            "YXJtdXBfc2Vjb25kcxgGIAEoBRIZChFiZW5jaG1hcmtfc2Vjb25kcxgHIAEo",
-            "BRIgChhzcGF3bl9sb2NhbF93b3JrZXJfY291bnQYCCABKAUiNgoJU2NlbmFy",
-            "aW9zEikKCXNjZW5hcmlvcxgBIAMoCzIWLmdycGMudGVzdGluZy5TY2VuYXJp",
-            "byL4AgoVU2NlbmFyaW9SZXN1bHRTdW1tYXJ5EgsKA3FwcxgBIAEoARIbChNx",
-            "cHNfcGVyX3NlcnZlcl9jb3JlGAIgASgBEhoKEnNlcnZlcl9zeXN0ZW1fdGlt",
-            "ZRgDIAEoARIYChBzZXJ2ZXJfdXNlcl90aW1lGAQgASgBEhoKEmNsaWVudF9z",
-            "eXN0ZW1fdGltZRgFIAEoARIYChBjbGllbnRfdXNlcl90aW1lGAYgASgBEhIK",
-            "CmxhdGVuY3lfNTAYByABKAESEgoKbGF0ZW5jeV85MBgIIAEoARISCgpsYXRl",
-            "bmN5Xzk1GAkgASgBEhIKCmxhdGVuY3lfOTkYCiABKAESEwoLbGF0ZW5jeV85",
-            "OTkYCyABKAESGAoQc2VydmVyX2NwdV91c2FnZRgMIAEoARImCh5zdWNjZXNz",
-            "ZnVsX3JlcXVlc3RzX3Blcl9zZWNvbmQYDSABKAESIgoaZmFpbGVkX3JlcXVl",
-            "c3RzX3Blcl9zZWNvbmQYDiABKAEigwMKDlNjZW5hcmlvUmVzdWx0EigKCHNj",
-            "ZW5hcmlvGAEgASgLMhYuZ3JwYy50ZXN0aW5nLlNjZW5hcmlvEi4KCWxhdGVu",
-            "Y2llcxgCIAEoCzIbLmdycGMudGVzdGluZy5IaXN0b2dyYW1EYXRhEi8KDGNs",
-            "aWVudF9zdGF0cxgDIAMoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cxIv",
-            "CgxzZXJ2ZXJfc3RhdHMYBCADKAsyGS5ncnBjLnRlc3RpbmcuU2VydmVyU3Rh",
-            "dHMSFAoMc2VydmVyX2NvcmVzGAUgAygFEjQKB3N1bW1hcnkYBiABKAsyIy5n",
-            "cnBjLnRlc3RpbmcuU2NlbmFyaW9SZXN1bHRTdW1tYXJ5EhYKDmNsaWVudF9z",
-            "dWNjZXNzGAcgAygIEhYKDnNlcnZlcl9zdWNjZXNzGAggAygIEjkKD3JlcXVl",
-            "c3RfcmVzdWx0cxgJIAMoCzIgLmdycGMudGVzdGluZy5SZXF1ZXN0UmVzdWx0",
-            "Q291bnQqQQoKQ2xpZW50VHlwZRIPCgtTWU5DX0NMSUVOVBAAEhAKDEFTWU5D",
-            "X0NMSUVOVBABEhAKDE9USEVSX0NMSUVOVBACKlsKClNlcnZlclR5cGUSDwoL",
-            "U1lOQ19TRVJWRVIQABIQCgxBU1lOQ19TRVJWRVIQARIYChRBU1lOQ19HRU5F",
-            "UklDX1NFUlZFUhACEhAKDE9USEVSX1NFUlZFUhADKiMKB1JwY1R5cGUSCQoF",
-            "VU5BUlkQABINCglTVFJFQU1JTkcQAWIGcHJvdG8z"));
+            "X2hvc3Rfb3ZlcnJpZGUYAiABKAkiTQoKQ2hhbm5lbEFyZxIMCgRuYW1lGAEg",
+            "ASgJEhMKCXN0cl92YWx1ZRgCIAEoCUgAEhMKCWludF92YWx1ZRgDIAEoBUgA",
+            "QgcKBXZhbHVlIqAECgxDbGllbnRDb25maWcSFgoOc2VydmVyX3RhcmdldHMY",
+            "ASADKAkSLQoLY2xpZW50X3R5cGUYAiABKA4yGC5ncnBjLnRlc3RpbmcuQ2xp",
+            "ZW50VHlwZRI1Cg9zZWN1cml0eV9wYXJhbXMYAyABKAsyHC5ncnBjLnRlc3Rp",
+            "bmcuU2VjdXJpdHlQYXJhbXMSJAocb3V0c3RhbmRpbmdfcnBjc19wZXJfY2hh",
+            "bm5lbBgEIAEoBRIXCg9jbGllbnRfY2hhbm5lbHMYBSABKAUSHAoUYXN5bmNf",
+            "Y2xpZW50X3RocmVhZHMYByABKAUSJwoIcnBjX3R5cGUYCCABKA4yFS5ncnBj",
+            "LnRlc3RpbmcuUnBjVHlwZRItCgtsb2FkX3BhcmFtcxgKIAEoCzIYLmdycGMu",
+            "dGVzdGluZy5Mb2FkUGFyYW1zEjMKDnBheWxvYWRfY29uZmlnGAsgASgLMhsu",
+            "Z3JwYy50ZXN0aW5nLlBheWxvYWRDb25maWcSNwoQaGlzdG9ncmFtX3BhcmFt",
+            "cxgMIAEoCzIdLmdycGMudGVzdGluZy5IaXN0b2dyYW1QYXJhbXMSEQoJY29y",
+            "ZV9saXN0GA0gAygFEhIKCmNvcmVfbGltaXQYDiABKAUSGAoQb3RoZXJfY2xp",
+            "ZW50X2FwaRgPIAEoCRIuCgxjaGFubmVsX2FyZ3MYECADKAsyGC5ncnBjLnRl",
+            "c3RpbmcuQ2hhbm5lbEFyZyI4CgxDbGllbnRTdGF0dXMSKAoFc3RhdHMYASAB",
+            "KAsyGS5ncnBjLnRlc3RpbmcuQ2xpZW50U3RhdHMiFQoETWFyaxINCgVyZXNl",
+            "dBgBIAEoCCJoCgpDbGllbnRBcmdzEisKBXNldHVwGAEgASgLMhouZ3JwYy50",
+            "ZXN0aW5nLkNsaWVudENvbmZpZ0gAEiIKBG1hcmsYAiABKAsyEi5ncnBjLnRl",
+            "c3RpbmcuTWFya0gAQgkKB2FyZ3R5cGUitAIKDFNlcnZlckNvbmZpZxItCgtz",
+            "ZXJ2ZXJfdHlwZRgBIAEoDjIYLmdycGMudGVzdGluZy5TZXJ2ZXJUeXBlEjUK",
+            "D3NlY3VyaXR5X3BhcmFtcxgCIAEoCzIcLmdycGMudGVzdGluZy5TZWN1cml0",
+            "eVBhcmFtcxIMCgRwb3J0GAQgASgFEhwKFGFzeW5jX3NlcnZlcl90aHJlYWRz",
+            "GAcgASgFEhIKCmNvcmVfbGltaXQYCCABKAUSMwoOcGF5bG9hZF9jb25maWcY",
+            "CSABKAsyGy5ncnBjLnRlc3RpbmcuUGF5bG9hZENvbmZpZxIRCgljb3JlX2xp",
+            "c3QYCiADKAUSGAoQb3RoZXJfc2VydmVyX2FwaRgLIAEoCRIcChNyZXNvdXJj",
+            "ZV9xdW90YV9zaXplGOkHIAEoBSJoCgpTZXJ2ZXJBcmdzEisKBXNldHVwGAEg",
+            "ASgLMhouZ3JwYy50ZXN0aW5nLlNlcnZlckNvbmZpZ0gAEiIKBG1hcmsYAiAB",
+            "KAsyEi5ncnBjLnRlc3RpbmcuTWFya0gAQgkKB2FyZ3R5cGUiVQoMU2VydmVy",
+            "U3RhdHVzEigKBXN0YXRzGAEgASgLMhkuZ3JwYy50ZXN0aW5nLlNlcnZlclN0",
+            "YXRzEgwKBHBvcnQYAiABKAUSDQoFY29yZXMYAyABKAUiDQoLQ29yZVJlcXVl",
+            "c3QiHQoMQ29yZVJlc3BvbnNlEg0KBWNvcmVzGAEgASgFIgYKBFZvaWQi/QEK",
+            "CFNjZW5hcmlvEgwKBG5hbWUYASABKAkSMQoNY2xpZW50X2NvbmZpZxgCIAEo",
+            "CzIaLmdycGMudGVzdGluZy5DbGllbnRDb25maWcSEwoLbnVtX2NsaWVudHMY",
+            "AyABKAUSMQoNc2VydmVyX2NvbmZpZxgEIAEoCzIaLmdycGMudGVzdGluZy5T",
+            "ZXJ2ZXJDb25maWcSEwoLbnVtX3NlcnZlcnMYBSABKAUSFgoOd2FybXVwX3Nl",
+            "Y29uZHMYBiABKAUSGQoRYmVuY2htYXJrX3NlY29uZHMYByABKAUSIAoYc3Bh",
+            "d25fbG9jYWxfd29ya2VyX2NvdW50GAggASgFIjYKCVNjZW5hcmlvcxIpCglz",
+            "Y2VuYXJpb3MYASADKAsyFi5ncnBjLnRlc3RpbmcuU2NlbmFyaW8i+AIKFVNj",
+            "ZW5hcmlvUmVzdWx0U3VtbWFyeRILCgNxcHMYASABKAESGwoTcXBzX3Blcl9z",
+            "ZXJ2ZXJfY29yZRgCIAEoARIaChJzZXJ2ZXJfc3lzdGVtX3RpbWUYAyABKAES",
+            "GAoQc2VydmVyX3VzZXJfdGltZRgEIAEoARIaChJjbGllbnRfc3lzdGVtX3Rp",
+            "bWUYBSABKAESGAoQY2xpZW50X3VzZXJfdGltZRgGIAEoARISCgpsYXRlbmN5",
+            "XzUwGAcgASgBEhIKCmxhdGVuY3lfOTAYCCABKAESEgoKbGF0ZW5jeV85NRgJ",
+            "IAEoARISCgpsYXRlbmN5Xzk5GAogASgBEhMKC2xhdGVuY3lfOTk5GAsgASgB",
+            "EhgKEHNlcnZlcl9jcHVfdXNhZ2UYDCABKAESJgoec3VjY2Vzc2Z1bF9yZXF1",
+            "ZXN0c19wZXJfc2Vjb25kGA0gASgBEiIKGmZhaWxlZF9yZXF1ZXN0c19wZXJf",
+            "c2Vjb25kGA4gASgBIoMDCg5TY2VuYXJpb1Jlc3VsdBIoCghzY2VuYXJpbxgB",
+            "IAEoCzIWLmdycGMudGVzdGluZy5TY2VuYXJpbxIuCglsYXRlbmNpZXMYAiAB",
+            "KAsyGy5ncnBjLnRlc3RpbmcuSGlzdG9ncmFtRGF0YRIvCgxjbGllbnRfc3Rh",
+            "dHMYAyADKAsyGS5ncnBjLnRlc3RpbmcuQ2xpZW50U3RhdHMSLwoMc2VydmVy",
+            "X3N0YXRzGAQgAygLMhkuZ3JwYy50ZXN0aW5nLlNlcnZlclN0YXRzEhQKDHNl",
+            "cnZlcl9jb3JlcxgFIAMoBRI0CgdzdW1tYXJ5GAYgASgLMiMuZ3JwYy50ZXN0",
+            "aW5nLlNjZW5hcmlvUmVzdWx0U3VtbWFyeRIWCg5jbGllbnRfc3VjY2VzcxgH",
+            "IAMoCBIWCg5zZXJ2ZXJfc3VjY2VzcxgIIAMoCBI5Cg9yZXF1ZXN0X3Jlc3Vs",
+            "dHMYCSADKAsyIC5ncnBjLnRlc3RpbmcuUmVxdWVzdFJlc3VsdENvdW50KkEK",
+            "CkNsaWVudFR5cGUSDwoLU1lOQ19DTElFTlQQABIQCgxBU1lOQ19DTElFTlQQ",
+            "ARIQCgxPVEhFUl9DTElFTlQQAipbCgpTZXJ2ZXJUeXBlEg8KC1NZTkNfU0VS",
+            "VkVSEAASEAoMQVNZTkNfU0VSVkVSEAESGAoUQVNZTkNfR0VORVJJQ19TRVJW",
+            "RVIQAhIQCgxPVEhFUl9TRVJWRVIQAyojCgdScGNUeXBlEgkKBVVOQVJZEAAS",
+            "DQoJU1RSRUFNSU5HEAFiBnByb3RvMw=="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { global::Grpc.Testing.PayloadsReflection.Descriptor, global::Grpc.Testing.StatsReflection.Descriptor, },
           new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Grpc.Testing.ClientType), typeof(global::Grpc.Testing.ServerType), typeof(global::Grpc.Testing.RpcType), }, new pbr::GeneratedClrTypeInfo[] {
@@ -94,7 +97,8 @@ namespace Grpc.Testing {
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClosedLoopParams), global::Grpc.Testing.ClosedLoopParams.Parser, null, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.LoadParams), global::Grpc.Testing.LoadParams.Parser, new[]{ "ClosedLoop", "Poisson" }, new[]{ "Load" }, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.SecurityParams), global::Grpc.Testing.SecurityParams.Parser, new[]{ "UseTestCa", "ServerHostOverride" }, null, null, null),
-            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams", "CoreList", "CoreLimit", "OtherClientApi" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ChannelArg), global::Grpc.Testing.ChannelArg.Parser, new[]{ "Name", "StrValue", "IntValue" }, new[]{ "Value" }, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams", "CoreList", "CoreLimit", "OtherClientApi", "ChannelArgs" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientStatus), global::Grpc.Testing.ClientStatus.Parser, new[]{ "Stats" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Mark), global::Grpc.Testing.Mark.Parser, new[]{ "Reset" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientArgs), global::Grpc.Testing.ClientArgs.Parser, new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null),
@@ -116,13 +120,13 @@ namespace Grpc.Testing {
   #region Enums
   public enum ClientType {
     /// <summary>
-    ///  Many languages support a basic distinction between using
-    ///  sync or async client, and this allows the specification
+    /// Many languages support a basic distinction between using
+    /// sync or async client, and this allows the specification
     /// </summary>
     [pbr::OriginalName("SYNC_CLIENT")] SyncClient = 0,
     [pbr::OriginalName("ASYNC_CLIENT")] AsyncClient = 1,
     /// <summary>
-    ///  used for some language-specific variants
+    /// used for some language-specific variants
     /// </summary>
     [pbr::OriginalName("OTHER_CLIENT")] OtherClient = 2,
   }
@@ -132,7 +136,7 @@ namespace Grpc.Testing {
     [pbr::OriginalName("ASYNC_SERVER")] AsyncServer = 1,
     [pbr::OriginalName("ASYNC_GENERIC_SERVER")] AsyncGenericServer = 2,
     /// <summary>
-    ///  used for some language-specific variants
+    /// used for some language-specific variants
     /// </summary>
     [pbr::OriginalName("OTHER_SERVER")] OtherServer = 3,
   }
@@ -146,8 +150,8 @@ namespace Grpc.Testing {
 
   #region Messages
   /// <summary>
-  ///  Parameters of poisson process distribution, which is a good representation
-  ///  of activity coming in from independent identical stationary sources.
+  /// Parameters of poisson process distribution, which is a good representation
+  /// of activity coming in from independent identical stationary sources.
   /// </summary>
   public sealed partial class PoissonParams : pb::IMessage<PoissonParams> {
     private static readonly pb::MessageParser<PoissonParams> _parser = new pb::MessageParser<PoissonParams>(() => new PoissonParams());
@@ -185,7 +189,7 @@ namespace Grpc.Testing {
     public const int OfferedLoadFieldNumber = 1;
     private double offeredLoad_;
     /// <summary>
-    ///  The rate of arrivals (a.k.a. lambda parameter of the exp distribution).
+    /// The rate of arrivals (a.k.a. lambda parameter of the exp distribution).
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double OfferedLoad {
@@ -270,8 +274,8 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  Once an RPC finishes, immediately start a new one.
-  ///  No configuration parameters needed.
+  /// Once an RPC finishes, immediately start a new one.
+  /// No configuration parameters needed.
   /// </summary>
   public sealed partial class ClosedLoopParams : pb::IMessage<ClosedLoopParams> {
     private static readonly pb::MessageParser<ClosedLoopParams> _parser = new pb::MessageParser<ClosedLoopParams>(() => new ClosedLoopParams());
@@ -549,7 +553,7 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  presence of SecurityParams implies use of TLS
+  /// presence of SecurityParams implies use of TLS
   /// </summary>
   public sealed partial class SecurityParams : pb::IMessage<SecurityParams> {
     private static readonly pb::MessageParser<SecurityParams> _parser = new pb::MessageParser<SecurityParams>(() => new SecurityParams());
@@ -696,6 +700,210 @@ namespace Grpc.Testing {
 
   }
 
+  public sealed partial class ChannelArg : pb::IMessage<ChannelArg> {
+    private static readonly pb::MessageParser<ChannelArg> _parser = new pb::MessageParser<ChannelArg>(() => new ChannelArg());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<ChannelArg> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[4]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ChannelArg() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ChannelArg(ChannelArg other) : this() {
+      name_ = other.name_;
+      switch (other.ValueCase) {
+        case ValueOneofCase.StrValue:
+          StrValue = other.StrValue;
+          break;
+        case ValueOneofCase.IntValue:
+          IntValue = other.IntValue;
+          break;
+      }
+
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ChannelArg Clone() {
+      return new ChannelArg(this);
+    }
+
+    /// <summary>Field number for the "name" field.</summary>
+    public const int NameFieldNumber = 1;
+    private string name_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Name {
+      get { return name_; }
+      set {
+        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "str_value" field.</summary>
+    public const int StrValueFieldNumber = 2;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string StrValue {
+      get { return valueCase_ == ValueOneofCase.StrValue ? (string) value_ : ""; }
+      set {
+        value_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+        valueCase_ = ValueOneofCase.StrValue;
+      }
+    }
+
+    /// <summary>Field number for the "int_value" field.</summary>
+    public const int IntValueFieldNumber = 3;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int IntValue {
+      get { return valueCase_ == ValueOneofCase.IntValue ? (int) value_ : 0; }
+      set {
+        value_ = value;
+        valueCase_ = ValueOneofCase.IntValue;
+      }
+    }
+
+    private object value_;
+    /// <summary>Enum of possible cases for the "value" oneof.</summary>
+    public enum ValueOneofCase {
+      None = 0,
+      StrValue = 2,
+      IntValue = 3,
+    }
+    private ValueOneofCase valueCase_ = ValueOneofCase.None;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ValueOneofCase ValueCase {
+      get { return valueCase_; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearValue() {
+      valueCase_ = ValueOneofCase.None;
+      value_ = null;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as ChannelArg);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(ChannelArg other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Name != other.Name) return false;
+      if (StrValue != other.StrValue) return false;
+      if (IntValue != other.IntValue) return false;
+      if (ValueCase != other.ValueCase) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Name.Length != 0) hash ^= Name.GetHashCode();
+      if (valueCase_ == ValueOneofCase.StrValue) hash ^= StrValue.GetHashCode();
+      if (valueCase_ == ValueOneofCase.IntValue) hash ^= IntValue.GetHashCode();
+      hash ^= (int) valueCase_;
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Name.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(Name);
+      }
+      if (valueCase_ == ValueOneofCase.StrValue) {
+        output.WriteRawTag(18);
+        output.WriteString(StrValue);
+      }
+      if (valueCase_ == ValueOneofCase.IntValue) {
+        output.WriteRawTag(24);
+        output.WriteInt32(IntValue);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (Name.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
+      }
+      if (valueCase_ == ValueOneofCase.StrValue) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(StrValue);
+      }
+      if (valueCase_ == ValueOneofCase.IntValue) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(IntValue);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(ChannelArg other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Name.Length != 0) {
+        Name = other.Name;
+      }
+      switch (other.ValueCase) {
+        case ValueOneofCase.StrValue:
+          StrValue = other.StrValue;
+          break;
+        case ValueOneofCase.IntValue:
+          IntValue = other.IntValue;
+          break;
+      }
+
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            Name = input.ReadString();
+            break;
+          }
+          case 18: {
+            StrValue = input.ReadString();
+            break;
+          }
+          case 24: {
+            IntValue = input.ReadInt32();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
   public sealed partial class ClientConfig : pb::IMessage<ClientConfig> {
     private static readonly pb::MessageParser<ClientConfig> _parser = new pb::MessageParser<ClientConfig>(() => new ClientConfig());
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -703,7 +911,7 @@ namespace Grpc.Testing {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[4]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[5]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -733,6 +941,7 @@ namespace Grpc.Testing {
       coreList_ = other.coreList_.Clone();
       coreLimit_ = other.coreLimit_;
       otherClientApi_ = other.otherClientApi_;
+      channelArgs_ = other.channelArgs_.Clone();
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -746,7 +955,7 @@ namespace Grpc.Testing {
         = pb::FieldCodec.ForString(10);
     private readonly pbc::RepeatedField<string> serverTargets_ = new pbc::RepeatedField<string>();
     /// <summary>
-    ///  List of targets to connect to. At least one target needs to be specified.
+    /// List of targets to connect to. At least one target needs to be specified.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<string> ServerTargets {
@@ -779,8 +988,8 @@ namespace Grpc.Testing {
     public const int OutstandingRpcsPerChannelFieldNumber = 4;
     private int outstandingRpcsPerChannel_;
     /// <summary>
-    ///  How many concurrent RPCs to start for each channel.
-    ///  For synchronous client, use a separate thread for each outstanding RPC.
+    /// How many concurrent RPCs to start for each channel.
+    /// For synchronous client, use a separate thread for each outstanding RPC.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int OutstandingRpcsPerChannel {
@@ -794,8 +1003,8 @@ namespace Grpc.Testing {
     public const int ClientChannelsFieldNumber = 5;
     private int clientChannels_;
     /// <summary>
-    ///  Number of independent client channels to create.
-    ///  i-th channel will connect to server_target[i % server_targets.size()]
+    /// Number of independent client channels to create.
+    /// i-th channel will connect to server_target[i % server_targets.size()]
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int ClientChannels {
@@ -809,7 +1018,7 @@ namespace Grpc.Testing {
     public const int AsyncClientThreadsFieldNumber = 7;
     private int asyncClientThreads_;
     /// <summary>
-    ///  Only for async client. Number of threads to use to start/manage RPCs.
+    /// Only for async client. Number of threads to use to start/manage RPCs.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int AsyncClientThreads {
@@ -834,7 +1043,7 @@ namespace Grpc.Testing {
     public const int LoadParamsFieldNumber = 10;
     private global::Grpc.Testing.LoadParams loadParams_;
     /// <summary>
-    ///  The requested load for the entire client (aggregated over all the threads).
+    /// The requested load for the entire client (aggregated over all the threads).
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.LoadParams LoadParams {
@@ -872,7 +1081,7 @@ namespace Grpc.Testing {
         = 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
+    /// Specify the cores we should run the client on, if desired
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<int> CoreList {
@@ -894,7 +1103,7 @@ namespace Grpc.Testing {
     public const int OtherClientApiFieldNumber = 15;
     private string otherClientApi_ = "";
     /// <summary>
-    ///  If we use an OTHER_CLIENT client_type, this string gives more detail
+    /// If we use an OTHER_CLIENT client_type, this string gives more detail
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string OtherClientApi {
@@ -904,6 +1113,16 @@ namespace Grpc.Testing {
       }
     }
 
+    /// <summary>Field number for the "channel_args" field.</summary>
+    public const int ChannelArgsFieldNumber = 16;
+    private static readonly pb::FieldCodec<global::Grpc.Testing.ChannelArg> _repeated_channelArgs_codec
+        = pb::FieldCodec.ForMessage(130, global::Grpc.Testing.ChannelArg.Parser);
+    private readonly pbc::RepeatedField<global::Grpc.Testing.ChannelArg> channelArgs_ = new pbc::RepeatedField<global::Grpc.Testing.ChannelArg>();
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<global::Grpc.Testing.ChannelArg> ChannelArgs {
+      get { return channelArgs_; }
+    }
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ClientConfig);
@@ -930,6 +1149,7 @@ namespace Grpc.Testing {
       if(!coreList_.Equals(other.coreList_)) return false;
       if (CoreLimit != other.CoreLimit) return false;
       if (OtherClientApi != other.OtherClientApi) return false;
+      if(!channelArgs_.Equals(other.channelArgs_)) return false;
       return true;
     }
 
@@ -949,6 +1169,7 @@ namespace Grpc.Testing {
       hash ^= coreList_.GetHashCode();
       if (CoreLimit != 0) hash ^= CoreLimit.GetHashCode();
       if (OtherClientApi.Length != 0) hash ^= OtherClientApi.GetHashCode();
+      hash ^= channelArgs_.GetHashCode();
       return hash;
     }
 
@@ -1005,6 +1226,7 @@ namespace Grpc.Testing {
         output.WriteRawTag(122);
         output.WriteString(OtherClientApi);
       }
+      channelArgs_.WriteTo(output, _repeated_channelArgs_codec);
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1045,6 +1267,7 @@ namespace Grpc.Testing {
       if (OtherClientApi.Length != 0) {
         size += 1 + pb::CodedOutputStream.ComputeStringSize(OtherClientApi);
       }
+      size += channelArgs_.CalculateSize(_repeated_channelArgs_codec);
       return size;
     }
 
@@ -1100,6 +1323,7 @@ namespace Grpc.Testing {
       if (other.OtherClientApi.Length != 0) {
         OtherClientApi = other.OtherClientApi;
       }
+      channelArgs_.Add(other.channelArgs_);
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1175,6 +1399,10 @@ namespace Grpc.Testing {
             OtherClientApi = input.ReadString();
             break;
           }
+          case 130: {
+            channelArgs_.AddEntriesFrom(input, _repeated_channelArgs_codec);
+            break;
+          }
         }
       }
     }
@@ -1188,7 +1416,7 @@ namespace Grpc.Testing {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[5]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[6]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1305,7 +1533,7 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  Request current stats
+  /// Request current stats
   /// </summary>
   public sealed partial class Mark : pb::IMessage<Mark> {
     private static readonly pb::MessageParser<Mark> _parser = new pb::MessageParser<Mark>(() => new Mark());
@@ -1314,7 +1542,7 @@ namespace Grpc.Testing {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[6]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[7]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1343,7 +1571,7 @@ namespace Grpc.Testing {
     public const int ResetFieldNumber = 1;
     private bool reset_;
     /// <summary>
-    ///  if true, the stats will be reset after taking their snapshot.
+    /// if true, the stats will be reset after taking their snapshot.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Reset {
@@ -1434,7 +1662,7 @@ namespace Grpc.Testing {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[7]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[8]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1620,7 +1848,7 @@ namespace Grpc.Testing {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[8]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[9]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1679,7 +1907,7 @@ namespace Grpc.Testing {
     public const int PortFieldNumber = 4;
     private int port_;
     /// <summary>
-    ///  Port on which to listen. Zero means pick unused port.
+    /// Port on which to listen. Zero means pick unused port.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Port {
@@ -1693,7 +1921,7 @@ namespace Grpc.Testing {
     public const int AsyncServerThreadsFieldNumber = 7;
     private int asyncServerThreads_;
     /// <summary>
-    ///  Only for async server. Number of threads used to serve the requests.
+    /// Only for async server. Number of threads used to serve the requests.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int AsyncServerThreads {
@@ -1707,7 +1935,7 @@ namespace Grpc.Testing {
     public const int CoreLimitFieldNumber = 8;
     private int coreLimit_;
     /// <summary>
-    ///  Specify the number of cores to limit server to, if desired
+    /// Specify the number of cores to limit server to, if desired
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CoreLimit {
@@ -1721,7 +1949,10 @@ namespace Grpc.Testing {
     public const int PayloadConfigFieldNumber = 9;
     private global::Grpc.Testing.PayloadConfig payloadConfig_;
     /// <summary>
-    ///  payload config, used in generic server
+    /// payload config, used in generic server.
+    /// Note this must NOT be used in proto (non-generic) servers. For proto servers,
+    /// 'response sizes' must be configured from the 'response_size' field of the
+    /// 'SimpleRequest' objects in RPC requests.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.PayloadConfig PayloadConfig {
@@ -1737,7 +1968,7 @@ namespace Grpc.Testing {
         = 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
+    /// Specify the cores we should run the server on, if desired
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<int> CoreList {
@@ -1748,7 +1979,7 @@ namespace Grpc.Testing {
     public const int OtherServerApiFieldNumber = 11;
     private string otherServerApi_ = "";
     /// <summary>
-    ///  If we use an OTHER_SERVER client_type, this string gives more detail
+    /// If we use an OTHER_SERVER client_type, this string gives more detail
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string OtherServerApi {
@@ -1762,7 +1993,7 @@ namespace Grpc.Testing {
     public const int ResourceQuotaSizeFieldNumber = 1001;
     private int resourceQuotaSize_;
     /// <summary>
-    ///  Buffer pool size (no buffer pool specified if unset)
+    /// Buffer pool size (no buffer pool specified if unset)
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int ResourceQuotaSize {
@@ -1987,7 +2218,7 @@ namespace Grpc.Testing {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[9]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[10]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2173,7 +2404,7 @@ namespace Grpc.Testing {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[10]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[11]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2215,7 +2446,7 @@ namespace Grpc.Testing {
     public const int PortFieldNumber = 2;
     private int port_;
     /// <summary>
-    ///  the port bound by the server
+    /// the port bound by the server
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Port {
@@ -2229,7 +2460,7 @@ namespace Grpc.Testing {
     public const int CoresFieldNumber = 3;
     private int cores_;
     /// <summary>
-    ///  Number of cores available to the server
+    /// Number of cores available to the server
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Cores {
@@ -2358,7 +2589,7 @@ namespace Grpc.Testing {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[11]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[12]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2447,7 +2678,7 @@ namespace Grpc.Testing {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[12]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[13]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2476,7 +2707,7 @@ namespace Grpc.Testing {
     public const int CoresFieldNumber = 1;
     private int cores_;
     /// <summary>
-    ///  Number of cores available on the server
+    /// Number of cores available on the server
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Cores {
@@ -2567,7 +2798,7 @@ namespace Grpc.Testing {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[13]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[14]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2650,7 +2881,7 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  A single performance scenario: input to qps_json_driver
+  /// A single performance scenario: input to qps_json_driver
   /// </summary>
   public sealed partial class Scenario : pb::IMessage<Scenario> {
     private static readonly pb::MessageParser<Scenario> _parser = new pb::MessageParser<Scenario>(() => new Scenario());
@@ -2659,7 +2890,7 @@ namespace Grpc.Testing {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[14]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[15]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2695,7 +2926,7 @@ namespace Grpc.Testing {
     public const int NameFieldNumber = 1;
     private string name_ = "";
     /// <summary>
-    ///  Human readable name for this scenario
+    /// Human readable name for this scenario
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Name {
@@ -2709,7 +2940,7 @@ namespace Grpc.Testing {
     public const int ClientConfigFieldNumber = 2;
     private global::Grpc.Testing.ClientConfig clientConfig_;
     /// <summary>
-    ///  Client configuration
+    /// Client configuration
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.ClientConfig ClientConfig {
@@ -2723,7 +2954,7 @@ namespace Grpc.Testing {
     public const int NumClientsFieldNumber = 3;
     private int numClients_;
     /// <summary>
-    ///  Number of clients to start for the test
+    /// Number of clients to start for the test
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int NumClients {
@@ -2737,7 +2968,7 @@ namespace Grpc.Testing {
     public const int ServerConfigFieldNumber = 4;
     private global::Grpc.Testing.ServerConfig serverConfig_;
     /// <summary>
-    ///  Server configuration
+    /// Server configuration
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.ServerConfig ServerConfig {
@@ -2751,7 +2982,7 @@ namespace Grpc.Testing {
     public const int NumServersFieldNumber = 5;
     private int numServers_;
     /// <summary>
-    ///  Number of servers to start for the test
+    /// Number of servers to start for the test
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int NumServers {
@@ -2765,7 +2996,7 @@ namespace Grpc.Testing {
     public const int WarmupSecondsFieldNumber = 6;
     private int warmupSeconds_;
     /// <summary>
-    ///  Warmup period, in seconds
+    /// Warmup period, in seconds
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int WarmupSeconds {
@@ -2779,7 +3010,7 @@ namespace Grpc.Testing {
     public const int BenchmarkSecondsFieldNumber = 7;
     private int benchmarkSeconds_;
     /// <summary>
-    ///  Benchmark time, in seconds
+    /// Benchmark time, in seconds
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int BenchmarkSeconds {
@@ -2793,7 +3024,7 @@ namespace Grpc.Testing {
     public const int SpawnLocalWorkerCountFieldNumber = 8;
     private int spawnLocalWorkerCount_;
     /// <summary>
-    ///  Number of workers to spawn locally (usually zero)
+    /// Number of workers to spawn locally (usually zero)
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int SpawnLocalWorkerCount {
@@ -3002,7 +3233,7 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  A set of scenarios to be run with qps_json_driver
+  /// A set of scenarios to be run with qps_json_driver
   /// </summary>
   public sealed partial class Scenarios : pb::IMessage<Scenarios> {
     private static readonly pb::MessageParser<Scenarios> _parser = new pb::MessageParser<Scenarios>(() => new Scenarios());
@@ -3011,7 +3242,7 @@ namespace Grpc.Testing {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[15]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[16]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3114,8 +3345,8 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  Basic summary that can be computed from ClientStats and ServerStats
-  ///  once the scenario has finished.
+  /// Basic summary that can be computed from ClientStats and ServerStats
+  /// once the scenario has finished.
   /// </summary>
   public sealed partial class ScenarioResultSummary : pb::IMessage<ScenarioResultSummary> {
     private static readonly pb::MessageParser<ScenarioResultSummary> _parser = new pb::MessageParser<ScenarioResultSummary>(() => new ScenarioResultSummary());
@@ -3124,7 +3355,7 @@ namespace Grpc.Testing {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[16]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[17]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3166,7 +3397,7 @@ namespace Grpc.Testing {
     public const int QpsFieldNumber = 1;
     private double qps_;
     /// <summary>
-    ///  Total number of operations per second over all clients.
+    /// Total number of operations per second over all clients.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double Qps {
@@ -3180,7 +3411,7 @@ namespace Grpc.Testing {
     public const int QpsPerServerCoreFieldNumber = 2;
     private double qpsPerServerCore_;
     /// <summary>
-    ///  QPS per one server core.
+    /// QPS per one server core.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double QpsPerServerCore {
@@ -3194,7 +3425,7 @@ namespace Grpc.Testing {
     public const int ServerSystemTimeFieldNumber = 3;
     private double serverSystemTime_;
     /// <summary>
-    ///  server load based on system_time (0.85 => 85%)
+    /// server load based on system_time (0.85 => 85%)
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double ServerSystemTime {
@@ -3208,7 +3439,7 @@ namespace Grpc.Testing {
     public const int ServerUserTimeFieldNumber = 4;
     private double serverUserTime_;
     /// <summary>
-    ///  server load based on user_time (0.85 => 85%)
+    /// server load based on user_time (0.85 => 85%)
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double ServerUserTime {
@@ -3222,7 +3453,7 @@ namespace Grpc.Testing {
     public const int ClientSystemTimeFieldNumber = 5;
     private double clientSystemTime_;
     /// <summary>
-    ///  client load based on system_time (0.85 => 85%)
+    /// client load based on system_time (0.85 => 85%)
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double ClientSystemTime {
@@ -3236,7 +3467,7 @@ namespace Grpc.Testing {
     public const int ClientUserTimeFieldNumber = 6;
     private double clientUserTime_;
     /// <summary>
-    ///  client load based on user_time (0.85 => 85%)
+    /// client load based on user_time (0.85 => 85%)
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double ClientUserTime {
@@ -3250,7 +3481,7 @@ namespace Grpc.Testing {
     public const int Latency50FieldNumber = 7;
     private double latency50_;
     /// <summary>
-    ///  X% latency percentiles (in nanoseconds)
+    /// X% latency percentiles (in nanoseconds)
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double Latency50 {
@@ -3308,7 +3539,7 @@ namespace Grpc.Testing {
     public const int ServerCpuUsageFieldNumber = 12;
     private double serverCpuUsage_;
     /// <summary>
-    ///  server cpu usage percentage
+    /// server cpu usage percentage
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double ServerCpuUsage {
@@ -3322,7 +3553,7 @@ namespace Grpc.Testing {
     public const int SuccessfulRequestsPerSecondFieldNumber = 13;
     private double successfulRequestsPerSecond_;
     /// <summary>
-    ///  Number of requests that succeeded/failed
+    /// Number of requests that succeeded/failed
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double SuccessfulRequestsPerSecond {
@@ -3626,7 +3857,7 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  Results of a single benchmark scenario.
+  /// Results of a single benchmark scenario.
   /// </summary>
   public sealed partial class ScenarioResult : pb::IMessage<ScenarioResult> {
     private static readonly pb::MessageParser<ScenarioResult> _parser = new pb::MessageParser<ScenarioResult>(() => new ScenarioResult());
@@ -3635,7 +3866,7 @@ namespace Grpc.Testing {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[17]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[18]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3672,7 +3903,7 @@ namespace Grpc.Testing {
     public const int ScenarioFieldNumber = 1;
     private global::Grpc.Testing.Scenario scenario_;
     /// <summary>
-    ///  Inputs used to run the scenario.
+    /// Inputs used to run the scenario.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.Scenario Scenario {
@@ -3686,7 +3917,7 @@ namespace Grpc.Testing {
     public const int LatenciesFieldNumber = 2;
     private global::Grpc.Testing.HistogramData latencies_;
     /// <summary>
-    ///  Histograms from all clients merged into one histogram.
+    /// Histograms from all clients merged into one histogram.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.HistogramData Latencies {
@@ -3702,7 +3933,7 @@ namespace Grpc.Testing {
         = pb::FieldCodec.ForMessage(26, global::Grpc.Testing.ClientStats.Parser);
     private readonly pbc::RepeatedField<global::Grpc.Testing.ClientStats> clientStats_ = new pbc::RepeatedField<global::Grpc.Testing.ClientStats>();
     /// <summary>
-    ///  Client stats for each client
+    /// Client stats for each client
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<global::Grpc.Testing.ClientStats> ClientStats {
@@ -3715,7 +3946,7 @@ namespace Grpc.Testing {
         = pb::FieldCodec.ForMessage(34, global::Grpc.Testing.ServerStats.Parser);
     private readonly pbc::RepeatedField<global::Grpc.Testing.ServerStats> serverStats_ = new pbc::RepeatedField<global::Grpc.Testing.ServerStats>();
     /// <summary>
-    ///  Server stats for each server
+    /// Server stats for each server
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<global::Grpc.Testing.ServerStats> ServerStats {
@@ -3728,7 +3959,7 @@ namespace Grpc.Testing {
         = pb::FieldCodec.ForInt32(42);
     private readonly pbc::RepeatedField<int> serverCores_ = new pbc::RepeatedField<int>();
     /// <summary>
-    ///  Number of cores available to each server
+    /// Number of cores available to each server
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<int> ServerCores {
@@ -3739,7 +3970,7 @@ namespace Grpc.Testing {
     public const int SummaryFieldNumber = 6;
     private global::Grpc.Testing.ScenarioResultSummary summary_;
     /// <summary>
-    ///  An after-the-fact computed summary
+    /// An after-the-fact computed summary
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.ScenarioResultSummary Summary {
@@ -3755,7 +3986,7 @@ namespace Grpc.Testing {
         = pb::FieldCodec.ForBool(58);
     private readonly pbc::RepeatedField<bool> clientSuccess_ = new pbc::RepeatedField<bool>();
     /// <summary>
-    ///  Information on success or failure of each worker
+    /// Information on success or failure of each worker
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<bool> ClientSuccess {
@@ -3778,7 +4009,7 @@ namespace Grpc.Testing {
         = pb::FieldCodec.ForMessage(74, global::Grpc.Testing.RequestResultCount.Parser);
     private readonly pbc::RepeatedField<global::Grpc.Testing.RequestResultCount> requestResults_ = new pbc::RepeatedField<global::Grpc.Testing.RequestResultCount>();
     /// <summary>
-    ///  Number of failed requests (one row per status code seen)
+    /// Number of failed requests (one row per status code seen)
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<global::Grpc.Testing.RequestResultCount> RequestResults {
diff --git a/src/csharp/Grpc.IntegrationTesting/Empty.cs b/src/csharp/Grpc.IntegrationTesting/Empty.cs
index 3017e664b906460770d94f3bcf92f156a63699ef..24ffd617417e2df2e5f5289db9f5e09d10486ee3 100644
--- a/src/csharp/Grpc.IntegrationTesting/Empty.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Empty.cs
@@ -35,13 +35,13 @@ namespace Grpc.Testing {
   }
   #region Messages
   /// <summary>
-  ///  An empty message that you can re-use to avoid defining duplicated empty
-  ///  messages in your project. A typical example is to use it as argument or the
-  ///  return value of a service API. For instance:
+  /// An empty message that you can re-use to avoid defining duplicated empty
+  /// messages in your project. A typical example is to use it as argument or the
+  /// return value of a service API. For instance:
   ///
-  ///    service Foo {
-  ///      rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { };
-  ///    };
+  ///   service Foo {
+  ///     rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { };
+  ///   };
   /// </summary>
   public sealed partial class Empty : pb::IMessage<Empty> {
     private static readonly pb::MessageParser<Empty> _parser = new pb::MessageParser<Empty>(() => new Empty());
diff --git a/src/csharp/Grpc.IntegrationTesting/GeneratedServiceBaseTest.cs b/src/csharp/Grpc.IntegrationTesting/GeneratedServiceBaseTest.cs
index 4216dc1d6be6813646dde7c8c807431c983e9f5d..780a9b73047257ba0b3b1f5cb89b59dc1c77a1ea 100644
--- a/src/csharp/Grpc.IntegrationTesting/GeneratedServiceBaseTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/GeneratedServiceBaseTest.cs
@@ -54,7 +54,8 @@ namespace Grpc.IntegrationTesting
         [SetUp]
         public void Init()
         {
-            server = new Server
+            // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755
+            server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
             {
                 Services = { TestService.BindService(new UnimplementedTestServiceImpl()) },
                 Ports = { { Host, ServerPort.PickUnused, SslServerCredentials.Insecure } }
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
old mode 100644
new mode 100755
index f7abcf8046997557a4e64e3a8147b899c81c7260..6f2f06a652291ade7af46a81a8e0947e6f46ef87
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
+++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
@@ -1,158 +1,56 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+  <Import Project="..\Grpc.Core\Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{C61154BA-DD4A-4838-8420-0162A28925E0}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>Grpc.IntegrationTesting</RootNamespace>
+    <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
     <AssemblyName>Grpc.IntegrationTesting</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <NuGetPackageImportStamp>3a1c655d</NuGetPackageImportStamp>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>AnyCPU</PlatformTarget>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>AnyCPU</PlatformTarget>
+    <OutputType>Exe</OutputType>
+    <PackageId>Grpc.IntegrationTesting</PackageId>
+    <PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
+    <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Net" />
-    <Reference Include="System.Net.Http" />
-    <Reference Include="System.Net.Http.WebRequest" />
-    <Reference Include="BouncyCastle.Crypto">
-      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
-    </Reference>
-    <Reference Include="Newtonsoft.Json">
-      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
-    </Reference>
-    <Reference Include="nunit.framework">
-      <HintPath>..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll</HintPath>
-    </Reference>
-    <Reference Include="nunitlite">
-      <HintPath>..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll</HintPath>
-    </Reference>
-    <Reference Include="CommandLineParser.Unofficial">
-      <HintPath>..\packages\CommandLineParser.Unofficial.2.0.275\lib\net45\CommandLineParser.Unofficial.dll</HintPath>
-    </Reference>
-    <Reference Include="log4net">
-      <HintPath>..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Core">
-      <HintPath>..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="Zlib.Portable">
-      <HintPath>..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis">
-      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.PlatformServices">
-      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth">
-      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth.PlatformServices">
-      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Protobuf">
-      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
-    </Reference>
-    <Reference Include="Castle.Core">
-      <HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="Moq">
-      <HintPath>..\packages\Moq.4.6.38-alpha\lib\net45\Moq.dll</HintPath>
-    </Reference>
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
-    </Reference>
+    <ProjectReference Include="../Grpc.Auth/Grpc.Auth.csproj" />
+    <ProjectReference Include="../Grpc.Core/Grpc.Core.csproj" />
   </ItemGroup>
+
   <ItemGroup>
-    <Compile Include="..\Grpc.Core\Version.cs">
-      <Link>Version.cs</Link>
-    </Compile>
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Empty.cs" />
-    <Compile Include="Messages.cs" />
-    <Compile Include="InteropClientServerTest.cs" />
-    <Compile Include="MetadataCredentialsTest.cs" />
-    <Compile Include="TestServiceImpl.cs" />
-    <Compile Include="InteropServer.cs" />
-    <Compile Include="InteropClient.cs" />
-    <Compile Include="TestCredentials.cs" />
-    <Compile Include="TestGrpc.cs" />
-    <Compile Include="SslCredentialsTest.cs" />
-    <Compile Include="Test.cs" />
-    <Compile Include="IClientRunner.cs" />
-    <Compile Include="ClientRunners.cs" />
-    <Compile Include="IServerRunner.cs" />
-    <Compile Include="ServerRunners.cs" />
-    <Compile Include="RunnerClientServerTest.cs" />
-    <Compile Include="Control.cs" />
-    <Compile Include="Payloads.cs" />
-    <Compile Include="Services.cs" />
-    <Compile Include="ServicesGrpc.cs" />
-    <Compile Include="Stats.cs" />
-    <Compile Include="BenchmarkServiceImpl.cs" />
-    <Compile Include="Histogram.cs" />
-    <Compile Include="HistogramTest.cs" />
-    <Compile Include="WorkerServiceImpl.cs" />
-    <Compile Include="QpsWorker.cs" />
-    <Compile Include="WallClockStopwatch.cs" />
-    <Compile Include="GenericService.cs" />
-    <Compile Include="GeneratedServiceBaseTest.cs" />
-    <Compile Include="GeneratedClientTest.cs" />
-    <Compile Include="InterarrivalTimers.cs" />
-    <Compile Include="NUnitMain.cs" />
-    <Compile Include="StressTestClient.cs" />
-    <Compile Include="Metrics.cs" />
-    <Compile Include="MetricsGrpc.cs" />
+    <PackageReference Include="Google.Protobuf" Version="$(GoogleProtobufVersion)" />
+    <PackageReference Include="CommandLineParser" Version="2.1.1-beta" />
+    <PackageReference Include="Moq" Version="4.7.0" />
+    <PackageReference Include="NUnit" Version="3.6.0" />
+    <PackageReference Include="NUnitLite" Version="3.6.0" />
   </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
+  </ItemGroup>
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">
+    <PackageReference Include="System.Linq.Expressions" Version="4.1.1" />
+  </ItemGroup>
+
   <ItemGroup>
-    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
-      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
-      <Name>Grpc.Core</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Grpc.Auth\Grpc.Auth.csproj">
-      <Project>{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}</Project>
-      <Name>Grpc.Auth</Name>
-    </ProjectReference>
+    <Compile Include="..\Grpc.Core\Version.cs" />
   </ItemGroup>
+
   <ItemGroup>
-    <None Include="Grpc.IntegrationTesting.project.json" />
-    <None Include="packages.config">
-      <SubType>Designer</SubType>
-    </None>
-    <None Include="data\README">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="data\ca.pem">
+    <Content Include="data\server1.pem">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="data\server1.key">
+      <Pack>false</Pack>
+    </Content>
+    <Content Include="data\server1.key">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="data\server1.pem">
+      <Pack>false</Pack>
+    </Content>
+    <Content Include="data\ca.pem">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-  </ItemGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+      <Pack>false</Pack>
+    </Content>
   </ItemGroup>
+
 </Project>
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.project.json b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.xproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.xproj
deleted file mode 100644
index 357300ecb9b9a75cf035d0a062a8126727d0ca7d..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>20354386-3e71-4046-a269-3bc2a06f3ec8</ProjectGuid>
-    <RootNamespace>Grpc.IntegrationTesting</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
index 4960a53f92d6c3ca9ec43ada9277899c79368020..04f833fcf5e8ec53c31416a0a4fd1100f561757e 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
@@ -56,7 +56,8 @@ namespace Grpc.IntegrationTesting
         [TestFixtureSetUp]
         public void Init()
         {
-            server = new Server
+            // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755
+            server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
             {
                 Services = { TestService.BindService(new TestServiceImpl()) },
                 Ports = { { Host, ServerPort.PickUnused, TestCredentials.CreateSslServerCredentials() } }
diff --git a/src/csharp/Grpc.IntegrationTesting/Messages.cs b/src/csharp/Grpc.IntegrationTesting/Messages.cs
index 369fe738d6ca02fbd966e970c116cc3547c9ebec..278ef662e4719bea4036062f959f3859b4c19dd7 100644
--- a/src/csharp/Grpc.IntegrationTesting/Messages.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Messages.cs
@@ -75,12 +75,12 @@ namespace Grpc.Testing {
   }
   #region Enums
   /// <summary>
-  ///  DEPRECATED, don't use. To be removed shortly.
-  ///  The type of payload that should be returned.
+  /// DEPRECATED, don't use. To be removed shortly.
+  /// The type of payload that should be returned.
   /// </summary>
   public enum PayloadType {
     /// <summary>
-    ///  Compressable text format.
+    /// Compressable text format.
     /// </summary>
     [pbr::OriginalName("COMPRESSABLE")] Compressable = 0,
   }
@@ -89,9 +89,9 @@ namespace Grpc.Testing {
 
   #region Messages
   /// <summary>
-  ///  TODO(dgq): Go back to using well-known types once
-  ///  https://github.com/grpc/grpc/issues/6980 has been fixed.
-  ///  import "google/protobuf/wrappers.proto";
+  /// TODO(dgq): Go back to using well-known types once
+  /// https://github.com/grpc/grpc/issues/6980 has been fixed.
+  /// import "google/protobuf/wrappers.proto";
   /// </summary>
   public sealed partial class BoolValue : pb::IMessage<BoolValue> {
     private static readonly pb::MessageParser<BoolValue> _parser = new pb::MessageParser<BoolValue>(() => new BoolValue());
@@ -129,7 +129,7 @@ namespace Grpc.Testing {
     public const int ValueFieldNumber = 1;
     private bool value_;
     /// <summary>
-    ///  The bool value.
+    /// The bool value.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Value {
@@ -214,7 +214,7 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  A block of data, to simply increase gRPC message size.
+  /// A block of data, to simply increase gRPC message size.
   /// </summary>
   public sealed partial class Payload : pb::IMessage<Payload> {
     private static readonly pb::MessageParser<Payload> _parser = new pb::MessageParser<Payload>(() => new Payload());
@@ -253,8 +253,8 @@ namespace Grpc.Testing {
     public const int TypeFieldNumber = 1;
     private global::Grpc.Testing.PayloadType type_ = 0;
     /// <summary>
-    ///  DEPRECATED, don't use. To be removed shortly.
-    ///  The type of data in body.
+    /// DEPRECATED, don't use. To be removed shortly.
+    /// The type of data in body.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.PayloadType Type {
@@ -268,7 +268,7 @@ namespace Grpc.Testing {
     public const int BodyFieldNumber = 2;
     private pb::ByteString body_ = pb::ByteString.Empty;
     /// <summary>
-    ///  Primary contents of payload.
+    /// Primary contents of payload.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pb::ByteString Body {
@@ -369,8 +369,8 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  A protobuf representation for grpc status. This is used by test
-  ///  clients to specify a status that the server should attempt to return.
+  /// A protobuf representation for grpc status. This is used by test
+  /// clients to specify a status that the server should attempt to return.
   /// </summary>
   public sealed partial class EchoStatus : pb::IMessage<EchoStatus> {
     private static readonly pb::MessageParser<EchoStatus> _parser = new pb::MessageParser<EchoStatus>(() => new EchoStatus());
@@ -518,7 +518,7 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  Unary request.
+  /// Unary request.
   /// </summary>
   public sealed partial class SimpleRequest : pb::IMessage<SimpleRequest> {
     private static readonly pb::MessageParser<SimpleRequest> _parser = new pb::MessageParser<SimpleRequest>(() => new SimpleRequest());
@@ -563,9 +563,9 @@ namespace Grpc.Testing {
     public const int ResponseTypeFieldNumber = 1;
     private global::Grpc.Testing.PayloadType responseType_ = 0;
     /// <summary>
-    ///  DEPRECATED, don't use. To be removed shortly.
-    ///  Desired payload type in the response from the server.
-    ///  If response_type is RANDOM, server randomly chooses one from other formats.
+    /// DEPRECATED, don't use. To be removed shortly.
+    /// Desired payload type in the response from the server.
+    /// If response_type is RANDOM, server randomly chooses one from other formats.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.PayloadType ResponseType {
@@ -579,7 +579,7 @@ namespace Grpc.Testing {
     public const int ResponseSizeFieldNumber = 2;
     private int responseSize_;
     /// <summary>
-    ///  Desired payload size in the response from the server.
+    /// Desired payload size in the response from the server.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int ResponseSize {
@@ -593,7 +593,7 @@ namespace Grpc.Testing {
     public const int PayloadFieldNumber = 3;
     private global::Grpc.Testing.Payload payload_;
     /// <summary>
-    ///  Optional input payload sent along with the request.
+    /// Optional input payload sent along with the request.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.Payload Payload {
@@ -607,7 +607,7 @@ namespace Grpc.Testing {
     public const int FillUsernameFieldNumber = 4;
     private bool fillUsername_;
     /// <summary>
-    ///  Whether SimpleResponse should include username.
+    /// Whether SimpleResponse should include username.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool FillUsername {
@@ -621,7 +621,7 @@ namespace Grpc.Testing {
     public const int FillOauthScopeFieldNumber = 5;
     private bool fillOauthScope_;
     /// <summary>
-    ///  Whether SimpleResponse should include OAuth scope.
+    /// Whether SimpleResponse should include OAuth scope.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool FillOauthScope {
@@ -635,10 +635,10 @@ namespace Grpc.Testing {
     public const int ResponseCompressedFieldNumber = 6;
     private global::Grpc.Testing.BoolValue responseCompressed_;
     /// <summary>
-    ///  Whether to request the server to compress the response. This field is
-    ///  "nullable" in order to interoperate seamlessly with clients not able to
-    ///  implement the full compression tests by introspecting the call to verify
-    ///  the response's compression status.
+    /// Whether to request the server to compress the response. This field is
+    /// "nullable" in order to interoperate seamlessly with clients not able to
+    /// implement the full compression tests by introspecting the call to verify
+    /// the response's compression status.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.BoolValue ResponseCompressed {
@@ -652,7 +652,7 @@ namespace Grpc.Testing {
     public const int ResponseStatusFieldNumber = 7;
     private global::Grpc.Testing.EchoStatus responseStatus_;
     /// <summary>
-    ///  Whether server should return a given status
+    /// Whether server should return a given status
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.EchoStatus ResponseStatus {
@@ -666,7 +666,7 @@ namespace Grpc.Testing {
     public const int ExpectCompressedFieldNumber = 8;
     private global::Grpc.Testing.BoolValue expectCompressed_;
     /// <summary>
-    ///  Whether the server should expect this request to be compressed.
+    /// Whether the server should expect this request to be compressed.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.BoolValue ExpectCompressed {
@@ -887,7 +887,7 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  Unary response, as configured by the request.
+  /// Unary response, as configured by the request.
   /// </summary>
   public sealed partial class SimpleResponse : pb::IMessage<SimpleResponse> {
     private static readonly pb::MessageParser<SimpleResponse> _parser = new pb::MessageParser<SimpleResponse>(() => new SimpleResponse());
@@ -927,7 +927,7 @@ namespace Grpc.Testing {
     public const int PayloadFieldNumber = 1;
     private global::Grpc.Testing.Payload payload_;
     /// <summary>
-    ///  Payload to increase message size.
+    /// Payload to increase message size.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.Payload Payload {
@@ -941,8 +941,8 @@ namespace Grpc.Testing {
     public const int UsernameFieldNumber = 2;
     private string username_ = "";
     /// <summary>
-    ///  The user the request came from, for verifying authentication was
-    ///  successful when the client expected it.
+    /// The user the request came from, for verifying authentication was
+    /// successful when the client expected it.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Username {
@@ -956,7 +956,7 @@ namespace Grpc.Testing {
     public const int OauthScopeFieldNumber = 3;
     private string oauthScope_ = "";
     /// <summary>
-    ///  OAuth scope.
+    /// OAuth scope.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string OauthScope {
@@ -1079,7 +1079,7 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  Client-streaming request.
+  /// Client-streaming request.
   /// </summary>
   public sealed partial class StreamingInputCallRequest : pb::IMessage<StreamingInputCallRequest> {
     private static readonly pb::MessageParser<StreamingInputCallRequest> _parser = new pb::MessageParser<StreamingInputCallRequest>(() => new StreamingInputCallRequest());
@@ -1118,7 +1118,7 @@ namespace Grpc.Testing {
     public const int PayloadFieldNumber = 1;
     private global::Grpc.Testing.Payload payload_;
     /// <summary>
-    ///  Optional input payload sent along with the request.
+    /// Optional input payload sent along with the request.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.Payload Payload {
@@ -1132,10 +1132,10 @@ namespace Grpc.Testing {
     public const int ExpectCompressedFieldNumber = 2;
     private global::Grpc.Testing.BoolValue expectCompressed_;
     /// <summary>
-    ///  Whether the server should expect this request to be compressed. This field
-    ///  is "nullable" in order to interoperate seamlessly with servers not able to
-    ///  implement the full compression tests by introspecting the call to verify
-    ///  the request's compression status.
+    /// Whether the server should expect this request to be compressed. This field
+    /// is "nullable" in order to interoperate seamlessly with servers not able to
+    /// implement the full compression tests by introspecting the call to verify
+    /// the request's compression status.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.BoolValue ExpectCompressed {
@@ -1248,7 +1248,7 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  Client-streaming response.
+  /// Client-streaming response.
   /// </summary>
   public sealed partial class StreamingInputCallResponse : pb::IMessage<StreamingInputCallResponse> {
     private static readonly pb::MessageParser<StreamingInputCallResponse> _parser = new pb::MessageParser<StreamingInputCallResponse>(() => new StreamingInputCallResponse());
@@ -1286,7 +1286,7 @@ namespace Grpc.Testing {
     public const int AggregatedPayloadSizeFieldNumber = 1;
     private int aggregatedPayloadSize_;
     /// <summary>
-    ///  Aggregated size of payloads received from the client.
+    /// Aggregated size of payloads received from the client.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int AggregatedPayloadSize {
@@ -1371,7 +1371,7 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  Configuration for a particular response.
+  /// Configuration for a particular response.
   /// </summary>
   public sealed partial class ResponseParameters : pb::IMessage<ResponseParameters> {
     private static readonly pb::MessageParser<ResponseParameters> _parser = new pb::MessageParser<ResponseParameters>(() => new ResponseParameters());
@@ -1411,7 +1411,7 @@ namespace Grpc.Testing {
     public const int SizeFieldNumber = 1;
     private int size_;
     /// <summary>
-    ///  Desired payload sizes in responses from the server.
+    /// Desired payload sizes in responses from the server.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Size {
@@ -1425,8 +1425,8 @@ namespace Grpc.Testing {
     public const int IntervalUsFieldNumber = 2;
     private int intervalUs_;
     /// <summary>
-    ///  Desired interval between consecutive responses in the response stream in
-    ///  microseconds.
+    /// Desired interval between consecutive responses in the response stream in
+    /// microseconds.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int IntervalUs {
@@ -1440,10 +1440,10 @@ namespace Grpc.Testing {
     public const int CompressedFieldNumber = 3;
     private global::Grpc.Testing.BoolValue compressed_;
     /// <summary>
-    ///  Whether to request the server to compress the response. This field is
-    ///  "nullable" in order to interoperate seamlessly with clients not able to
-    ///  implement the full compression tests by introspecting the call to verify
-    ///  the response's compression status.
+    /// Whether to request the server to compress the response. This field is
+    /// "nullable" in order to interoperate seamlessly with clients not able to
+    /// implement the full compression tests by introspecting the call to verify
+    /// the response's compression status.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.BoolValue Compressed {
@@ -1566,7 +1566,7 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  Server-streaming request.
+  /// Server-streaming request.
   /// </summary>
   public sealed partial class StreamingOutputCallRequest : pb::IMessage<StreamingOutputCallRequest> {
     private static readonly pb::MessageParser<StreamingOutputCallRequest> _parser = new pb::MessageParser<StreamingOutputCallRequest>(() => new StreamingOutputCallRequest());
@@ -1607,11 +1607,11 @@ namespace Grpc.Testing {
     public const int ResponseTypeFieldNumber = 1;
     private global::Grpc.Testing.PayloadType responseType_ = 0;
     /// <summary>
-    ///  DEPRECATED, don't use. To be removed shortly.
-    ///  Desired payload type in the response from the server.
-    ///  If response_type is RANDOM, the payload from each response in the stream
-    ///  might be of different types. This is to simulate a mixed type of payload
-    ///  stream.
+    /// DEPRECATED, don't use. To be removed shortly.
+    /// Desired payload type in the response from the server.
+    /// If response_type is RANDOM, the payload from each response in the stream
+    /// might be of different types. This is to simulate a mixed type of payload
+    /// stream.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.PayloadType ResponseType {
@@ -1627,7 +1627,7 @@ namespace Grpc.Testing {
         = pb::FieldCodec.ForMessage(18, global::Grpc.Testing.ResponseParameters.Parser);
     private readonly pbc::RepeatedField<global::Grpc.Testing.ResponseParameters> responseParameters_ = new pbc::RepeatedField<global::Grpc.Testing.ResponseParameters>();
     /// <summary>
-    ///  Configuration for each expected response message.
+    /// Configuration for each expected response message.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<global::Grpc.Testing.ResponseParameters> ResponseParameters {
@@ -1638,7 +1638,7 @@ namespace Grpc.Testing {
     public const int PayloadFieldNumber = 3;
     private global::Grpc.Testing.Payload payload_;
     /// <summary>
-    ///  Optional input payload sent along with the request.
+    /// Optional input payload sent along with the request.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.Payload Payload {
@@ -1652,7 +1652,7 @@ namespace Grpc.Testing {
     public const int ResponseStatusFieldNumber = 7;
     private global::Grpc.Testing.EchoStatus responseStatus_;
     /// <summary>
-    ///  Whether server should return a given status
+    /// Whether server should return a given status
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.EchoStatus ResponseStatus {
@@ -1790,7 +1790,7 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  Server-streaming response, as configured by the request and parameters.
+  /// Server-streaming response, as configured by the request and parameters.
   /// </summary>
   public sealed partial class StreamingOutputCallResponse : pb::IMessage<StreamingOutputCallResponse> {
     private static readonly pb::MessageParser<StreamingOutputCallResponse> _parser = new pb::MessageParser<StreamingOutputCallResponse>(() => new StreamingOutputCallResponse());
@@ -1828,7 +1828,7 @@ namespace Grpc.Testing {
     public const int PayloadFieldNumber = 1;
     private global::Grpc.Testing.Payload payload_;
     /// <summary>
-    ///  Payload to increase response size.
+    /// Payload to increase response size.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.Payload Payload {
@@ -1919,8 +1919,8 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  For reconnect interop test only.
-  ///  Client tells server what reconnection parameters it used.
+  /// For reconnect interop test only.
+  /// Client tells server what reconnection parameters it used.
   /// </summary>
   public sealed partial class ReconnectParams : pb::IMessage<ReconnectParams> {
     private static readonly pb::MessageParser<ReconnectParams> _parser = new pb::MessageParser<ReconnectParams>(() => new ReconnectParams());
@@ -2040,9 +2040,9 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  For reconnect interop test only.
-  ///  Server tells client whether its reconnects are following the spec and the
-  ///  reconnect backoffs it saw.
+  /// For reconnect interop test only.
+  /// Server tells client whether its reconnects are following the spec and the
+  /// reconnect backoffs it saw.
   /// </summary>
   public sealed partial class ReconnectInfo : pb::IMessage<ReconnectInfo> {
     private static readonly pb::MessageParser<ReconnectInfo> _parser = new pb::MessageParser<ReconnectInfo>(() => new ReconnectInfo());
diff --git a/src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs
index d55e658d949d482f5f25c6cc8c54466188e12cbf..ef63f530f68dd9d8a78ced9e5722f8295f197288 100644
--- a/src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs
@@ -56,7 +56,8 @@ namespace Grpc.IntegrationTesting
         [SetUp]
         public void Init()
         {
-            server = new Server
+            // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755
+            server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
             {
                 Services = { TestService.BindService(new FakeTestService()) },
                 Ports = { { Host, ServerPort.PickUnused, TestCredentials.CreateSslServerCredentials() } }
diff --git a/src/csharp/Grpc.IntegrationTesting/Metrics.cs b/src/csharp/Grpc.IntegrationTesting/Metrics.cs
index 4de1847e5fb970a037f938fd8d4cfeabb41aaf83..84eb09af4fb7b909a30ff6350477e93201823d2e 100644
--- a/src/csharp/Grpc.IntegrationTesting/Metrics.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Metrics.cs
@@ -44,7 +44,7 @@ namespace Grpc.Testing {
   }
   #region Messages
   /// <summary>
-  ///  Reponse message containing the gauge name and value
+  /// Reponse message containing the gauge name and value
   /// </summary>
   public sealed partial class GaugeResponse : pb::IMessage<GaugeResponse> {
     private static readonly pb::MessageParser<GaugeResponse> _parser = new pb::MessageParser<GaugeResponse>(() => new GaugeResponse());
@@ -282,7 +282,7 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  Request message containing the gauge name
+  /// Request message containing the gauge name
   /// </summary>
   public sealed partial class GaugeRequest : pb::IMessage<GaugeRequest> {
     private static readonly pb::MessageParser<GaugeRequest> _parser = new pb::MessageParser<GaugeRequest>(() => new GaugeRequest());
diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
index 8b58622d5308860167c8dbc06709918e7ae84df6..c80ffa8cf6793cd5180162d8405bc553281b4634 100644
--- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
@@ -41,26 +41,26 @@
 using System;
 using System.Threading;
 using System.Threading.Tasks;
-using Grpc.Core;
+using grpc = global::Grpc.Core;
 
 namespace Grpc.Testing {
   public static partial class MetricsService
   {
     static readonly string __ServiceName = "grpc.testing.MetricsService";
 
-    static readonly Marshaller<global::Grpc.Testing.EmptyMessage> __Marshaller_EmptyMessage = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.EmptyMessage.Parser.ParseFrom);
-    static readonly Marshaller<global::Grpc.Testing.GaugeResponse> __Marshaller_GaugeResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.GaugeResponse.Parser.ParseFrom);
-    static readonly Marshaller<global::Grpc.Testing.GaugeRequest> __Marshaller_GaugeRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.GaugeRequest.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.EmptyMessage> __Marshaller_EmptyMessage = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.EmptyMessage.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.GaugeResponse> __Marshaller_GaugeResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.GaugeResponse.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.GaugeRequest> __Marshaller_GaugeRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.GaugeRequest.Parser.ParseFrom);
 
-    static readonly Method<global::Grpc.Testing.EmptyMessage, global::Grpc.Testing.GaugeResponse> __Method_GetAllGauges = new Method<global::Grpc.Testing.EmptyMessage, global::Grpc.Testing.GaugeResponse>(
-        MethodType.ServerStreaming,
+    static readonly grpc::Method<global::Grpc.Testing.EmptyMessage, global::Grpc.Testing.GaugeResponse> __Method_GetAllGauges = new grpc::Method<global::Grpc.Testing.EmptyMessage, global::Grpc.Testing.GaugeResponse>(
+        grpc::MethodType.ServerStreaming,
         __ServiceName,
         "GetAllGauges",
         __Marshaller_EmptyMessage,
         __Marshaller_GaugeResponse);
 
-    static readonly Method<global::Grpc.Testing.GaugeRequest, global::Grpc.Testing.GaugeResponse> __Method_GetGauge = new Method<global::Grpc.Testing.GaugeRequest, global::Grpc.Testing.GaugeResponse>(
-        MethodType.Unary,
+    static readonly grpc::Method<global::Grpc.Testing.GaugeRequest, global::Grpc.Testing.GaugeResponse> __Method_GetGauge = new grpc::Method<global::Grpc.Testing.GaugeRequest, global::Grpc.Testing.GaugeResponse>(
+        grpc::MethodType.Unary,
         __ServiceName,
         "GetGauge",
         __Marshaller_GaugeRequest,
@@ -83,9 +83,9 @@ namespace Grpc.Testing {
       /// <param name="responseStream">Used for sending responses back to the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>A task indicating completion of the handler.</returns>
-      public virtual global::System.Threading.Tasks.Task GetAllGauges(global::Grpc.Testing.EmptyMessage request, IServerStreamWriter<global::Grpc.Testing.GaugeResponse> responseStream, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task GetAllGauges(global::Grpc.Testing.EmptyMessage request, grpc::IServerStreamWriter<global::Grpc.Testing.GaugeResponse> responseStream, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
@@ -94,24 +94,24 @@ namespace Grpc.Testing {
       /// <param name="request">The request received from the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.GaugeResponse> GetGauge(global::Grpc.Testing.GaugeRequest request, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.GaugeResponse> GetGauge(global::Grpc.Testing.GaugeRequest request, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
     }
 
     /// <summary>Client for MetricsService</summary>
-    public partial class MetricsServiceClient : ClientBase<MetricsServiceClient>
+    public partial class MetricsServiceClient : grpc::ClientBase<MetricsServiceClient>
     {
       /// <summary>Creates a new client for MetricsService</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
-      public MetricsServiceClient(Channel channel) : base(channel)
+      public MetricsServiceClient(grpc::Channel channel) : base(channel)
       {
       }
       /// <summary>Creates a new client for MetricsService that uses a custom <c>CallInvoker</c>.</summary>
       /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
-      public MetricsServiceClient(CallInvoker callInvoker) : base(callInvoker)
+      public MetricsServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
       {
       }
       /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
@@ -133,9 +133,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncServerStreamingCall<global::Grpc.Testing.GaugeResponse> GetAllGauges(global::Grpc.Testing.EmptyMessage request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.GaugeResponse> GetAllGauges(global::Grpc.Testing.EmptyMessage request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return GetAllGauges(request, new CallOptions(headers, deadline, cancellationToken));
+        return GetAllGauges(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// Returns the values of all the gauges that are currently being maintained by
@@ -144,7 +144,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncServerStreamingCall<global::Grpc.Testing.GaugeResponse> GetAllGauges(global::Grpc.Testing.EmptyMessage request, CallOptions options)
+      public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.GaugeResponse> GetAllGauges(global::Grpc.Testing.EmptyMessage request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncServerStreamingCall(__Method_GetAllGauges, null, options, request);
       }
@@ -156,9 +156,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.GaugeResponse GetGauge(global::Grpc.Testing.GaugeRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.GaugeResponse GetGauge(global::Grpc.Testing.GaugeRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return GetGauge(request, new CallOptions(headers, deadline, cancellationToken));
+        return GetGauge(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// Returns the value of one gauge
@@ -166,7 +166,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.GaugeResponse GetGauge(global::Grpc.Testing.GaugeRequest request, CallOptions options)
+      public virtual global::Grpc.Testing.GaugeResponse GetGauge(global::Grpc.Testing.GaugeRequest request, grpc::CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_GetGauge, null, options, request);
       }
@@ -178,9 +178,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.GaugeResponse> GetGaugeAsync(global::Grpc.Testing.GaugeRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.GaugeResponse> GetGaugeAsync(global::Grpc.Testing.GaugeRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return GetGaugeAsync(request, new CallOptions(headers, deadline, cancellationToken));
+        return GetGaugeAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// Returns the value of one gauge
@@ -188,7 +188,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.GaugeResponse> GetGaugeAsync(global::Grpc.Testing.GaugeRequest request, CallOptions options)
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.GaugeResponse> GetGaugeAsync(global::Grpc.Testing.GaugeRequest request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_GetGauge, null, options, request);
       }
@@ -201,9 +201,9 @@ namespace Grpc.Testing {
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
-    public static ServerServiceDefinition BindService(MetricsServiceBase serviceImpl)
+    public static grpc::ServerServiceDefinition BindService(MetricsServiceBase serviceImpl)
     {
-      return ServerServiceDefinition.CreateBuilder()
+      return grpc::ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_GetAllGauges, serviceImpl.GetAllGauges)
           .AddMethod(__Method_GetGauge, serviceImpl.GetGauge).Build();
     }
diff --git a/src/csharp/Grpc.IntegrationTesting/Payloads.cs b/src/csharp/Grpc.IntegrationTesting/Payloads.cs
index 7aef35cda31d5430891aee8627633956d7497f01..f918b9576bdf80dfd2d8e1072004129c760eaa09 100644
--- a/src/csharp/Grpc.IntegrationTesting/Payloads.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Payloads.cs
@@ -335,8 +335,8 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  TODO (vpai): Fill this in once the details of complex, representative
-  ///               protos are decided
+  /// TODO (vpai): Fill this in once the details of complex, representative
+  ///              protos are decided
   /// </summary>
   public sealed partial class ComplexProtoParams : pb::IMessage<ComplexProtoParams> {
     private static readonly pb::MessageParser<ComplexProtoParams> _parser = new pb::MessageParser<ComplexProtoParams>(() => new ComplexProtoParams());
diff --git a/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs b/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs
index b17b2c2183a2860714503829fa04966f24dc77f1..486befe964c3681f85431dabd291eedfa403c97b 100644
--- a/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs
+++ b/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs
@@ -95,10 +95,13 @@ namespace Grpc.IntegrationTesting
                 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));
+            GrpcEnvironment.Logger.Info("Running qps worker server on {0}:{1}", host, boundPort);
             server.Start();
             await tcs.Task;
             await server.ShutdownAsync();
+
+            GrpcEnvironment.Logger.Info("GC collection counts (after shutdown): gen0 {0}, gen1 {1}, gen2 {2}, gen3 {3}",
+                GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2), GC.CollectionCount(3));
         }
     }
 }
diff --git a/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs b/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs
index 8689d188aed4ea5bd4eb6f4c15725c4084339c7d..7ab773470057bd2ad2a7a3940a0d6ae44b330ebe 100644
--- a/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs
@@ -154,6 +154,9 @@ namespace Grpc.IntegrationTesting
         {
             var secondsElapsed = wallClockStopwatch.GetElapsedSnapshot(reset).TotalSeconds;
 
+            GrpcEnvironment.Logger.Info("[ServerRunner.GetStats] GC collection counts: gen0 {0}, gen1 {1}, gen2 {2}, gen3 {3} (seconds since last reset {4})",
+                GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2), GC.CollectionCount(3), secondsElapsed);
+
             // TODO: populate user time and system time
             return new ServerStats
             {
diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
index 5135d9ab66d18aa4abf151f9a493cba7258037f1..bb95c8a549f11a3fdd8c45b29e76d43a45695d0b 100644
--- a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
@@ -37,25 +37,25 @@
 using System;
 using System.Threading;
 using System.Threading.Tasks;
-using Grpc.Core;
+using grpc = global::Grpc.Core;
 
 namespace Grpc.Testing {
   public static partial class BenchmarkService
   {
     static readonly string __ServiceName = "grpc.testing.BenchmarkService";
 
-    static readonly Marshaller<global::Grpc.Testing.SimpleRequest> __Marshaller_SimpleRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleRequest.Parser.ParseFrom);
-    static readonly Marshaller<global::Grpc.Testing.SimpleResponse> __Marshaller_SimpleResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleResponse.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.SimpleRequest> __Marshaller_SimpleRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleRequest.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.SimpleResponse> __Marshaller_SimpleResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleResponse.Parser.ParseFrom);
 
-    static readonly Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_UnaryCall = new Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
-        MethodType.Unary,
+    static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_UnaryCall = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+        grpc::MethodType.Unary,
         __ServiceName,
         "UnaryCall",
         __Marshaller_SimpleRequest,
         __Marshaller_SimpleResponse);
 
-    static readonly Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingCall = new Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
-        MethodType.DuplexStreaming,
+    static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingCall = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+        grpc::MethodType.DuplexStreaming,
         __ServiceName,
         "StreamingCall",
         __Marshaller_SimpleRequest,
@@ -77,9 +77,9 @@ namespace Grpc.Testing {
       /// <param name="request">The request received from the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
@@ -90,24 +90,24 @@ namespace Grpc.Testing {
       /// <param name="responseStream">Used for sending responses back to the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>A task indicating completion of the handler.</returns>
-      public virtual global::System.Threading.Tasks.Task StreamingCall(IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task StreamingCall(grpc::IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
     }
 
     /// <summary>Client for BenchmarkService</summary>
-    public partial class BenchmarkServiceClient : ClientBase<BenchmarkServiceClient>
+    public partial class BenchmarkServiceClient : grpc::ClientBase<BenchmarkServiceClient>
     {
       /// <summary>Creates a new client for BenchmarkService</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
-      public BenchmarkServiceClient(Channel channel) : base(channel)
+      public BenchmarkServiceClient(grpc::Channel channel) : base(channel)
       {
       }
       /// <summary>Creates a new client for BenchmarkService that uses a custom <c>CallInvoker</c>.</summary>
       /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
-      public BenchmarkServiceClient(CallInvoker callInvoker) : base(callInvoker)
+      public BenchmarkServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
       {
       }
       /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
@@ -129,9 +129,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return UnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
+        return UnaryCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// One request followed by one response.
@@ -140,7 +140,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+      public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
       }
@@ -153,9 +153,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return UnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
+        return UnaryCallAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// One request followed by one response.
@@ -164,7 +164,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
       }
@@ -176,9 +176,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return StreamingCall(new CallOptions(headers, deadline, cancellationToken));
+        return StreamingCall(new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// One request followed by one response.
@@ -186,7 +186,7 @@ namespace Grpc.Testing {
       /// </summary>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(CallOptions options)
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(grpc::CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingCall, null, options);
       }
@@ -199,9 +199,9 @@ namespace Grpc.Testing {
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
-    public static ServerServiceDefinition BindService(BenchmarkServiceBase serviceImpl)
+    public static grpc::ServerServiceDefinition BindService(BenchmarkServiceBase serviceImpl)
     {
-      return ServerServiceDefinition.CreateBuilder()
+      return grpc::ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
           .AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall).Build();
     }
@@ -211,37 +211,37 @@ namespace Grpc.Testing {
   {
     static readonly string __ServiceName = "grpc.testing.WorkerService";
 
-    static readonly Marshaller<global::Grpc.Testing.ServerArgs> __Marshaller_ServerArgs = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerArgs.Parser.ParseFrom);
-    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 grpc::Marshaller<global::Grpc.Testing.ServerArgs> __Marshaller_ServerArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerArgs.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.ServerStatus> __Marshaller_ServerStatus = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerStatus.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.ClientArgs> __Marshaller_ClientArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientArgs.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.ClientStatus> __Marshaller_ClientStatus = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientStatus.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.CoreRequest> __Marshaller_CoreRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.CoreRequest.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.CoreResponse> __Marshaller_CoreResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.CoreResponse.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.Void> __Marshaller_Void = grpc::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,
+    static readonly grpc::Method<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> __Method_RunServer = new grpc::Method<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus>(
+        grpc::MethodType.DuplexStreaming,
         __ServiceName,
         "RunServer",
         __Marshaller_ServerArgs,
         __Marshaller_ServerStatus);
 
-    static readonly Method<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> __Method_RunClient = new Method<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus>(
-        MethodType.DuplexStreaming,
+    static readonly grpc::Method<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> __Method_RunClient = new grpc::Method<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus>(
+        grpc::MethodType.DuplexStreaming,
         __ServiceName,
         "RunClient",
         __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,
+    static readonly grpc::Method<global::Grpc.Testing.CoreRequest, global::Grpc.Testing.CoreResponse> __Method_CoreCount = new grpc::Method<global::Grpc.Testing.CoreRequest, global::Grpc.Testing.CoreResponse>(
+        grpc::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,
+    static readonly grpc::Method<global::Grpc.Testing.Void, global::Grpc.Testing.Void> __Method_QuitWorker = new grpc::Method<global::Grpc.Testing.Void, global::Grpc.Testing.Void>(
+        grpc::MethodType.Unary,
         __ServiceName,
         "QuitWorker",
         __Marshaller_Void,
@@ -268,9 +268,9 @@ namespace Grpc.Testing {
       /// <param name="responseStream">Used for sending responses back to the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>A task indicating completion of the handler.</returns>
-      public virtual global::System.Threading.Tasks.Task RunServer(IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task RunServer(grpc::IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
@@ -285,9 +285,9 @@ namespace Grpc.Testing {
       /// <param name="responseStream">Used for sending responses back to the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>A task indicating completion of the handler.</returns>
-      public virtual global::System.Threading.Tasks.Task RunClient(IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task RunClient(grpc::IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
@@ -296,9 +296,9 @@ namespace Grpc.Testing {
       /// <param name="request">The request received from the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
@@ -307,24 +307,24 @@ namespace Grpc.Testing {
       /// <param name="request">The request received from the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
     }
 
     /// <summary>Client for WorkerService</summary>
-    public partial class WorkerServiceClient : ClientBase<WorkerServiceClient>
+    public partial class WorkerServiceClient : grpc::ClientBase<WorkerServiceClient>
     {
       /// <summary>Creates a new client for WorkerService</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
-      public WorkerServiceClient(Channel channel) : base(channel)
+      public WorkerServiceClient(grpc::Channel channel) : base(channel)
       {
       }
       /// <summary>Creates a new client for WorkerService that uses a custom <c>CallInvoker</c>.</summary>
       /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
-      public WorkerServiceClient(CallInvoker callInvoker) : base(callInvoker)
+      public WorkerServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
       {
       }
       /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
@@ -349,9 +349,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return RunServer(new CallOptions(headers, deadline, cancellationToken));
+        return RunServer(new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// Start server with specified workload.
@@ -363,7 +363,7 @@ namespace Grpc.Testing {
       /// </summary>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(CallOptions options)
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(grpc::CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_RunServer, null, options);
       }
@@ -379,9 +379,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return RunClient(new CallOptions(headers, deadline, cancellationToken));
+        return RunClient(new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// Start client with specified workload.
@@ -393,7 +393,7 @@ namespace Grpc.Testing {
       /// </summary>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(CallOptions options)
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(grpc::CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_RunClient, null, options);
       }
@@ -405,9 +405,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return CoreCount(request, new CallOptions(headers, deadline, cancellationToken));
+        return CoreCount(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// Just return the core count - unary call
@@ -415,7 +415,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, CallOptions options)
+      public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, grpc::CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_CoreCount, null, options, request);
       }
@@ -427,9 +427,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return CoreCountAsync(request, new CallOptions(headers, deadline, cancellationToken));
+        return CoreCountAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// Just return the core count - unary call
@@ -437,7 +437,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, CallOptions options)
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_CoreCount, null, options, request);
       }
@@ -449,9 +449,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return QuitWorker(request, new CallOptions(headers, deadline, cancellationToken));
+        return QuitWorker(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// Quit this worker
@@ -459,7 +459,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, CallOptions options)
+      public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, grpc::CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_QuitWorker, null, options, request);
       }
@@ -471,9 +471,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return QuitWorkerAsync(request, new CallOptions(headers, deadline, cancellationToken));
+        return QuitWorkerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// Quit this worker
@@ -481,7 +481,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, CallOptions options)
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_QuitWorker, null, options, request);
       }
@@ -494,9 +494,9 @@ namespace Grpc.Testing {
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
-    public static ServerServiceDefinition BindService(WorkerServiceBase serviceImpl)
+    public static grpc::ServerServiceDefinition BindService(WorkerServiceBase serviceImpl)
     {
-      return ServerServiceDefinition.CreateBuilder()
+      return grpc::ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_RunServer, serviceImpl.RunServer)
           .AddMethod(__Method_RunClient, serviceImpl.RunClient)
           .AddMethod(__Method_CoreCount, serviceImpl.CoreCount)
diff --git a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
index f85e272711f96dd8e6b921b149bf0cfc7fbdc5c2..48ecc2344fcd511e9e4126d00306881d8e2a2574 100644
--- a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
@@ -37,6 +37,7 @@ using System.IO;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
+using Google.Protobuf;
 using Grpc.Core;
 using Grpc.Core.Utils;
 using Grpc.Testing;
@@ -66,9 +67,10 @@ namespace Grpc.IntegrationTesting
             var serverCredentials = new SslServerCredentials(new[] { keyCertPair }, rootCert, true);
             var clientCredentials = new SslCredentials(rootCert, keyCertPair);
 
-            server = new Server
+            // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755
+            server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
             {
-                Services = { TestService.BindService(new TestServiceImpl()) },
+                Services = { TestService.BindService(new SslCredentialsTestServiceImpl()) },
                 Ports = { { Host, ServerPort.PickUnused, serverCredentials } }
             };
             server.Start();
@@ -95,5 +97,40 @@ namespace Grpc.IntegrationTesting
             var response = client.UnaryCall(new SimpleRequest { ResponseSize = 10 });
             Assert.AreEqual(10, response.Payload.Body.Length);
         }
+
+        [Test]
+        public async Task AuthContextIsPopulated()
+        {
+            var call = client.StreamingInputCall();
+            await call.RequestStream.CompleteAsync();
+            var response = await call.ResponseAsync;
+            Assert.AreEqual(12345, response.AggregatedPayloadSize);
+        }
+
+        private class SslCredentialsTestServiceImpl : TestService.TestServiceBase
+        {
+            public override async Task<SimpleResponse> UnaryCall(SimpleRequest request, ServerCallContext context)
+            {
+                return new SimpleResponse { Payload = CreateZerosPayload(request.ResponseSize) };
+            }
+
+            public override async Task<StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<StreamingInputCallRequest> requestStream, ServerCallContext context)
+            {
+                var authContext = context.AuthContext;
+                await requestStream.ForEachAsync(async request => {});
+
+                Assert.IsTrue(authContext.IsPeerAuthenticated);
+                Assert.AreEqual("x509_subject_alternative_name", authContext.PeerIdentityPropertyName);
+                Assert.IsTrue(authContext.PeerIdentity.Count() > 0);
+                Assert.AreEqual("ssl", authContext.FindPropertiesByName("transport_security_type").First().Value);
+
+                return new StreamingInputCallResponse { AggregatedPayloadSize = 12345 };
+            }
+
+            private static Payload CreateZerosPayload(int size)
+            {
+                return new Payload { Body = ByteString.CopyFrom(new byte[size]) };
+            }
+        }
     }
 }
diff --git a/src/csharp/Grpc.IntegrationTesting/Stats.cs b/src/csharp/Grpc.IntegrationTesting/Stats.cs
index 504aa11d8a7729e112a08bb3c557f69af9dd9b78..79ff220436adb3fb3b7e67c2e7c683075743ed92 100644
--- a/src/csharp/Grpc.IntegrationTesting/Stats.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Stats.cs
@@ -90,7 +90,7 @@ namespace Grpc.Testing {
     public const int TimeElapsedFieldNumber = 1;
     private double timeElapsed_;
     /// <summary>
-    ///  wall clock time change in seconds since last reset
+    /// wall clock time change in seconds since last reset
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double TimeElapsed {
@@ -104,7 +104,7 @@ namespace Grpc.Testing {
     public const int TimeUserFieldNumber = 2;
     private double timeUser_;
     /// <summary>
-    ///  change in user time (in seconds) used by the server since last reset
+    /// change in user time (in seconds) used by the server since last reset
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double TimeUser {
@@ -118,8 +118,8 @@ namespace Grpc.Testing {
     public const int TimeSystemFieldNumber = 3;
     private double timeSystem_;
     /// <summary>
-    ///  change in server time (in seconds) used by the server process and all
-    ///  threads since last reset
+    /// change in server time (in seconds) used by the server process and all
+    /// threads since last reset
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double TimeSystem {
@@ -133,7 +133,7 @@ namespace Grpc.Testing {
     public const int TotalCpuTimeFieldNumber = 4;
     private ulong totalCpuTime_;
     /// <summary>
-    ///  change in total cpu time of the server (data from proc/stat)
+    /// change in total cpu time of the server (data from proc/stat)
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ulong TotalCpuTime {
@@ -147,7 +147,7 @@ namespace Grpc.Testing {
     public const int IdleCpuTimeFieldNumber = 5;
     private ulong idleCpuTime_;
     /// <summary>
-    ///  change in idle time of the server (data from proc/stat)
+    /// change in idle time of the server (data from proc/stat)
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ulong IdleCpuTime {
@@ -296,7 +296,7 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  Histogram params based on grpc/support/histogram.c
+  /// Histogram params based on grpc/support/histogram.c
   /// </summary>
   public sealed partial class HistogramParams : pb::IMessage<HistogramParams> {
     private static readonly pb::MessageParser<HistogramParams> _parser = new pb::MessageParser<HistogramParams>(() => new HistogramParams());
@@ -335,7 +335,7 @@ namespace Grpc.Testing {
     public const int ResolutionFieldNumber = 1;
     private double resolution_;
     /// <summary>
-    ///  first bucket is [0, 1 + resolution)
+    /// first bucket is [0, 1 + resolution)
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double Resolution {
@@ -349,7 +349,7 @@ namespace Grpc.Testing {
     public const int MaxPossibleFieldNumber = 2;
     private double maxPossible_;
     /// <summary>
-    ///  use enough buckets to allow this value
+    /// use enough buckets to allow this value
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double MaxPossible {
@@ -450,7 +450,7 @@ namespace Grpc.Testing {
   }
 
   /// <summary>
-  ///  Histogram data based on grpc/support/histogram.c
+  /// Histogram data based on grpc/support/histogram.c
   /// </summary>
   public sealed partial class HistogramData : pb::IMessage<HistogramData> {
     private static readonly pb::MessageParser<HistogramData> _parser = new pb::MessageParser<HistogramData>(() => new HistogramData());
@@ -887,7 +887,7 @@ namespace Grpc.Testing {
     public const int LatenciesFieldNumber = 1;
     private global::Grpc.Testing.HistogramData latencies_;
     /// <summary>
-    ///  Latency histogram. Data points are in nanoseconds.
+    /// Latency histogram. Data points are in nanoseconds.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.HistogramData Latencies {
@@ -901,7 +901,7 @@ namespace Grpc.Testing {
     public const int TimeElapsedFieldNumber = 2;
     private double timeElapsed_;
     /// <summary>
-    ///  See ServerStats for details.
+    /// See ServerStats for details.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double TimeElapsed {
@@ -939,7 +939,7 @@ namespace Grpc.Testing {
         = pb::FieldCodec.ForMessage(42, global::Grpc.Testing.RequestResultCount.Parser);
     private readonly pbc::RepeatedField<global::Grpc.Testing.RequestResultCount> requestResults_ = new pbc::RepeatedField<global::Grpc.Testing.RequestResultCount>();
     /// <summary>
-    ///  Number of failed requests (one row per status code seen)
+    /// Number of failed requests (one row per status code seen)
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<global::Grpc.Testing.RequestResultCount> RequestResults {
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index 0265f8e821ebe93fb62351562b26b21eaa55919d..77f76ebbe9cb89acaa10637c7fbac2dbd0f5c3a8 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -38,7 +38,7 @@
 using System;
 using System.Threading;
 using System.Threading.Tasks;
-using Grpc.Core;
+using grpc = global::Grpc.Core;
 
 namespace Grpc.Testing {
   /// <summary>
@@ -49,65 +49,65 @@ namespace Grpc.Testing {
   {
     static readonly string __ServiceName = "grpc.testing.TestService";
 
-    static readonly Marshaller<global::Grpc.Testing.Empty> __Marshaller_Empty = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Empty.Parser.ParseFrom);
-    static readonly Marshaller<global::Grpc.Testing.SimpleRequest> __Marshaller_SimpleRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleRequest.Parser.ParseFrom);
-    static readonly Marshaller<global::Grpc.Testing.SimpleResponse> __Marshaller_SimpleResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleResponse.Parser.ParseFrom);
-    static readonly Marshaller<global::Grpc.Testing.StreamingOutputCallRequest> __Marshaller_StreamingOutputCallRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingOutputCallRequest.Parser.ParseFrom);
-    static readonly Marshaller<global::Grpc.Testing.StreamingOutputCallResponse> __Marshaller_StreamingOutputCallResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingOutputCallResponse.Parser.ParseFrom);
-    static readonly Marshaller<global::Grpc.Testing.StreamingInputCallRequest> __Marshaller_StreamingInputCallRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingInputCallRequest.Parser.ParseFrom);
-    static readonly Marshaller<global::Grpc.Testing.StreamingInputCallResponse> __Marshaller_StreamingInputCallResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingInputCallResponse.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.Empty> __Marshaller_Empty = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Empty.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.SimpleRequest> __Marshaller_SimpleRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleRequest.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.SimpleResponse> __Marshaller_SimpleResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleResponse.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.StreamingOutputCallRequest> __Marshaller_StreamingOutputCallRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingOutputCallRequest.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.StreamingOutputCallResponse> __Marshaller_StreamingOutputCallResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingOutputCallResponse.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.StreamingInputCallRequest> __Marshaller_StreamingInputCallRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingInputCallRequest.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.StreamingInputCallResponse> __Marshaller_StreamingInputCallResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingInputCallResponse.Parser.ParseFrom);
 
-    static readonly Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty> __Method_EmptyCall = new Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty>(
-        MethodType.Unary,
+    static readonly grpc::Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty> __Method_EmptyCall = new grpc::Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty>(
+        grpc::MethodType.Unary,
         __ServiceName,
         "EmptyCall",
         __Marshaller_Empty,
         __Marshaller_Empty);
 
-    static readonly Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_UnaryCall = new Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
-        MethodType.Unary,
+    static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_UnaryCall = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+        grpc::MethodType.Unary,
         __ServiceName,
         "UnaryCall",
         __Marshaller_SimpleRequest,
         __Marshaller_SimpleResponse);
 
-    static readonly Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_CacheableUnaryCall = new Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
-        MethodType.Unary,
+    static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_CacheableUnaryCall = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+        grpc::MethodType.Unary,
         __ServiceName,
         "CacheableUnaryCall",
         __Marshaller_SimpleRequest,
         __Marshaller_SimpleResponse);
 
-    static readonly Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> __Method_StreamingOutputCall = new Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse>(
-        MethodType.ServerStreaming,
+    static readonly grpc::Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> __Method_StreamingOutputCall = new grpc::Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse>(
+        grpc::MethodType.ServerStreaming,
         __ServiceName,
         "StreamingOutputCall",
         __Marshaller_StreamingOutputCallRequest,
         __Marshaller_StreamingOutputCallResponse);
 
-    static readonly Method<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> __Method_StreamingInputCall = new Method<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse>(
-        MethodType.ClientStreaming,
+    static readonly grpc::Method<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> __Method_StreamingInputCall = new grpc::Method<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse>(
+        grpc::MethodType.ClientStreaming,
         __ServiceName,
         "StreamingInputCall",
         __Marshaller_StreamingInputCallRequest,
         __Marshaller_StreamingInputCallResponse);
 
-    static readonly Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> __Method_FullDuplexCall = new Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse>(
-        MethodType.DuplexStreaming,
+    static readonly grpc::Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> __Method_FullDuplexCall = new grpc::Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse>(
+        grpc::MethodType.DuplexStreaming,
         __ServiceName,
         "FullDuplexCall",
         __Marshaller_StreamingOutputCallRequest,
         __Marshaller_StreamingOutputCallResponse);
 
-    static readonly Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> __Method_HalfDuplexCall = new Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse>(
-        MethodType.DuplexStreaming,
+    static readonly grpc::Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> __Method_HalfDuplexCall = new grpc::Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse>(
+        grpc::MethodType.DuplexStreaming,
         __ServiceName,
         "HalfDuplexCall",
         __Marshaller_StreamingOutputCallRequest,
         __Marshaller_StreamingOutputCallResponse);
 
-    static readonly Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty> __Method_UnimplementedCall = new Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty>(
-        MethodType.Unary,
+    static readonly grpc::Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty> __Method_UnimplementedCall = new grpc::Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty>(
+        grpc::MethodType.Unary,
         __ServiceName,
         "UnimplementedCall",
         __Marshaller_Empty,
@@ -128,9 +128,9 @@ namespace Grpc.Testing {
       /// <param name="request">The request received from the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> EmptyCall(global::Grpc.Testing.Empty request, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> EmptyCall(global::Grpc.Testing.Empty request, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
@@ -139,9 +139,9 @@ namespace Grpc.Testing {
       /// <param name="request">The request received from the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
@@ -152,9 +152,9 @@ namespace Grpc.Testing {
       /// <param name="request">The request received from the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
@@ -165,9 +165,9 @@ namespace Grpc.Testing {
       /// <param name="responseStream">Used for sending responses back to the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>A task indicating completion of the handler.</returns>
-      public virtual global::System.Threading.Tasks.Task StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, grpc::IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
@@ -177,9 +177,9 @@ namespace Grpc.Testing {
       /// <param name="requestStream">Used for reading requests from the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<global::Grpc.Testing.StreamingInputCallRequest> requestStream, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(grpc::IAsyncStreamReader<global::Grpc.Testing.StreamingInputCallRequest> requestStream, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
@@ -191,9 +191,9 @@ namespace Grpc.Testing {
       /// <param name="responseStream">Used for sending responses back to the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>A task indicating completion of the handler.</returns>
-      public virtual global::System.Threading.Tasks.Task FullDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task FullDuplexCall(grpc::IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
@@ -206,9 +206,9 @@ namespace Grpc.Testing {
       /// <param name="responseStream">Used for sending responses back to the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>A task indicating completion of the handler.</returns>
-      public virtual global::System.Threading.Tasks.Task HalfDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task HalfDuplexCall(grpc::IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
       /// <summary>
@@ -218,24 +218,24 @@ namespace Grpc.Testing {
       /// <param name="request">The request received from the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
     }
 
     /// <summary>Client for TestService</summary>
-    public partial class TestServiceClient : ClientBase<TestServiceClient>
+    public partial class TestServiceClient : grpc::ClientBase<TestServiceClient>
     {
       /// <summary>Creates a new client for TestService</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
-      public TestServiceClient(Channel channel) : base(channel)
+      public TestServiceClient(grpc::Channel channel) : base(channel)
       {
       }
       /// <summary>Creates a new client for TestService that uses a custom <c>CallInvoker</c>.</summary>
       /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
-      public TestServiceClient(CallInvoker callInvoker) : base(callInvoker)
+      public TestServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
       {
       }
       /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
@@ -256,9 +256,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return EmptyCall(request, new CallOptions(headers, deadline, cancellationToken));
+        return EmptyCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// One empty request followed by one empty response.
@@ -266,7 +266,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, CallOptions options)
+      public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, grpc::CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_EmptyCall, null, options, request);
       }
@@ -278,9 +278,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return EmptyCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
+        return EmptyCallAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// One empty request followed by one empty response.
@@ -288,7 +288,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_EmptyCall, null, options, request);
       }
@@ -300,9 +300,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return UnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
+        return UnaryCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// One request followed by one response.
@@ -310,7 +310,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+      public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
       }
@@ -322,9 +322,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return UnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
+        return UnaryCallAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// One request followed by one response.
@@ -332,7 +332,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
       }
@@ -346,9 +346,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.SimpleResponse CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.SimpleResponse CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return CacheableUnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
+        return CacheableUnaryCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// One request followed by one response. Response has cache control
@@ -358,7 +358,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.SimpleResponse CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+      public virtual global::Grpc.Testing.SimpleResponse CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_CacheableUnaryCall, null, options, request);
       }
@@ -372,9 +372,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> CacheableUnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> CacheableUnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return CacheableUnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
+        return CacheableUnaryCallAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// One request followed by one response. Response has cache control
@@ -384,7 +384,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> CacheableUnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> CacheableUnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_CacheableUnaryCall, null, options, request);
       }
@@ -397,9 +397,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return StreamingOutputCall(request, new CallOptions(headers, deadline, cancellationToken));
+        return StreamingOutputCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// One request followed by a sequence of responses (streamed download).
@@ -408,7 +408,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, CallOptions options)
+      public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncServerStreamingCall(__Method_StreamingOutputCall, null, options, request);
       }
@@ -420,9 +420,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return StreamingInputCall(new CallOptions(headers, deadline, cancellationToken));
+        return StreamingInputCall(new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// A sequence of requests followed by one response (streamed upload).
@@ -430,7 +430,7 @@ namespace Grpc.Testing {
       /// </summary>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(CallOptions options)
+      public virtual grpc::AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(grpc::CallOptions options)
       {
         return CallInvoker.AsyncClientStreamingCall(__Method_StreamingInputCall, null, options);
       }
@@ -443,9 +443,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return FullDuplexCall(new CallOptions(headers, deadline, cancellationToken));
+        return FullDuplexCall(new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// A sequence of requests with each request served by the server immediately.
@@ -454,7 +454,7 @@ namespace Grpc.Testing {
       /// </summary>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(CallOptions options)
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(grpc::CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_FullDuplexCall, null, options);
       }
@@ -468,9 +468,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return HalfDuplexCall(new CallOptions(headers, deadline, cancellationToken));
+        return HalfDuplexCall(new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// A sequence of requests followed by a sequence of responses.
@@ -480,7 +480,7 @@ namespace Grpc.Testing {
       /// </summary>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options)
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(grpc::CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_HalfDuplexCall, null, options);
       }
@@ -493,9 +493,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return UnimplementedCall(request, new CallOptions(headers, deadline, cancellationToken));
+        return UnimplementedCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// The test server will not implement this method. It will be used
@@ -504,7 +504,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, CallOptions options)
+      public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, grpc::CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_UnimplementedCall, null, options, request);
       }
@@ -517,9 +517,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return UnimplementedCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
+        return UnimplementedCallAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// The test server will not implement this method. It will be used
@@ -528,7 +528,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_UnimplementedCall, null, options, request);
       }
@@ -541,9 +541,9 @@ namespace Grpc.Testing {
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
-    public static ServerServiceDefinition BindService(TestServiceBase serviceImpl)
+    public static grpc::ServerServiceDefinition BindService(TestServiceBase serviceImpl)
     {
-      return ServerServiceDefinition.CreateBuilder()
+      return grpc::ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_EmptyCall, serviceImpl.EmptyCall)
           .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
           .AddMethod(__Method_CacheableUnaryCall, serviceImpl.CacheableUnaryCall)
@@ -563,10 +563,10 @@ namespace Grpc.Testing {
   {
     static readonly string __ServiceName = "grpc.testing.UnimplementedService";
 
-    static readonly Marshaller<global::Grpc.Testing.Empty> __Marshaller_Empty = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Empty.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.Empty> __Marshaller_Empty = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Empty.Parser.ParseFrom);
 
-    static readonly Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty> __Method_UnimplementedCall = new Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty>(
-        MethodType.Unary,
+    static readonly grpc::Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty> __Method_UnimplementedCall = new grpc::Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty>(
+        grpc::MethodType.Unary,
         __ServiceName,
         "UnimplementedCall",
         __Marshaller_Empty,
@@ -587,24 +587,24 @@ namespace Grpc.Testing {
       /// <param name="request">The request received from the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
     }
 
     /// <summary>Client for UnimplementedService</summary>
-    public partial class UnimplementedServiceClient : ClientBase<UnimplementedServiceClient>
+    public partial class UnimplementedServiceClient : grpc::ClientBase<UnimplementedServiceClient>
     {
       /// <summary>Creates a new client for UnimplementedService</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
-      public UnimplementedServiceClient(Channel channel) : base(channel)
+      public UnimplementedServiceClient(grpc::Channel channel) : base(channel)
       {
       }
       /// <summary>Creates a new client for UnimplementedService that uses a custom <c>CallInvoker</c>.</summary>
       /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
-      public UnimplementedServiceClient(CallInvoker callInvoker) : base(callInvoker)
+      public UnimplementedServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
       {
       }
       /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
@@ -625,9 +625,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return UnimplementedCall(request, new CallOptions(headers, deadline, cancellationToken));
+        return UnimplementedCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// A call that no server should implement
@@ -635,7 +635,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, CallOptions options)
+      public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, grpc::CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_UnimplementedCall, null, options, request);
       }
@@ -647,9 +647,9 @@ namespace Grpc.Testing {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return UnimplementedCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
+        return UnimplementedCallAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// A call that no server should implement
@@ -657,7 +657,7 @@ namespace Grpc.Testing {
       /// <param name="request">The request to send to the server.</param>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_UnimplementedCall, null, options, request);
       }
@@ -670,9 +670,9 @@ namespace Grpc.Testing {
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
-    public static ServerServiceDefinition BindService(UnimplementedServiceBase serviceImpl)
+    public static grpc::ServerServiceDefinition BindService(UnimplementedServiceBase serviceImpl)
     {
-      return ServerServiceDefinition.CreateBuilder()
+      return grpc::ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build();
     }
 
@@ -684,19 +684,19 @@ namespace Grpc.Testing {
   {
     static readonly string __ServiceName = "grpc.testing.ReconnectService";
 
-    static readonly Marshaller<global::Grpc.Testing.ReconnectParams> __Marshaller_ReconnectParams = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ReconnectParams.Parser.ParseFrom);
-    static readonly Marshaller<global::Grpc.Testing.Empty> __Marshaller_Empty = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Empty.Parser.ParseFrom);
-    static readonly Marshaller<global::Grpc.Testing.ReconnectInfo> __Marshaller_ReconnectInfo = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ReconnectInfo.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.ReconnectParams> __Marshaller_ReconnectParams = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ReconnectParams.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.Empty> __Marshaller_Empty = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Empty.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.ReconnectInfo> __Marshaller_ReconnectInfo = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ReconnectInfo.Parser.ParseFrom);
 
-    static readonly Method<global::Grpc.Testing.ReconnectParams, global::Grpc.Testing.Empty> __Method_Start = new Method<global::Grpc.Testing.ReconnectParams, global::Grpc.Testing.Empty>(
-        MethodType.Unary,
+    static readonly grpc::Method<global::Grpc.Testing.ReconnectParams, global::Grpc.Testing.Empty> __Method_Start = new grpc::Method<global::Grpc.Testing.ReconnectParams, global::Grpc.Testing.Empty>(
+        grpc::MethodType.Unary,
         __ServiceName,
         "Start",
         __Marshaller_ReconnectParams,
         __Marshaller_Empty);
 
-    static readonly Method<global::Grpc.Testing.Empty, global::Grpc.Testing.ReconnectInfo> __Method_Stop = new Method<global::Grpc.Testing.Empty, global::Grpc.Testing.ReconnectInfo>(
-        MethodType.Unary,
+    static readonly grpc::Method<global::Grpc.Testing.Empty, global::Grpc.Testing.ReconnectInfo> __Method_Stop = new grpc::Method<global::Grpc.Testing.Empty, global::Grpc.Testing.ReconnectInfo>(
+        grpc::MethodType.Unary,
         __ServiceName,
         "Stop",
         __Marshaller_Empty,
@@ -711,29 +711,29 @@ namespace Grpc.Testing {
     /// <summary>Base class for server-side implementations of ReconnectService</summary>
     public abstract partial class ReconnectServiceBase
     {
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.ReconnectParams request, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.ReconnectParams request, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.ReconnectInfo> Stop(global::Grpc.Testing.Empty request, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.ReconnectInfo> Stop(global::Grpc.Testing.Empty request, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
     }
 
     /// <summary>Client for ReconnectService</summary>
-    public partial class ReconnectServiceClient : ClientBase<ReconnectServiceClient>
+    public partial class ReconnectServiceClient : grpc::ClientBase<ReconnectServiceClient>
     {
       /// <summary>Creates a new client for ReconnectService</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
-      public ReconnectServiceClient(Channel channel) : base(channel)
+      public ReconnectServiceClient(grpc::Channel channel) : base(channel)
       {
       }
       /// <summary>Creates a new client for ReconnectService that uses a custom <c>CallInvoker</c>.</summary>
       /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
-      public ReconnectServiceClient(CallInvoker callInvoker) : base(callInvoker)
+      public ReconnectServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
       {
       }
       /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
@@ -746,35 +746,35 @@ namespace Grpc.Testing {
       {
       }
 
-      public virtual global::Grpc.Testing.Empty Start(global::Grpc.Testing.ReconnectParams request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.Empty Start(global::Grpc.Testing.ReconnectParams request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return Start(request, new CallOptions(headers, deadline, cancellationToken));
+        return Start(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
-      public virtual global::Grpc.Testing.Empty Start(global::Grpc.Testing.ReconnectParams request, CallOptions options)
+      public virtual global::Grpc.Testing.Empty Start(global::Grpc.Testing.ReconnectParams request, grpc::CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_Start, null, options, request);
       }
-      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.ReconnectParams request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.ReconnectParams request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return StartAsync(request, new CallOptions(headers, deadline, cancellationToken));
+        return StartAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
-      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.ReconnectParams request, CallOptions options)
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.ReconnectParams request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_Start, null, options, request);
       }
-      public virtual global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return Stop(request, new CallOptions(headers, deadline, cancellationToken));
+        return Stop(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
-      public virtual global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, CallOptions options)
+      public virtual global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, grpc::CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_Stop, null, options, request);
       }
-      public virtual AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return StopAsync(request, new CallOptions(headers, deadline, cancellationToken));
+        return StopAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
       }
-      public virtual AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, CallOptions options)
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, grpc::CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_Stop, null, options, request);
       }
@@ -787,9 +787,9 @@ namespace Grpc.Testing {
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
-    public static ServerServiceDefinition BindService(ReconnectServiceBase serviceImpl)
+    public static grpc::ServerServiceDefinition BindService(ReconnectServiceBase serviceImpl)
     {
-      return ServerServiceDefinition.CreateBuilder()
+      return grpc::ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_Start, serviceImpl.Start)
           .AddMethod(__Method_Stop, serviceImpl.Stop).Build();
     }
diff --git a/src/csharp/Grpc.IntegrationTesting/packages.config b/src/csharp/Grpc.IntegrationTesting/packages.config
deleted file mode 100644
index a03ee926f4769e0ab106d3ebd82dc8c41caebaab..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting/packages.config
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
-  <package id="Castle.Core" version="3.3.3" targetFramework="net45" />
-  <package id="CommandLineParser.Unofficial" version="2.0.275" targetFramework="net45" />
-  <package id="Google.Apis" version="1.16.0" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.16.0" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.16.0" targetFramework="net45" />
-  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="log4net" version="2.0.3" targetFramework="net45" />
-  <package id="Moq" version="4.6.38-alpha" targetFramework="net45" />
-  <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
-  <package id="NUnit" version="3.2.0" targetFramework="net45" />
-  <package id="NUnitLite" version="3.2.0" targetFramework="net45" />
-  <package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
-  <package id="Zlib.Portable.Signed" version="1.11.0" targetFramework="net45" />
-</packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting/project.json b/src/csharp/Grpc.IntegrationTesting/project.json
deleted file mode 100644
index eba54318a5beb4f632bed1c5fa5140fd0b98a77b..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.IntegrationTesting/project.json
+++ /dev/null
@@ -1,83 +0,0 @@
-{
-  "buildOptions": {
-    "emitEntryPoint": true
-  },
-  "configurations": {
-    "Debug": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
-            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
-            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    },
-    "Release": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
-            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
-            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    }
-  },
-
-  "dependencies": {
-    "Grpc.Auth": {
-      "target": "project"
-    },
-    "Grpc.Core": {
-      "target": "project"
-    },
-    "Google.Protobuf": "3.0.0",
-    "CommandLineParser.Unofficial": "2.0.275",
-    "Moq": "4.6.38-alpha",
-    "NUnit": "3.2.0",
-    "NUnitLite": "3.2.0-*"
-  },
-  "frameworks": {
-    "net45": {
-      "frameworkAssemblies": {
-        "System.Runtime": "",
-        "System.IO": ""
-      }
-    },
-    "netcoreapp1.0": {
-      "imports": [
-        "portable-net45"
-      ],
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.0"
-        },
-        "System.Linq.Expressions": "4.1.0"
-      }
-    }
-  }
-}
diff --git a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj
old mode 100644
new mode 100755
index c5918b194ef78b82784f08b4ef8648aedefb5dff..af6ade852b2ddb4792c5aaba4d69a2323d92c6e8
--- a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj
+++ b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj
@@ -1,85 +1,33 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+  <Import Project="..\Grpc.Core\Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{B88F91D6-436D-4C78-8B99-47800FA8DE03}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Grpc.Reflection.Tests</RootNamespace>
+    <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
     <AssemblyName>Grpc.Reflection.Tests</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+    <OutputType>Exe</OutputType>
+    <PackageId>Grpc.Reflection.Tests</PackageId>
+    <PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
+    <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-    <Reference Include="nunit.framework">
-      <HintPath>..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll</HintPath>
-    </Reference>
-    <Reference Include="nunitlite">
-      <HintPath>..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Protobuf">
-      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
-    </Reference>
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
-    </Reference>
+    <ProjectReference Include="../Grpc.Reflection/Grpc.Reflection.csproj" />
   </ItemGroup>
+
   <ItemGroup>
-    <Compile Include="..\Grpc.Core\Version.cs">
-      <Link>Version.cs</Link>
-    </Compile>
-    <Compile Include="SymbolRegistryTest.cs" />
-    <Compile Include="ReflectionClientServerTest.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="NUnitMain.cs" />
+    <PackageReference Include="NUnit" Version="3.6.0" />
+    <PackageReference Include="NUnitLite" Version="3.6.0" />
   </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
-      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
-      <Name>Grpc.Core</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Grpc.Reflection\Grpc.Reflection.csproj">
-      <Project>{4F18CF52-B3DB-4A77-97C5-7F7F4B6C1715}</Project>
-      <Name>Grpc.Reflection</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="Grpc.Reflection.Tests.project.json" />
-    <None Include="packages.config" />
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
+
   <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+    <Compile Include="..\Grpc.Core\Version.cs" />
   </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.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">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
\ No newline at end of file
+
+</Project>
diff --git a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.project.json b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.xproj b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.xproj
deleted file mode 100644
index 4a3100853d15ec7f270a726f49f12daf7a4f69f9..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>fe90181d-a4b3-4a5c-8490-f07561e18e3b</ProjectGuid>
-    <RootNamespace>Grpc.Reflection.Tests</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Reflection.Tests/ReflectionClientServerTest.cs b/src/csharp/Grpc.Reflection.Tests/ReflectionClientServerTest.cs
index 1d0845e276cd141516ce485afb3e025a2db5a6c7..22edbed04027f2152c71bb3640199a974280055e 100644
--- a/src/csharp/Grpc.Reflection.Tests/ReflectionClientServerTest.cs
+++ b/src/csharp/Grpc.Reflection.Tests/ReflectionClientServerTest.cs
@@ -58,7 +58,8 @@ namespace Grpc.Reflection.Tests
         {
             serviceImpl = new ReflectionServiceImpl(ServerReflection.Descriptor);
 
-            server = new Server
+            // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755
+            server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
             {
                 Services = { ServerReflection.BindService(serviceImpl) },
                 Ports = { { Host, ServerPort.PickUnused, ServerCredentials.Insecure } }
diff --git a/src/csharp/Grpc.Reflection.Tests/packages.config b/src/csharp/Grpc.Reflection.Tests/packages.config
deleted file mode 100644
index 0fed4dbd415340511d18512507e9925e704c8879..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Reflection.Tests/packages.config
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="NUnit" version="3.2.0" targetFramework="net45" />
-  <package id="NUnitLite" version="3.2.0" targetFramework="net45" />
-  <package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
-</packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Reflection.Tests/project.json b/src/csharp/Grpc.Reflection.Tests/project.json
deleted file mode 100644
index b90834a25eb255d7699577d4116c4bca6233f670..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Reflection.Tests/project.json
+++ /dev/null
@@ -1,65 +0,0 @@
-{
-  "buildOptions": {
-    "emitEntryPoint": true
-  },
-  "configurations": {
-    "Debug": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    },
-    "Release": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    }
-  },
-
-  "dependencies": {
-    "Grpc.Reflection": {
-      "target": "project"
-    },
-    "NUnit": "3.2.0",
-    "NUnitLite": "3.2.0-*"
-  },
-  "frameworks": {
-    "net45": { },
-    "netcoreapp1.0": {
-      "imports": [
-        "portable-net45"
-      ],
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.0"
-        }
-      }
-    }
-  }
-}
diff --git a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj
old mode 100644
new mode 100755
index 4e254a0b5397b15ddeb51ee8979476d4d6a9d131..70bfcc89c5cd633b0ee0f48f31e381f61a460d01
--- a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj
+++ b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj
@@ -1,74 +1,37 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+  <Import Project="..\Grpc.Core\Common.csproj.include" />
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{4F18CF52-B3DB-4A77-97C5-7F7F4B6C1715}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Grpc.Reflection</RootNamespace>
+    <Copyright>Copyright 2016, Google Inc.</Copyright>
+    <AssemblyTitle>gRPC C# Reflection</AssemblyTitle>
+    <VersionPrefix>$(GrpcCsharpVersion)</VersionPrefix>
+    <Authors>Google Inc.</Authors>
+    <TargetFrameworks>net45;netstandard1.5</TargetFrameworks>
     <AssemblyName>Grpc.Reflection</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <DocumentationFile>bin\$(Configuration)\Grpc.Reflection.Xml</DocumentationFile>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+    <PackageId>Grpc.Reflection</PackageId>
+    <PackageTags>gRPC reflection</PackageTags>
+    <PackageProjectUrl>https://github.com/grpc/grpc</PackageProjectUrl>
+    <PackageLicenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</PackageLicenseUrl>
+    <NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.5' ">1.6.0</NetStandardImplicitPackageVersion>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-    <Reference Include="Google.Protobuf">
-      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
-    </Reference>
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
-    </Reference>
+    <Compile Include="..\Grpc.Core\Version.cs" />
   </ItemGroup>
+
   <ItemGroup>
-    <Compile Include="..\Grpc.Core\Version.cs">
-      <Link>Version.cs</Link>
-    </Compile>
-    <Compile Include="SymbolRegistry.cs" />
-    <Compile Include="ReflectionServiceImpl.cs" />
-    <Compile Include="Reflection.cs" />
-    <Compile Include="ReflectionGrpc.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
+    <ProjectReference Include="../Grpc.Core/Grpc.Core.csproj" />
   </ItemGroup>
+
   <ItemGroup>
-    <None Include="Grpc.Reflection.project.json" />
-    <None Include="packages.config" />
+    <PackageReference Include="Google.Protobuf" Version="$(GoogleProtobufVersion)" />
   </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
-      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
-      <Name>Grpc.Core</Name>
-    </ProjectReference>
+
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
+    <Reference Include="System" />
+    <Reference Include="Microsoft.CSharp" />
   </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.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">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
\ No newline at end of file
+
+</Project>
diff --git a/src/csharp/Grpc.Reflection/Grpc.Reflection.project.json b/src/csharp/Grpc.Reflection/Grpc.Reflection.project.json
deleted file mode 100644
index c2f5bcb1637badadff8959d672e04c942cb54d51..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Reflection/Grpc.Reflection.project.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "frameworks": {
-    "net45": { }
-  },
-  "runtimes": {
-    "win": { }
-  }
-}
diff --git a/src/csharp/Grpc.Reflection/Grpc.Reflection.xproj b/src/csharp/Grpc.Reflection/Grpc.Reflection.xproj
deleted file mode 100644
index 833d98b12168259b79a1a98cf3ef50a4d027f398..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Reflection/Grpc.Reflection.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>2b372155-80ba-4cf9-82d6-4b938e8ec3a0</ProjectGuid>
-    <RootNamespace>Grpc.Reflection</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Reflection/Reflection.cs b/src/csharp/Grpc.Reflection/Reflection.cs
index 06c5d08030d5448f2d446e7a9cd0105cfd9bc06c..86e9aace8c83e069c34fb50928b85a53a8ae4bd5 100644
--- a/src/csharp/Grpc.Reflection/Reflection.cs
+++ b/src/csharp/Grpc.Reflection/Reflection.cs
@@ -70,7 +70,7 @@ namespace Grpc.Reflection.V1Alpha {
   }
   #region Messages
   /// <summary>
-  ///  The message sent by the client when calling ServerReflectionInfo method.
+  /// The message sent by the client when calling ServerReflectionInfo method.
   /// </summary>
   public sealed partial class ServerReflectionRequest : pb::IMessage<ServerReflectionRequest> {
     private static readonly pb::MessageParser<ServerReflectionRequest> _parser = new pb::MessageParser<ServerReflectionRequest>(() => new ServerReflectionRequest());
@@ -136,7 +136,7 @@ namespace Grpc.Reflection.V1Alpha {
     /// <summary>Field number for the "file_by_filename" field.</summary>
     public const int FileByFilenameFieldNumber = 3;
     /// <summary>
-    ///  Find a proto file by the file name.
+    /// Find a proto file by the file name.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string FileByFilename {
@@ -150,9 +150,9 @@ namespace Grpc.Reflection.V1Alpha {
     /// <summary>Field number for the "file_containing_symbol" field.</summary>
     public const int FileContainingSymbolFieldNumber = 4;
     /// <summary>
-    ///  Find the proto file that declares the given fully-qualified symbol name.
-    ///  This field should be a fully-qualified symbol name
-    ///  (e.g. &lt;package>.&lt;service>[.&lt;method>] or &lt;package>.&lt;type>).
+    /// Find the proto file that declares the given fully-qualified symbol name.
+    /// This field should be a fully-qualified symbol name
+    /// (e.g. &lt;package>.&lt;service>[.&lt;method>] or &lt;package>.&lt;type>).
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string FileContainingSymbol {
@@ -166,8 +166,8 @@ namespace Grpc.Reflection.V1Alpha {
     /// <summary>Field number for the "file_containing_extension" field.</summary>
     public const int FileContainingExtensionFieldNumber = 5;
     /// <summary>
-    ///  Find the proto file which defines an extension extending the given
-    ///  message type with the given field number.
+    /// Find the proto file which defines an extension extending the given
+    /// message type with the given field number.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Reflection.V1Alpha.ExtensionRequest FileContainingExtension {
@@ -181,14 +181,14 @@ namespace Grpc.Reflection.V1Alpha {
     /// <summary>Field number for the "all_extension_numbers_of_type" field.</summary>
     public const int AllExtensionNumbersOfTypeFieldNumber = 6;
     /// <summary>
-    ///  Finds the tag numbers used by all known extensions of the given message
-    ///  type, and appends them to ExtensionNumberResponse in an undefined order.
-    ///  Its corresponding method is best-effort: it's not guaranteed that the
-    ///  reflection service will implement this method, and it's not guaranteed
-    ///  that this method will provide all extensions. Returns
-    ///  StatusCode::UNIMPLEMENTED if it's not implemented.
-    ///  This field should be a fully-qualified type name. The format is
-    ///  &lt;package>.&lt;type>
+    /// Finds the tag numbers used by all known extensions of the given message
+    /// type, and appends them to ExtensionNumberResponse in an undefined order.
+    /// Its corresponding method is best-effort: it's not guaranteed that the
+    /// reflection service will implement this method, and it's not guaranteed
+    /// that this method will provide all extensions. Returns
+    /// StatusCode::UNIMPLEMENTED if it's not implemented.
+    /// This field should be a fully-qualified type name. The format is
+    /// &lt;package>.&lt;type>
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string AllExtensionNumbersOfType {
@@ -202,8 +202,8 @@ namespace Grpc.Reflection.V1Alpha {
     /// <summary>Field number for the "list_services" field.</summary>
     public const int ListServicesFieldNumber = 7;
     /// <summary>
-    ///  List the full names of registered services. The content will not be
-    ///  checked.
+    /// List the full names of registered services. The content will not be
+    /// checked.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string ListServices {
@@ -401,8 +401,8 @@ namespace Grpc.Reflection.V1Alpha {
   }
 
   /// <summary>
-  ///  The type name and extension number sent by the client when requesting
-  ///  file_containing_extension.
+  /// The type name and extension number sent by the client when requesting
+  /// file_containing_extension.
   /// </summary>
   public sealed partial class ExtensionRequest : pb::IMessage<ExtensionRequest> {
     private static readonly pb::MessageParser<ExtensionRequest> _parser = new pb::MessageParser<ExtensionRequest>(() => new ExtensionRequest());
@@ -441,7 +441,7 @@ namespace Grpc.Reflection.V1Alpha {
     public const int ContainingTypeFieldNumber = 1;
     private string containingType_ = "";
     /// <summary>
-    ///  Fully-qualified type name. The format should be &lt;package>.&lt;type>
+    /// Fully-qualified type name. The format should be &lt;package>.&lt;type>
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string ContainingType {
@@ -553,7 +553,7 @@ namespace Grpc.Reflection.V1Alpha {
   }
 
   /// <summary>
-  ///  The message sent by the server to answer ServerReflectionInfo method.
+  /// The message sent by the server to answer ServerReflectionInfo method.
   /// </summary>
   public sealed partial class ServerReflectionResponse : pb::IMessage<ServerReflectionResponse> {
     private static readonly pb::MessageParser<ServerReflectionResponse> _parser = new pb::MessageParser<ServerReflectionResponse>(() => new ServerReflectionResponse());
@@ -628,12 +628,12 @@ namespace Grpc.Reflection.V1Alpha {
     /// <summary>Field number for the "file_descriptor_response" field.</summary>
     public const int FileDescriptorResponseFieldNumber = 4;
     /// <summary>
-    ///  This message is used to answer file_by_filename, file_containing_symbol,
-    ///  file_containing_extension requests with transitive dependencies. As
-    ///  the repeated label is not allowed in oneof fields, we use a
-    ///  FileDescriptorResponse message to encapsulate the repeated fields.
-    ///  The reflection service is allowed to avoid sending FileDescriptorProtos
-    ///  that were previously sent in response to earlier requests in the stream.
+    /// This message is used to answer file_by_filename, file_containing_symbol,
+    /// file_containing_extension requests with transitive dependencies. As
+    /// the repeated label is not allowed in oneof fields, we use a
+    /// FileDescriptorResponse message to encapsulate the repeated fields.
+    /// The reflection service is allowed to avoid sending FileDescriptorProtos
+    /// that were previously sent in response to earlier requests in the stream.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Reflection.V1Alpha.FileDescriptorResponse FileDescriptorResponse {
@@ -647,7 +647,7 @@ namespace Grpc.Reflection.V1Alpha {
     /// <summary>Field number for the "all_extension_numbers_response" field.</summary>
     public const int AllExtensionNumbersResponseFieldNumber = 5;
     /// <summary>
-    ///  This message is used to answer all_extension_numbers_of_type requst.
+    /// This message is used to answer all_extension_numbers_of_type requst.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Reflection.V1Alpha.ExtensionNumberResponse AllExtensionNumbersResponse {
@@ -661,7 +661,7 @@ namespace Grpc.Reflection.V1Alpha {
     /// <summary>Field number for the "list_services_response" field.</summary>
     public const int ListServicesResponseFieldNumber = 6;
     /// <summary>
-    ///  This message is used to answer list_services request.
+    /// This message is used to answer list_services request.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Reflection.V1Alpha.ListServiceResponse ListServicesResponse {
@@ -675,7 +675,7 @@ namespace Grpc.Reflection.V1Alpha {
     /// <summary>Field number for the "error_response" field.</summary>
     public const int ErrorResponseFieldNumber = 7;
     /// <summary>
-    ///  This message is used when an error occurs.
+    /// This message is used when an error occurs.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Reflection.V1Alpha.ErrorResponse ErrorResponse {
@@ -893,9 +893,9 @@ namespace Grpc.Reflection.V1Alpha {
   }
 
   /// <summary>
-  ///  Serialized FileDescriptorProto messages sent by the server answering
-  ///  a file_by_filename, file_containing_symbol, or file_containing_extension
-  ///  request.
+  /// Serialized FileDescriptorProto messages sent by the server answering
+  /// a file_by_filename, file_containing_symbol, or file_containing_extension
+  /// request.
   /// </summary>
   public sealed partial class FileDescriptorResponse : pb::IMessage<FileDescriptorResponse> {
     private static readonly pb::MessageParser<FileDescriptorResponse> _parser = new pb::MessageParser<FileDescriptorResponse>(() => new FileDescriptorResponse());
@@ -935,9 +935,9 @@ namespace Grpc.Reflection.V1Alpha {
         = pb::FieldCodec.ForBytes(10);
     private readonly pbc::RepeatedField<pb::ByteString> fileDescriptorProto_ = new pbc::RepeatedField<pb::ByteString>();
     /// <summary>
-    ///  Serialized FileDescriptorProto messages. We avoid taking a dependency on
-    ///  descriptor.proto, which uses proto2 only features, by making them opaque
-    ///  bytes instead.
+    /// Serialized FileDescriptorProto messages. We avoid taking a dependency on
+    /// descriptor.proto, which uses proto2 only features, by making them opaque
+    /// bytes instead.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<pb::ByteString> FileDescriptorProto {
@@ -1012,8 +1012,8 @@ namespace Grpc.Reflection.V1Alpha {
   }
 
   /// <summary>
-  ///  A list of extension numbers sent by the server answering
-  ///  all_extension_numbers_of_type request.
+  /// A list of extension numbers sent by the server answering
+  /// all_extension_numbers_of_type request.
   /// </summary>
   public sealed partial class ExtensionNumberResponse : pb::IMessage<ExtensionNumberResponse> {
     private static readonly pb::MessageParser<ExtensionNumberResponse> _parser = new pb::MessageParser<ExtensionNumberResponse>(() => new ExtensionNumberResponse());
@@ -1052,8 +1052,8 @@ namespace Grpc.Reflection.V1Alpha {
     public const int BaseTypeNameFieldNumber = 1;
     private string baseTypeName_ = "";
     /// <summary>
-    ///  Full name of the base type, including the package name. The format
-    ///  is &lt;package>.&lt;type>
+    /// Full name of the base type, including the package name. The format
+    /// is &lt;package>.&lt;type>
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string BaseTypeName {
@@ -1158,7 +1158,7 @@ namespace Grpc.Reflection.V1Alpha {
   }
 
   /// <summary>
-  ///  A list of ServiceResponse sent by the server answering list_services request.
+  /// A list of ServiceResponse sent by the server answering list_services request.
   /// </summary>
   public sealed partial class ListServiceResponse : pb::IMessage<ListServiceResponse> {
     private static readonly pb::MessageParser<ListServiceResponse> _parser = new pb::MessageParser<ListServiceResponse>(() => new ListServiceResponse());
@@ -1198,8 +1198,8 @@ namespace Grpc.Reflection.V1Alpha {
         = pb::FieldCodec.ForMessage(10, global::Grpc.Reflection.V1Alpha.ServiceResponse.Parser);
     private readonly pbc::RepeatedField<global::Grpc.Reflection.V1Alpha.ServiceResponse> service_ = new pbc::RepeatedField<global::Grpc.Reflection.V1Alpha.ServiceResponse>();
     /// <summary>
-    ///  The information of each service may be expanded in the future, so we use
-    ///  ServiceResponse message to encapsulate it.
+    /// The information of each service may be expanded in the future, so we use
+    /// ServiceResponse message to encapsulate it.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<global::Grpc.Reflection.V1Alpha.ServiceResponse> Service {
@@ -1274,8 +1274,8 @@ namespace Grpc.Reflection.V1Alpha {
   }
 
   /// <summary>
-  ///  The information of a single service used by ListServiceResponse to answer
-  ///  list_services request.
+  /// The information of a single service used by ListServiceResponse to answer
+  /// list_services request.
   /// </summary>
   public sealed partial class ServiceResponse : pb::IMessage<ServiceResponse> {
     private static readonly pb::MessageParser<ServiceResponse> _parser = new pb::MessageParser<ServiceResponse>(() => new ServiceResponse());
@@ -1313,8 +1313,8 @@ namespace Grpc.Reflection.V1Alpha {
     public const int NameFieldNumber = 1;
     private string name_ = "";
     /// <summary>
-    ///  Full name of a registered service, including its package name. The format
-    ///  is &lt;package>.&lt;service>
+    /// Full name of a registered service, including its package name. The format
+    /// is &lt;package>.&lt;service>
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Name {
@@ -1399,7 +1399,7 @@ namespace Grpc.Reflection.V1Alpha {
   }
 
   /// <summary>
-  ///  The error code and error message sent by the server when an error occurs.
+  /// The error code and error message sent by the server when an error occurs.
   /// </summary>
   public sealed partial class ErrorResponse : pb::IMessage<ErrorResponse> {
     private static readonly pb::MessageParser<ErrorResponse> _parser = new pb::MessageParser<ErrorResponse>(() => new ErrorResponse());
@@ -1438,7 +1438,7 @@ namespace Grpc.Reflection.V1Alpha {
     public const int ErrorCodeFieldNumber = 1;
     private int errorCode_;
     /// <summary>
-    ///  This field uses the error codes defined in grpc::StatusCode.
+    /// This field uses the error codes defined in grpc::StatusCode.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int ErrorCode {
diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
index 5bd7558be58e2bad6f0877af7cb8f9d77966b944..45321587f5893620b3c6ce8408a7f5620a4b7e2f 100644
--- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
+++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
@@ -37,18 +37,18 @@
 using System;
 using System.Threading;
 using System.Threading.Tasks;
-using Grpc.Core;
+using grpc = global::Grpc.Core;
 
 namespace Grpc.Reflection.V1Alpha {
   public static partial class ServerReflection
   {
     static readonly string __ServiceName = "grpc.reflection.v1alpha.ServerReflection";
 
-    static readonly Marshaller<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest> __Marshaller_ServerReflectionRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Reflection.V1Alpha.ServerReflectionRequest.Parser.ParseFrom);
-    static readonly Marshaller<global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> __Marshaller_ServerReflectionResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Reflection.V1Alpha.ServerReflectionResponse.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest> __Marshaller_ServerReflectionRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Reflection.V1Alpha.ServerReflectionRequest.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> __Marshaller_ServerReflectionResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Reflection.V1Alpha.ServerReflectionResponse.Parser.ParseFrom);
 
-    static readonly Method<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> __Method_ServerReflectionInfo = new Method<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse>(
-        MethodType.DuplexStreaming,
+    static readonly grpc::Method<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> __Method_ServerReflectionInfo = new grpc::Method<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse>(
+        grpc::MethodType.DuplexStreaming,
         __ServiceName,
         "ServerReflectionInfo",
         __Marshaller_ServerReflectionRequest,
@@ -71,24 +71,24 @@ namespace Grpc.Reflection.V1Alpha {
       /// <param name="responseStream">Used for sending responses back to the client.</param>
       /// <param name="context">The context of the server-side call handler being invoked.</param>
       /// <returns>A task indicating completion of the handler.</returns>
-      public virtual global::System.Threading.Tasks.Task ServerReflectionInfo(IAsyncStreamReader<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest> requestStream, IServerStreamWriter<global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> responseStream, ServerCallContext context)
+      public virtual global::System.Threading.Tasks.Task ServerReflectionInfo(grpc::IAsyncStreamReader<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest> requestStream, grpc::IServerStreamWriter<global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> responseStream, grpc::ServerCallContext context)
       {
-        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
     }
 
     /// <summary>Client for ServerReflection</summary>
-    public partial class ServerReflectionClient : ClientBase<ServerReflectionClient>
+    public partial class ServerReflectionClient : grpc::ClientBase<ServerReflectionClient>
     {
       /// <summary>Creates a new client for ServerReflection</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
-      public ServerReflectionClient(Channel channel) : base(channel)
+      public ServerReflectionClient(grpc::Channel channel) : base(channel)
       {
       }
       /// <summary>Creates a new client for ServerReflection that uses a custom <c>CallInvoker</c>.</summary>
       /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
-      public ServerReflectionClient(CallInvoker callInvoker) : base(callInvoker)
+      public ServerReflectionClient(grpc::CallInvoker callInvoker) : base(callInvoker)
       {
       }
       /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
@@ -109,9 +109,9 @@ namespace Grpc.Reflection.V1Alpha {
       /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
       /// <param name="cancellationToken">An optional token for canceling the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncDuplexStreamingCall<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> ServerReflectionInfo(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> ServerReflectionInfo(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        return ServerReflectionInfo(new CallOptions(headers, deadline, cancellationToken));
+        return ServerReflectionInfo(new grpc::CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
       /// The reflection service is structured as a bidirectional stream, ensuring
@@ -119,7 +119,7 @@ namespace Grpc.Reflection.V1Alpha {
       /// </summary>
       /// <param name="options">The options for the call.</param>
       /// <returns>The call object.</returns>
-      public virtual AsyncDuplexStreamingCall<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> ServerReflectionInfo(CallOptions options)
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> ServerReflectionInfo(grpc::CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_ServerReflectionInfo, null, options);
       }
@@ -132,9 +132,9 @@ namespace Grpc.Reflection.V1Alpha {
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
-    public static ServerServiceDefinition BindService(ServerReflectionBase serviceImpl)
+    public static grpc::ServerServiceDefinition BindService(ServerReflectionBase serviceImpl)
     {
-      return ServerServiceDefinition.CreateBuilder()
+      return grpc::ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_ServerReflectionInfo, serviceImpl.ServerReflectionInfo).Build();
     }
 
diff --git a/src/csharp/Grpc.Reflection/packages.config b/src/csharp/Grpc.Reflection/packages.config
deleted file mode 100644
index 5ab40b7a8ced7fa54ff91552d9e3f885d337b237..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Reflection/packages.config
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
-</packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Reflection/project.json b/src/csharp/Grpc.Reflection/project.json
deleted file mode 100644
index bfc57661eb3f54b0028b901f6bb967502ee4edb4..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Reflection/project.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
-  "version": "1.2.0-dev",
-  "title": "gRPC C# Reflection",
-  "authors": [ "Google Inc." ],
-  "copyright": "Copyright 2016, Google Inc.",
-  "packOptions": {
-    "summary": "Implementation of gRPC reflection service",
-    "description": "Provides information about services running on a gRPC C# server.",
-    "owners": [ "grpc-packages" ],
-    "licenseUrl": "https://github.com/grpc/grpc/blob/master/LICENSE",
-    "projectUrl": "https://github.com/grpc/grpc",
-    "requireLicenseAcceptance": false,
-    "tags": [ "gRPC reflection" ]
-  },
-  "buildOptions": {
-    "define": [ "SIGNED" ],
-    "keyFile": "../keys/Grpc.snk",
-    "xmlDoc": true,
-    "compile": {
-      "includeFiles": [ "../Grpc.Core/Version.cs" ]
-    }
-  },
-  "dependencies": {
-    "Grpc.Core": "1.2.0-dev",
-    "Google.Protobuf": "3.0.0"
-  },
-  "frameworks": {
-    "net45": {
-      "frameworkAssemblies": {
-        "System.Runtime": "",
-        "System.IO": ""
-      }
-    },
-    "netstandard1.5": {
-      "dependencies": {
-        "NETStandard.Library": "1.6.0"
-      }
-    }
-  }
-}
diff --git a/src/csharp/Grpc.sln b/src/csharp/Grpc.sln
index 84ba46047f71a05df8b3c7f253fa8e7f96b44cd4..beab3ccb36c48a5564b9a3c0b7877c95ddeb747a 100644
--- a/src/csharp/Grpc.sln
+++ b/src/csharp/Grpc.sln
@@ -1,125 +1,118 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-VisualStudioVersion = 12.0.31101.0
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Examples", "Grpc.Examples\Grpc.Examples.csproj", "{7DC1433E-3225-42C7-B7EA-546D56E27A4B}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Core", "Grpc.Core\Grpc.Core.csproj", "{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Core.Tests", "Grpc.Core.Tests\Grpc.Core.Tests.csproj", "{86EC5CB4-4EA2-40A2-8057-86542A0353BB}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Examples.Tests", "Grpc.Examples.Tests\Grpc.Examples.Tests.csproj", "{143B1C29-C442-4BE0-BF3F-A8F92288AC9F}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Examples.MathClient", "Grpc.Examples.MathClient\Grpc.Examples.MathClient.csproj", "{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting", "Grpc.IntegrationTesting\Grpc.IntegrationTesting.csproj", "{C61154BA-DD4A-4838-8420-0162A28925E0}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.Client", "Grpc.IntegrationTesting.Client\Grpc.IntegrationTesting.Client.csproj", "{3D166931-BA2D-416E-95A3-D36E8F6E90B9}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.Server", "Grpc.IntegrationTesting.Server\Grpc.IntegrationTesting.Server.csproj", "{A654F3B8-E859-4E6A-B30D-227527DBEF0D}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Examples.MathServer", "Grpc.Examples.MathServer\Grpc.Examples.MathServer.csproj", "{BF62FE08-373A-43D6-9D73-41CAA38B7011}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Auth", "Grpc.Auth\Grpc.Auth.csproj", "{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{B5B87121-35FE-49D1-8CB1-8A91AAA398A9}"
-	ProjectSection(SolutionItems) = preProject
-		.nuget\packages.config = .nuget\packages.config
-	EndProjectSection
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.HealthCheck", "Grpc.HealthCheck\Grpc.HealthCheck.csproj", "{AA5E328A-8835-49D7-98ED-C29F2B3049F0}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.HealthCheck.Tests", "Grpc.HealthCheck.Tests\Grpc.HealthCheck.Tests.csproj", "{F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.QpsWorker", "Grpc.IntegrationTesting.QpsWorker\Grpc.IntegrationTesting.QpsWorker.csproj", "{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.StressClient", "Grpc.IntegrationTesting.StressClient\Grpc.IntegrationTesting.StressClient.csproj", "{ADEBA147-80AE-4710-82E9-5B7F93690266}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Reflection", "Grpc.Reflection\Grpc.Reflection.csproj", "{4F18CF52-B3DB-4A77-97C5-7F7F4B6C1715}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Reflection.Tests", "Grpc.Reflection.Tests\Grpc.Reflection.Tests.csproj", "{B88F91D6-436D-4C78-8B99-47800FA8DE03}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Core.Testing", "Grpc.Core.Testing\Grpc.Core.Testing.csproj", "{3AB047CA-6CF9-435D-AA61-2D86C6FA2457}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
-		Release|Any CPU = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Release|Any CPU.Build.0 = Release|Any CPU
-		{3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Release|Any CPU.Build.0 = Release|Any CPU
-		{4F18CF52-B3DB-4A77-97C5-7F7F4B6C1715}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{4F18CF52-B3DB-4A77-97C5-7F7F4B6C1715}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{4F18CF52-B3DB-4A77-97C5-7F7F4B6C1715}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{4F18CF52-B3DB-4A77-97C5-7F7F4B6C1715}.Release|Any CPU.Build.0 = Release|Any CPU
-		{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Release|Any CPU.Build.0 = Release|Any CPU
-		{7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Release|Any CPU.Build.0 = Release|Any CPU
-		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Release|Any CPU.Build.0 = Release|Any CPU
-		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|Any CPU.Build.0 = Release|Any CPU
-		{AA5E328A-8835-49D7-98ED-C29F2B3049F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{AA5E328A-8835-49D7-98ED-C29F2B3049F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{AA5E328A-8835-49D7-98ED-C29F2B3049F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{AA5E328A-8835-49D7-98ED-C29F2B3049F0}.Release|Any CPU.Build.0 = Release|Any CPU
-		{ADEBA147-80AE-4710-82E9-5B7F93690266}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{ADEBA147-80AE-4710-82E9-5B7F93690266}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{ADEBA147-80AE-4710-82E9-5B7F93690266}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{ADEBA147-80AE-4710-82E9-5B7F93690266}.Release|Any CPU.Build.0 = Release|Any CPU
-		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Release|Any CPU.Build.0 = Release|Any CPU
-		{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}.Release|Any CPU.Build.0 = Release|Any CPU
-		{B88F91D6-436D-4C78-8B99-47800FA8DE03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{B88F91D6-436D-4C78-8B99-47800FA8DE03}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{B88F91D6-436D-4C78-8B99-47800FA8DE03}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{B88F91D6-436D-4C78-8B99-47800FA8DE03}.Release|Any CPU.Build.0 = Release|Any CPU
-		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|Any CPU.Build.0 = Release|Any CPU
-		{C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{C61154BA-DD4A-4838-8420-0162A28925E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{C61154BA-DD4A-4838-8420-0162A28925E0}.Release|Any CPU.Build.0 = Release|Any CPU
-		{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Release|Any CPU.Build.0 = Release|Any CPU
-		{F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Release|Any CPU.Build.0 = Release|Any CPU
-		{3AB047CA-6CF9-435D-AA61-2D86C6FA2457}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{3AB047CA-6CF9-435D-AA61-2D86C6FA2457}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{3AB047CA-6CF9-435D-AA61-2D86C6FA2457}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{3AB047CA-6CF9-435D-AA61-2D86C6FA2457}.Release|Any CPU.Build.0 = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(NestedProjects) = preSolution
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26228.4
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Core", "Grpc.Core\Grpc.Core.csproj", "{BD878CB3-BDB4-46AB-84EF-C3B4729F56BC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Auth", "Grpc.Auth\Grpc.Auth.csproj", "{2A16007A-5D67-4C53-BEC8-51E5064D18BF}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Core.Testing", "Grpc.Core.Testing\Grpc.Core.Testing.csproj", "{05DC61DF-26F3-4F51-8577-1ABE4F4388B0}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Core.Tests", "Grpc.Core.Tests\Grpc.Core.Tests.csproj", "{02C79983-6011-43E2-A52D-75F9FC64663F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Examples", "Grpc.Examples\Grpc.Examples.csproj", "{C643975D-5D26-4860-8002-3B62A132DA2B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Examples.MathClient", "Grpc.Examples.MathClient\Grpc.Examples.MathClient.csproj", "{1F498972-FD16-4A02-B133-C24652F14869}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Examples.MathServer", "Grpc.Examples.MathServer\Grpc.Examples.MathServer.csproj", "{9F2A873E-83E0-44C4-81D0-DDBC1D36F8B0}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Examples.Tests", "Grpc.Examples.Tests\Grpc.Examples.Tests.csproj", "{7022461C-0D5E-4817-9A5A-3C027FD22457}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.HealthCheck", "Grpc.HealthCheck\Grpc.HealthCheck.csproj", "{DBD57899-0148-4B0D-A8EA-DE3954FA657C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.HealthCheck.Tests", "Grpc.HealthCheck.Tests\Grpc.HealthCheck.Tests.csproj", "{033E4DC1-5D79-4308-B8B1-9A1B71E39BA1}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.IntegrationTesting", "Grpc.IntegrationTesting\Grpc.IntegrationTesting.csproj", "{CB43BF5B-4D31-4347-A97A-0164B1248B39}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.IntegrationTesting.Client", "Grpc.IntegrationTesting.Client\Grpc.IntegrationTesting.Client.csproj", "{83CCB684-54E6-4552-A00D-3CF9291A1B27}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.IntegrationTesting.QpsWorker", "Grpc.IntegrationTesting.QpsWorker\Grpc.IntegrationTesting.QpsWorker.csproj", "{8ED094CD-DF46-4272-A981-99F3DD184590}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.IntegrationTesting.Server", "Grpc.IntegrationTesting.Server\Grpc.IntegrationTesting.Server.csproj", "{F3A264BE-A62F-4B6A-89A0-7CF7BB275460}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.IntegrationTesting.StressClient", "Grpc.IntegrationTesting.StressClient\Grpc.IntegrationTesting.StressClient.csproj", "{0BB94A8B-9CE3-4A87-95BC-90F8A53CC154}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Reflection", "Grpc.Reflection\Grpc.Reflection.csproj", "{26807744-FD0B-494A-9F99-0B171E9A892E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Reflection.Tests", "Grpc.Reflection.Tests\Grpc.Reflection.Tests.csproj", "{335AD0A2-F2CC-4C2E-853C-26174206BEE7}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{BD878CB3-BDB4-46AB-84EF-C3B4729F56BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{BD878CB3-BDB4-46AB-84EF-C3B4729F56BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BD878CB3-BDB4-46AB-84EF-C3B4729F56BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{BD878CB3-BDB4-46AB-84EF-C3B4729F56BC}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2A16007A-5D67-4C53-BEC8-51E5064D18BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2A16007A-5D67-4C53-BEC8-51E5064D18BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2A16007A-5D67-4C53-BEC8-51E5064D18BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2A16007A-5D67-4C53-BEC8-51E5064D18BF}.Release|Any CPU.Build.0 = Release|Any CPU
+		{05DC61DF-26F3-4F51-8577-1ABE4F4388B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{05DC61DF-26F3-4F51-8577-1ABE4F4388B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{05DC61DF-26F3-4F51-8577-1ABE4F4388B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{05DC61DF-26F3-4F51-8577-1ABE4F4388B0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{02C79983-6011-43E2-A52D-75F9FC64663F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{02C79983-6011-43E2-A52D-75F9FC64663F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{02C79983-6011-43E2-A52D-75F9FC64663F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{02C79983-6011-43E2-A52D-75F9FC64663F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C643975D-5D26-4860-8002-3B62A132DA2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C643975D-5D26-4860-8002-3B62A132DA2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C643975D-5D26-4860-8002-3B62A132DA2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C643975D-5D26-4860-8002-3B62A132DA2B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{1F498972-FD16-4A02-B133-C24652F14869}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1F498972-FD16-4A02-B133-C24652F14869}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1F498972-FD16-4A02-B133-C24652F14869}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{1F498972-FD16-4A02-B133-C24652F14869}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9F2A873E-83E0-44C4-81D0-DDBC1D36F8B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{9F2A873E-83E0-44C4-81D0-DDBC1D36F8B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9F2A873E-83E0-44C4-81D0-DDBC1D36F8B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{9F2A873E-83E0-44C4-81D0-DDBC1D36F8B0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7022461C-0D5E-4817-9A5A-3C027FD22457}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7022461C-0D5E-4817-9A5A-3C027FD22457}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7022461C-0D5E-4817-9A5A-3C027FD22457}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7022461C-0D5E-4817-9A5A-3C027FD22457}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DBD57899-0148-4B0D-A8EA-DE3954FA657C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DBD57899-0148-4B0D-A8EA-DE3954FA657C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DBD57899-0148-4B0D-A8EA-DE3954FA657C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DBD57899-0148-4B0D-A8EA-DE3954FA657C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{033E4DC1-5D79-4308-B8B1-9A1B71E39BA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{033E4DC1-5D79-4308-B8B1-9A1B71E39BA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{033E4DC1-5D79-4308-B8B1-9A1B71E39BA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{033E4DC1-5D79-4308-B8B1-9A1B71E39BA1}.Release|Any CPU.Build.0 = Release|Any CPU
+		{CB43BF5B-4D31-4347-A97A-0164B1248B39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{CB43BF5B-4D31-4347-A97A-0164B1248B39}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{CB43BF5B-4D31-4347-A97A-0164B1248B39}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{CB43BF5B-4D31-4347-A97A-0164B1248B39}.Release|Any CPU.Build.0 = Release|Any CPU
+		{83CCB684-54E6-4552-A00D-3CF9291A1B27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{83CCB684-54E6-4552-A00D-3CF9291A1B27}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{83CCB684-54E6-4552-A00D-3CF9291A1B27}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{83CCB684-54E6-4552-A00D-3CF9291A1B27}.Release|Any CPU.Build.0 = Release|Any CPU
+		{8ED094CD-DF46-4272-A981-99F3DD184590}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{8ED094CD-DF46-4272-A981-99F3DD184590}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{8ED094CD-DF46-4272-A981-99F3DD184590}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{8ED094CD-DF46-4272-A981-99F3DD184590}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F3A264BE-A62F-4B6A-89A0-7CF7BB275460}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F3A264BE-A62F-4B6A-89A0-7CF7BB275460}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F3A264BE-A62F-4B6A-89A0-7CF7BB275460}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F3A264BE-A62F-4B6A-89A0-7CF7BB275460}.Release|Any CPU.Build.0 = Release|Any CPU
+		{0BB94A8B-9CE3-4A87-95BC-90F8A53CC154}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{0BB94A8B-9CE3-4A87-95BC-90F8A53CC154}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{0BB94A8B-9CE3-4A87-95BC-90F8A53CC154}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{0BB94A8B-9CE3-4A87-95BC-90F8A53CC154}.Release|Any CPU.Build.0 = Release|Any CPU
+		{26807744-FD0B-494A-9F99-0B171E9A892E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{26807744-FD0B-494A-9F99-0B171E9A892E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{26807744-FD0B-494A-9F99-0B171E9A892E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{26807744-FD0B-494A-9F99-0B171E9A892E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{335AD0A2-F2CC-4C2E-853C-26174206BEE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{335AD0A2-F2CC-4C2E-853C-26174206BEE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{335AD0A2-F2CC-4C2E-853C-26174206BEE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{335AD0A2-F2CC-4C2E-853C-26174206BEE7}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/src/csharp/README.md b/src/csharp/README.md
index a21b72f2253083a081997ee1bd60dd6c9bb92648..a973d2e59709f1c66e1dcb0993503a74ce086678 100644
--- a/src/csharp/README.md
+++ b/src/csharp/README.md
@@ -16,7 +16,7 @@ PREREQUISITES
 
 When using gRPC C# under .NET Core you only need to [install .NET Core](https://www.microsoft.com/net/core).
 
-- Windows: .NET Framework 4.5+, Visual Studio 2013 or 2015
+- Windows: .NET Framework 4.5+, Visual Studio 2013, 2015, 2017
 - Linux: Mono 4+, MonoDevelop 5.9+ (with NuGet add-in installed)
 - Mac OS X: Xamarin Studio 5.9+
 
@@ -45,7 +45,9 @@ If you are a user of gRPC C#, go to Usage section above.
   $ python tools/run_tests/run_tests.py -c dbg -l csharp --build_only
   ```
 
-- Use Visual Studio / MonoDevelop / Xamarin Studio to open the solution Grpc.sln
+- Use Visual Studio 2017 (on Windows) to open the solution `Grpc.sln` or use Visual Studio Code with C# extension (on Linux and Mac). gRPC C# code has been migrated to
+  dotnet SDK `.csproj` projects that are much simpler to maintain, but are not yet supported by Xamarin Studio or Monodevelop (the NuGet packages still
+  support both `net45` and `netstandard` and can be used in all IDEs).
 
 RUNNING TESTS
 -------------
@@ -55,9 +57,6 @@ gRPC C# is using NUnit as the testing framework.
 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 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.
-
 gRPC team uses a Python script to simplify facilitate running tests for
 different languages.
 
diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat
index b99fdcbdfde8bee033333af49e9bd2199e4dd4ee..673642e3d8714710ea10993101f2145d97f41399 100755
--- a/src/csharp/build_packages_dotnetcli.bat
+++ b/src/csharp/build_packages_dotnetcli.bat
@@ -28,12 +28,11 @@
 @rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 @rem Current package versions
-set VERSION=1.2.0-dev
-set PROTOBUF_VERSION=3.0.0
+set VERSION=1.4.0-dev
 
 @rem Adjust the location of nuget.exe
 set NUGET=C:\nuget\nuget.exe
-set DOTNET=C:\dotnet\dotnet.exe
+set DOTNET=dotnet
 
 set -ex
 
@@ -56,13 +55,16 @@ xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=linux\artifacts\* pr
 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\
 
-%DOTNET% restore . || goto :error
+%DOTNET% restore Grpc.sln || goto :error
 
-%DOTNET% pack --configuration Release Grpc.Core\project.json --output ..\..\artifacts || goto :error
-%DOTNET% pack --configuration Release Grpc.Core.Testing\project.json --output ..\..\artifacts || goto :error
-%DOTNET% pack --configuration Release Grpc.Auth\project.json --output ..\..\artifacts || goto :error
-%DOTNET% pack --configuration Release Grpc.HealthCheck\project.json --output ..\..\artifacts || goto :error
-%DOTNET% pack --configuration Release Grpc.Reflection\project.json --output ..\..\artifacts || goto :error
+@rem To be able to build, we also need to put grpc_csharp_ext to its normal location
+xcopy /Y /I nativelibs\windows_x64\grpc_csharp_ext.dll ..\..\cmake\build\x64\Release\
+
+%DOTNET% pack --configuration Release Grpc.Core --output ..\..\..\artifacts || goto :error
+%DOTNET% pack --configuration Release Grpc.Core.Testing --output ..\..\..\artifacts || goto :error
+%DOTNET% pack --configuration Release Grpc.Auth --output ..\..\..\artifacts || goto :error
+%DOTNET% pack --configuration Release Grpc.HealthCheck --output ..\..\..\artifacts || goto :error
+%DOTNET% pack --configuration Release Grpc.Reflection --output ..\..\..\artifacts || goto :error
 
 %NUGET% pack Grpc.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts || goto :error
 %NUGET% pack Grpc.Tools.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts
diff --git a/src/csharp/build_packages_dotnetcli.sh b/src/csharp/build_packages_dotnetcli.sh
index 442e3acad28a5e23b8d0351a502b4b20c8a78071..ee923e3d870b5edeb7193eeb0ba787790fef0703 100755
--- a/src/csharp/build_packages_dotnetcli.sh
+++ b/src/csharp/build_packages_dotnetcli.sh
@@ -58,15 +58,19 @@ cp $EXTERNAL_GIT_ROOT/architecture=x64,language=protoc,platform=linux/artifacts/
 cp $EXTERNAL_GIT_ROOT/architecture=x86,language=protoc,platform=macos/artifacts/* protoc_plugins/macosx_x86 || true
 cp $EXTERNAL_GIT_ROOT/architecture=x64,language=protoc,platform=macos/artifacts/* protoc_plugins/macosx_x64 || true
 
-dotnet restore .
+dotnet restore Grpc.sln
 
-dotnet pack --configuration Release Grpc.Core/project.json --output ../../artifacts
-dotnet pack --configuration Release Grpc.Core.Testing/project.json --output ../../artifacts
-dotnet pack --configuration Release Grpc.Auth/project.json --output ../../artifacts
-dotnet pack --configuration Release Grpc.HealthCheck/project.json --output ../../artifacts
-dotnet pack --configuration Release Grpc.Reflection/project.json --output ../../artifacts
+# To be able to build, we also need to put grpc_csharp_ext to its normal location
+mkdir -p ../../libs/opt
+cp nativelibs/linux_x64/libgrpc_csharp_ext.so ../../libs/opt
 
-nuget pack Grpc.nuspec -Version "1.2.0-dev" -OutputDirectory ../../artifacts
-nuget pack Grpc.Tools.nuspec -Version "1.2.0-dev" -OutputDirectory ../../artifacts
+dotnet pack --configuration Release Grpc.Core --output ../../../artifacts
+dotnet pack --configuration Release Grpc.Core.Testing --output ../../../artifacts
+dotnet pack --configuration Release Grpc.Auth --output ../../../artifacts
+dotnet pack --configuration Release Grpc.HealthCheck --output ../../../artifacts
+dotnet pack --configuration Release Grpc.Reflection --output ../../../artifacts
+
+nuget pack Grpc.nuspec -Version "1.4.0-dev" -OutputDirectory ../../artifacts
+nuget pack Grpc.Tools.nuspec -Version "1.4.0-dev" -OutputDirectory ../../artifacts
 
 (cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg)
diff --git a/src/csharp/doc/grpc_csharp_public.shfbproj b/src/csharp/doc/grpc_csharp_public.shfbproj
index d9b9749819099de7c731dee84d75ba93983ca2fa..fab953da35339dab4bfadbced1f8f14972db0456 100644
--- a/src/csharp/doc/grpc_csharp_public.shfbproj
+++ b/src/csharp/doc/grpc_csharp_public.shfbproj
@@ -18,8 +18,10 @@
     <Language>en-US</Language>
     <DocumentationSources>
       <DocumentationSource sourceFile="..\Grpc.Auth\Grpc.Auth.csproj" />
-      <DocumentationSource sourceFile="..\Grpc.Core\Grpc.Core.csproj" />
-    </DocumentationSources>
+<DocumentationSource sourceFile="..\Grpc.Core\Grpc.Core.csproj" />
+<DocumentationSource sourceFile="..\Grpc.HealthCheck\Grpc.HealthCheck.csproj" />
+<DocumentationSource sourceFile="..\Grpc.Reflection\Grpc.Reflection.csproj" />
+<DocumentationSource sourceFile="..\Grpc.Core.Testing\Grpc.Core.Testing.csproj" /></DocumentationSources>
     <BuildAssemblerVerbosity>OnlyWarningsAndErrors</BuildAssemblerVerbosity>
     <HelpFileFormat>Website</HelpFileFormat>
     <IndentHtml>False</IndentHtml>
@@ -40,12 +42,13 @@
     <HtmlHelpName>Documentation</HtmlHelpName>
     <NamespaceSummaries>
       <NamespaceSummaryItem name="Grpc.Auth" isDocumented="True">Provides OAuth2 based authentication for gRPC. &lt;c&gt;Grpc.Auth&lt;/c&gt; currently consists of a set of very lightweight wrappers and uses C# &lt;a href="https://www.nuget.org/packages/Google.Apis.Auth/"&gt;Google.Apis.Auth&lt;/a&gt; library.</NamespaceSummaryItem>
-<NamespaceSummaryItem name="Grpc.Core" isDocumented="True">Main namespace for gRPC C# functionality. Contains concepts representing both client side and server side gRPC logic.
+      <NamespaceSummaryItem name="Grpc.Core" isDocumented="True">Main namespace for gRPC C# functionality. Contains concepts representing both client side and server side gRPC logic.
 
 &lt;seealso cref="Grpc.Core.Channel"/&gt; 
 &lt;seealso cref="Grpc.Core.Server"/&gt;</NamespaceSummaryItem>
-<NamespaceSummaryItem name="Grpc.Core.Logging" isDocumented="True">Provides functionality to redirect gRPC logs to application-specified destination.</NamespaceSummaryItem>
-<NamespaceSummaryItem name="Grpc.Core.Utils" isDocumented="True">Various utilities for gRPC C#.</NamespaceSummaryItem></NamespaceSummaries>
+      <NamespaceSummaryItem name="Grpc.Core.Logging" isDocumented="True">Provides functionality to redirect gRPC logs to application-specified destination.</NamespaceSummaryItem>
+      <NamespaceSummaryItem name="Grpc.Core.Utils" isDocumented="True">Various utilities for gRPC C#.</NamespaceSummaryItem>
+    </NamespaceSummaries>
     <MissingTags>Summary, Parameter, AutoDocumentCtors, Namespace, TypeParameter, AutoDocumentDispose</MissingTags>
   </PropertyGroup>
   <!-- There are no properties for these groups.  AnyCPU needs to appear in order for Visual Studio to perform
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 6a241190b274c0e957ecbd0c3b43c1e34ade1b91..f6cff454bdba59d2b94e452b60bb4edb33e72503 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -34,14 +34,14 @@
 #include "src/core/lib/support/string.h"
 
 #include <grpc/byte_buffer_reader.h>
-#include <grpc/support/port_platform.h>
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+#include <grpc/slice.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
-#include <grpc/slice.h>
+#include <grpc/support/port_platform.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/thd.h>
-#include <grpc/grpc.h>
-#include <grpc/grpc_security.h>
 
 #include <string.h>
 
@@ -84,7 +84,8 @@ typedef struct grpcsharp_batch_context {
   int recv_close_on_server_cancelled;
 } grpcsharp_batch_context;
 
-GPR_EXPORT grpcsharp_batch_context *GPR_CALLTYPE grpcsharp_batch_context_create() {
+GPR_EXPORT grpcsharp_batch_context *GPR_CALLTYPE
+grpcsharp_batch_context_create() {
   grpcsharp_batch_context *ctx = gpr_malloc(sizeof(grpcsharp_batch_context));
   memset(ctx, 0, sizeof(grpcsharp_batch_context));
   return ctx;
@@ -96,8 +97,10 @@ typedef struct {
   grpc_metadata_array request_metadata;
 } grpcsharp_request_call_context;
 
-GPR_EXPORT grpcsharp_request_call_context *GPR_CALLTYPE grpcsharp_request_call_context_create() {
-  grpcsharp_request_call_context *ctx = gpr_malloc(sizeof(grpcsharp_request_call_context));
+GPR_EXPORT grpcsharp_request_call_context *GPR_CALLTYPE
+grpcsharp_request_call_context_create() {
+  grpcsharp_request_call_context *ctx =
+      gpr_malloc(sizeof(grpcsharp_request_call_context));
   memset(ctx, 0, sizeof(grpcsharp_request_call_context));
   return ctx;
 }
@@ -175,15 +178,15 @@ grpcsharp_metadata_array_count(grpc_metadata_array *array) {
   return (intptr_t)array->count;
 }
 
-GPR_EXPORT const char *GPR_CALLTYPE
-grpcsharp_metadata_array_get_key(grpc_metadata_array *array, size_t index, size_t *key_length) {
+GPR_EXPORT const char *GPR_CALLTYPE grpcsharp_metadata_array_get_key(
+    grpc_metadata_array *array, size_t index, size_t *key_length) {
   GPR_ASSERT(index < array->count);
   *key_length = GRPC_SLICE_LENGTH(array->metadata[index].key);
   return (char *)GRPC_SLICE_START_PTR(array->metadata[index].key);
 }
 
-GPR_EXPORT const char *GPR_CALLTYPE
-grpcsharp_metadata_array_get_value(grpc_metadata_array *array, size_t index, size_t *value_length) {
+GPR_EXPORT const char *GPR_CALLTYPE grpcsharp_metadata_array_get_value(
+    grpc_metadata_array *array, size_t index, size_t *value_length) {
   GPR_ASSERT(index < array->count);
   *value_length = GRPC_SLICE_LENGTH(array->metadata[index].value);
   return (char *)GRPC_SLICE_START_PTR(array->metadata[index].value);
@@ -208,7 +211,8 @@ void grpcsharp_metadata_array_move(grpc_metadata_array *dest,
   src->metadata = NULL;
 }
 
-GPR_EXPORT void GPR_CALLTYPE grpcsharp_batch_context_destroy(grpcsharp_batch_context *ctx) {
+GPR_EXPORT void GPR_CALLTYPE
+grpcsharp_batch_context_destroy(grpcsharp_batch_context *ctx) {
   if (!ctx) {
     return;
   }
@@ -231,7 +235,8 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_batch_context_destroy(grpcsharp_batch_con
   gpr_free(ctx);
 }
 
-GPR_EXPORT void GPR_CALLTYPE grpcsharp_request_call_context_destroy(grpcsharp_request_call_context *ctx) {
+GPR_EXPORT void GPR_CALLTYPE
+grpcsharp_request_call_context_destroy(grpcsharp_request_call_context *ctx) {
   if (!ctx) {
     return;
   }
@@ -240,8 +245,7 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_request_call_context_destroy(grpcsharp_re
      to take its ownership. */
 
   grpc_call_details_destroy(&(ctx->call_details));
-  grpcsharp_metadata_array_destroy_metadata_only(
-      &(ctx->request_metadata));
+  grpcsharp_metadata_array_destroy_metadata_only(&(ctx->request_metadata));
 
   gpr_free(ctx);
 }
@@ -299,8 +303,10 @@ grpcsharp_batch_context_recv_status_on_client_status(
 GPR_EXPORT const char *GPR_CALLTYPE
 grpcsharp_batch_context_recv_status_on_client_details(
     const grpcsharp_batch_context *ctx, size_t *details_length) {
-  *details_length = GRPC_SLICE_LENGTH(ctx->recv_status_on_client.status_details);
-  return (char *)GRPC_SLICE_START_PTR(ctx->recv_status_on_client.status_details);
+  *details_length =
+      GRPC_SLICE_LENGTH(ctx->recv_status_on_client.status_details);
+  return (char *)GRPC_SLICE_START_PTR(
+      ctx->recv_status_on_client.status_details);
 }
 
 GPR_EXPORT const grpc_metadata_array *GPR_CALLTYPE
@@ -309,13 +315,12 @@ grpcsharp_batch_context_recv_status_on_client_trailing_metadata(
   return &(ctx->recv_status_on_client.trailing_metadata);
 }
 
-GPR_EXPORT grpc_call *GPR_CALLTYPE grpcsharp_request_call_context_call(
-    const grpcsharp_request_call_context *ctx) {
+GPR_EXPORT grpc_call *GPR_CALLTYPE
+grpcsharp_request_call_context_call(const grpcsharp_request_call_context *ctx) {
   return ctx->call;
 }
 
-GPR_EXPORT const char *GPR_CALLTYPE
-grpcsharp_request_call_context_method(
+GPR_EXPORT const char *GPR_CALLTYPE grpcsharp_request_call_context_method(
     const grpcsharp_request_call_context *ctx, size_t *method_length) {
   *method_length = GRPC_SLICE_LENGTH(ctx->call_details.method);
   return (char *)GRPC_SLICE_START_PTR(ctx->call_details.method);
@@ -327,8 +332,7 @@ GPR_EXPORT const char *GPR_CALLTYPE grpcsharp_request_call_context_host(
   return (char *)GRPC_SLICE_START_PTR(ctx->call_details.host);
 }
 
-GPR_EXPORT gpr_timespec GPR_CALLTYPE
-grpcsharp_request_call_context_deadline(
+GPR_EXPORT gpr_timespec GPR_CALLTYPE grpcsharp_request_call_context_deadline(
     const grpcsharp_request_call_context *ctx) {
   return ctx->call_details.deadline;
 }
@@ -342,7 +346,7 @@ grpcsharp_request_call_context_request_metadata(
 GPR_EXPORT int32_t GPR_CALLTYPE
 grpcsharp_batch_context_recv_close_on_server_cancelled(
     const grpcsharp_batch_context *ctx) {
-  return (int32_t) ctx->recv_close_on_server_cancelled;
+  return (int32_t)ctx->recv_close_on_server_cancelled;
 }
 
 /* Init & shutdown */
@@ -354,8 +358,13 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_shutdown(void) { grpc_shutdown(); }
 /* Completion queue */
 
 GPR_EXPORT grpc_completion_queue *GPR_CALLTYPE
-grpcsharp_completion_queue_create(void) {
-  return grpc_completion_queue_create(NULL);
+grpcsharp_completion_queue_create_async(void) {
+  return grpc_completion_queue_create_for_next(NULL);
+}
+
+GPR_EXPORT grpc_completion_queue *GPR_CALLTYPE
+grpcsharp_completion_queue_create_sync(void) {
+  return grpc_completion_queue_create_for_pluck(NULL);
 }
 
 GPR_EXPORT void GPR_CALLTYPE
@@ -384,7 +393,8 @@ grpcsharp_completion_queue_pluck(grpc_completion_queue *cq, void *tag) {
 
 GPR_EXPORT grpc_channel *GPR_CALLTYPE
 
-grpcsharp_insecure_channel_create(const char *target, const grpc_channel_args *args) {
+grpcsharp_insecure_channel_create(const char *target,
+                                  const grpc_channel_args *args) {
   return grpc_insecure_channel_create(target, args, NULL);
 }
 
@@ -392,12 +402,10 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_channel_destroy(grpc_channel *channel) {
   grpc_channel_destroy(channel);
 }
 
-GPR_EXPORT grpc_call *GPR_CALLTYPE
-grpcsharp_channel_create_call(grpc_channel *channel, grpc_call *parent_call,
-                              uint32_t propagation_mask,
-                              grpc_completion_queue *cq,
-                              const char *method, const char *host,
-                              gpr_timespec deadline) {
+GPR_EXPORT grpc_call *GPR_CALLTYPE grpcsharp_channel_create_call(
+    grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
+    grpc_completion_queue *cq, const char *method, const char *host,
+    gpr_timespec deadline) {
   grpc_slice method_slice = grpc_slice_from_copied_string(method);
   grpc_slice *host_slice_ptr = NULL;
   grpc_slice host_slice;
@@ -410,18 +418,21 @@ grpcsharp_channel_create_call(grpc_channel *channel, grpc_call *parent_call,
 }
 
 GPR_EXPORT grpc_connectivity_state GPR_CALLTYPE
-grpcsharp_channel_check_connectivity_state(grpc_channel *channel, int32_t try_to_connect) {
+grpcsharp_channel_check_connectivity_state(grpc_channel *channel,
+                                           int32_t try_to_connect) {
   return grpc_channel_check_connectivity_state(channel, try_to_connect);
 }
 
 GPR_EXPORT void GPR_CALLTYPE grpcsharp_channel_watch_connectivity_state(
     grpc_channel *channel, grpc_connectivity_state last_observed_state,
-    gpr_timespec deadline, grpc_completion_queue *cq, grpcsharp_batch_context *ctx) {
-  grpc_channel_watch_connectivity_state(channel, last_observed_state,
-                                        deadline, cq, ctx);
+    gpr_timespec deadline, grpc_completion_queue *cq,
+    grpcsharp_batch_context *ctx) {
+  grpc_channel_watch_connectivity_state(channel, last_observed_state, deadline,
+                                        cq, ctx);
 }
 
-GPR_EXPORT char *GPR_CALLTYPE grpcsharp_channel_get_target(grpc_channel *channel) {
+GPR_EXPORT char *GPR_CALLTYPE
+grpcsharp_channel_get_target(grpc_channel *channel) {
   return grpc_channel_get_target(channel);
 }
 
@@ -439,9 +450,8 @@ grpcsharp_channel_args_create(size_t num_args) {
   return args;
 }
 
-GPR_EXPORT void GPR_CALLTYPE
-grpcsharp_channel_args_set_string(grpc_channel_args *args, size_t index,
-                                  const char *key, const char *value) {
+GPR_EXPORT void GPR_CALLTYPE grpcsharp_channel_args_set_string(
+    grpc_channel_args *args, size_t index, const char *key, const char *value) {
   GPR_ASSERT(args);
   GPR_ASSERT(index < args->num_args);
   args->args[index].type = GRPC_ARG_STRING;
@@ -449,9 +459,8 @@ grpcsharp_channel_args_set_string(grpc_channel_args *args, size_t index,
   args->args[index].value.string = gpr_strdup(value);
 }
 
-GPR_EXPORT void GPR_CALLTYPE
-grpcsharp_channel_args_set_integer(grpc_channel_args *args, size_t index,
-                                  const char *key, int value) {
+GPR_EXPORT void GPR_CALLTYPE grpcsharp_channel_args_set_integer(
+    grpc_channel_args *args, size_t index, const char *key, int value) {
   GPR_ASSERT(args);
   GPR_ASSERT(index < args->num_args);
   args->args[index].type = GRPC_ARG_INTEGER;
@@ -480,15 +489,18 @@ GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_now(gpr_clock_type clock_type) {
   return gpr_now(clock_type);
 }
 
-GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_inf_future(gpr_clock_type clock_type) {
+GPR_EXPORT gpr_timespec GPR_CALLTYPE
+gprsharp_inf_future(gpr_clock_type clock_type) {
   return gpr_inf_future(clock_type);
 }
 
-GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_inf_past(gpr_clock_type clock_type) {
+GPR_EXPORT gpr_timespec GPR_CALLTYPE
+gprsharp_inf_past(gpr_clock_type clock_type) {
   return gpr_inf_past(clock_type);
 }
 
-GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_convert_clock_type(gpr_timespec t, gpr_clock_type target_clock) {
+GPR_EXPORT gpr_timespec GPR_CALLTYPE
+gprsharp_convert_clock_type(gpr_timespec t, gpr_clock_type target_clock) {
   return gpr_convert_clock_type(t, target_clock);
 }
 
@@ -502,9 +514,8 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_cancel(grpc_call *call) {
   return grpc_call_cancel(call, NULL);
 }
 
-GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_cancel_with_status(grpc_call *call, grpc_status_code status,
-                                  const char *description) {
+GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_cancel_with_status(
+    grpc_call *call, grpc_status_code status, const char *description) {
   return grpc_call_cancel_with_status(call, status, description, NULL);
 }
 
@@ -512,18 +523,16 @@ GPR_EXPORT char *GPR_CALLTYPE grpcsharp_call_get_peer(grpc_call *call) {
   return grpc_call_get_peer(call);
 }
 
-GPR_EXPORT void GPR_CALLTYPE gprsharp_free(void *p) {
-  gpr_free(p);
-}
+GPR_EXPORT void GPR_CALLTYPE gprsharp_free(void *p) { gpr_free(p); }
 
 GPR_EXPORT void GPR_CALLTYPE grpcsharp_call_destroy(grpc_call *call) {
-  grpc_call_destroy(call);
+  grpc_call_unref(call);
 }
 
-GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_start_unary(grpc_call *call, grpcsharp_batch_context *ctx,
-                           const char *send_buffer, size_t send_buffer_len, uint32_t write_flags,
-                           grpc_metadata_array *initial_metadata, uint32_t initial_metadata_flags) {
+GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_unary(
+    grpc_call *call, grpcsharp_batch_context *ctx, const char *send_buffer,
+    size_t send_buffer_len, uint32_t write_flags,
+    grpc_metadata_array *initial_metadata, uint32_t initial_metadata_flags) {
   /* TODO: don't use magic number */
   grpc_op ops[6];
   memset(ops, 0, sizeof(ops));
@@ -571,11 +580,9 @@ grpcsharp_call_start_unary(grpc_call *call, grpcsharp_batch_context *ctx,
                                NULL);
 }
 
-GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_start_client_streaming(grpc_call *call,
-                                      grpcsharp_batch_context *ctx,
-                                      grpc_metadata_array *initial_metadata,
-                                      uint32_t initial_metadata_flags) {
+GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_client_streaming(
+    grpc_call *call, grpcsharp_batch_context *ctx,
+    grpc_metadata_array *initial_metadata, uint32_t initial_metadata_flags) {
   /* TODO: don't use magic number */
   grpc_op ops[4];
   memset(ops, 0, sizeof(ops));
@@ -653,11 +660,9 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_server_streaming(
                                NULL);
 }
 
-GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_start_duplex_streaming(grpc_call *call,
-                                      grpcsharp_batch_context *ctx,
-                                      grpc_metadata_array *initial_metadata,
-                                      uint32_t initial_metadata_flags) {
+GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_duplex_streaming(
+    grpc_call *call, grpcsharp_batch_context *ctx,
+    grpc_metadata_array *initial_metadata, uint32_t initial_metadata_flags) {
   /* TODO: don't use magic number */
   grpc_op ops[2];
   memset(ops, 0, sizeof(ops));
@@ -685,7 +690,7 @@ grpcsharp_call_start_duplex_streaming(grpc_call *call,
 }
 
 GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_recv_initial_metadata(
-  grpc_call *call, grpcsharp_batch_context *ctx) {
+    grpc_call *call, grpcsharp_batch_context *ctx) {
   /* TODO: don't use magic number */
   grpc_op ops[1];
   ops[0].op = GRPC_OP_RECV_INITIAL_METADATA;
@@ -695,14 +700,13 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_recv_initial_metadata(
   ops[0].reserved = NULL;
 
   return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
-    NULL);
+                               NULL);
 }
 
-GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_send_message(grpc_call *call, grpcsharp_batch_context *ctx,
-                            const char *send_buffer, size_t send_buffer_len,
-                            uint32_t write_flags,
-                            int32_t send_empty_initial_metadata) {
+GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_message(
+    grpc_call *call, grpcsharp_batch_context *ctx, const char *send_buffer,
+    size_t send_buffer_len, uint32_t write_flags,
+    int32_t send_empty_initial_metadata) {
   /* TODO: don't use magic number */
   grpc_op ops[2];
   memset(ops, 0, sizeof(ops));
@@ -719,9 +723,8 @@ grpcsharp_call_send_message(grpc_call *call, grpcsharp_batch_context *ctx,
   return grpc_call_start_batch(call, ops, nops, ctx, NULL);
 }
 
-GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_send_close_from_client(grpc_call *call,
-                                      grpcsharp_batch_context *ctx) {
+GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_close_from_client(
+    grpc_call *call, grpcsharp_batch_context *ctx) {
   /* TODO: don't use magic number */
   grpc_op ops[1];
   ops[0].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
@@ -735,14 +738,15 @@ grpcsharp_call_send_close_from_client(grpc_call *call,
 GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_status_from_server(
     grpc_call *call, grpcsharp_batch_context *ctx, grpc_status_code status_code,
     const char *status_details, size_t status_details_len,
-    grpc_metadata_array *trailing_metadata,
-    int32_t send_empty_initial_metadata, const char* optional_send_buffer,
-    size_t optional_send_buffer_len, uint32_t write_flags) {
+    grpc_metadata_array *trailing_metadata, int32_t send_empty_initial_metadata,
+    const char *optional_send_buffer, size_t optional_send_buffer_len,
+    uint32_t write_flags) {
   /* TODO: don't use magic number */
   grpc_op ops[3];
   memset(ops, 0, sizeof(ops));
   size_t nops = 1;
-  grpc_slice status_details_slice = grpc_slice_from_copied_buffer(status_details, status_details_len);
+  grpc_slice status_details_slice =
+      grpc_slice_from_copied_buffer(status_details, status_details_len);
   ops[0].op = GRPC_OP_SEND_STATUS_FROM_SERVER;
   ops[0].data.send_status_from_server.status = status_code;
   ops[0].data.send_status_from_server.status_details = &status_details_slice;
@@ -756,8 +760,8 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_status_from_server(
   ops[0].reserved = NULL;
   if (optional_send_buffer) {
     ops[nops].op = GRPC_OP_SEND_MESSAGE;
-    ctx->send_message = string_to_byte_buffer(optional_send_buffer,
-                                              optional_send_buffer_len);
+    ctx->send_message =
+        string_to_byte_buffer(optional_send_buffer, optional_send_buffer_len);
     ops[nops].data.send_message.send_message = ctx->send_message;
     ops[nops].flags = write_flags;
     ops[nops].reserved = NULL;
@@ -798,10 +802,9 @@ grpcsharp_call_start_serverside(grpc_call *call, grpcsharp_batch_context *ctx) {
                                NULL);
 }
 
-GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_send_initial_metadata(grpc_call *call,
-                                     grpcsharp_batch_context *ctx,
-                                     grpc_metadata_array *initial_metadata) {
+GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_initial_metadata(
+    grpc_call *call, grpcsharp_batch_context *ctx,
+    grpc_metadata_array *initial_metadata) {
   /* TODO: don't use magic number */
   grpc_op ops[1];
   memset(ops, 0, sizeof(ops));
@@ -818,9 +821,8 @@ grpcsharp_call_send_initial_metadata(grpc_call *call,
                                NULL);
 }
 
-GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_set_credentials(
-    grpc_call *call,
-    grpc_call_credentials *creds) {
+GPR_EXPORT grpc_call_error GPR_CALLTYPE
+grpcsharp_call_set_credentials(grpc_call *call, grpc_call_credentials *creds) {
   return grpc_call_set_credentials(call, creds);
 }
 
@@ -831,14 +833,13 @@ grpcsharp_server_create(const grpc_channel_args *args) {
   return grpc_server_create(args, NULL);
 }
 
-GPR_EXPORT void GPR_CALLTYPE
-grpcsharp_server_register_completion_queue(grpc_server *server,
-                                           grpc_completion_queue *cq) {
+GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_register_completion_queue(
+    grpc_server *server, grpc_completion_queue *cq) {
   grpc_server_register_completion_queue(server, cq, NULL);
 }
 
-GPR_EXPORT int32_t GPR_CALLTYPE
-grpcsharp_server_add_insecure_http2_port(grpc_server *server, const char *addr) {
+GPR_EXPORT int32_t GPR_CALLTYPE grpcsharp_server_add_insecure_http2_port(
+    grpc_server *server, const char *addr) {
   return grpc_server_add_insecure_http2_port(server, addr);
 }
 
@@ -846,14 +847,14 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_start(grpc_server *server) {
   grpc_server_start(server);
 }
 
-GPR_EXPORT void GPR_CALLTYPE
-grpcsharp_server_shutdown_and_notify_callback(grpc_server *server,
-                                              grpc_completion_queue *cq,
-                                              grpcsharp_batch_context *ctx) {
+GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_shutdown_and_notify_callback(
+    grpc_server *server, grpc_completion_queue *cq,
+    grpcsharp_batch_context *ctx) {
   grpc_server_shutdown_and_notify(server, cq, ctx);
 }
 
-GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_cancel_all_calls(grpc_server *server) {
+GPR_EXPORT void GPR_CALLTYPE
+grpcsharp_server_cancel_all_calls(grpc_server *server) {
   grpc_server_cancel_all_calls(server);
 }
 
@@ -864,9 +865,8 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_destroy(grpc_server *server) {
 GPR_EXPORT grpc_call_error GPR_CALLTYPE
 grpcsharp_server_request_call(grpc_server *server, grpc_completion_queue *cq,
                               grpcsharp_request_call_context *ctx) {
-  return grpc_server_request_call(
-      server, &(ctx->call), &(ctx->call_details),
-      &(ctx->request_metadata), cq, cq, ctx);
+  return grpc_server_request_call(server, &(ctx->call), &(ctx->call_details),
+                                  &(ctx->request_metadata), cq, cq, ctx);
 }
 
 /* Security */
@@ -883,8 +883,8 @@ static grpc_ssl_roots_override_result override_ssl_roots_handler(
   return GRPC_SSL_ROOTS_OVERRIDE_OK;
 }
 
-GPR_EXPORT void GPR_CALLTYPE grpcsharp_override_default_ssl_roots(
-    const char *pem_root_certs) {
+GPR_EXPORT void GPR_CALLTYPE
+grpcsharp_override_default_ssl_roots(const char *pem_root_certs) {
   /*
    * This currently wastes ~300kB of memory by keeping a copy of roots
    * in a static variable, but for desktop/server use, the overhead
@@ -911,20 +911,19 @@ grpcsharp_ssl_credentials_create(const char *pem_root_certs,
   }
 }
 
-GPR_EXPORT void GPR_CALLTYPE grpcsharp_channel_credentials_release(
-    grpc_channel_credentials *creds) {
+GPR_EXPORT void GPR_CALLTYPE
+grpcsharp_channel_credentials_release(grpc_channel_credentials *creds) {
   grpc_channel_credentials_release(creds);
 }
 
-GPR_EXPORT void GPR_CALLTYPE grpcsharp_call_credentials_release(
-    grpc_call_credentials *creds) {
+GPR_EXPORT void GPR_CALLTYPE
+grpcsharp_call_credentials_release(grpc_call_credentials *creds) {
   grpc_call_credentials_release(creds);
 }
 
-GPR_EXPORT grpc_channel *GPR_CALLTYPE
-grpcsharp_secure_channel_create(grpc_channel_credentials *creds,
-                                const char *target,
-                                const grpc_channel_args *args) {
+GPR_EXPORT grpc_channel *GPR_CALLTYPE grpcsharp_secure_channel_create(
+    grpc_channel_credentials *creds, const char *target,
+    const grpc_channel_args *args) {
   return grpc_secure_channel_create(creds, target, args, NULL);
 }
 
@@ -957,36 +956,36 @@ grpcsharp_ssl_server_credentials_create(
   return creds;
 }
 
-GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_credentials_release(
-    grpc_server_credentials *creds) {
+GPR_EXPORT void GPR_CALLTYPE
+grpcsharp_server_credentials_release(grpc_server_credentials *creds) {
   grpc_server_credentials_release(creds);
 }
 
-GPR_EXPORT int32_t GPR_CALLTYPE
-grpcsharp_server_add_secure_http2_port(grpc_server *server, const char *addr,
-                                       grpc_server_credentials *creds) {
+GPR_EXPORT int32_t GPR_CALLTYPE grpcsharp_server_add_secure_http2_port(
+    grpc_server *server, const char *addr, grpc_server_credentials *creds) {
   return grpc_server_add_secure_http2_port(server, addr, creds);
 }
 
-GPR_EXPORT grpc_channel_credentials *GPR_CALLTYPE grpcsharp_composite_channel_credentials_create(
-  grpc_channel_credentials *channel_creds,
-  grpc_call_credentials *call_creds) {
-  return grpc_composite_channel_credentials_create(channel_creds, call_creds, NULL);
+GPR_EXPORT grpc_channel_credentials *GPR_CALLTYPE
+grpcsharp_composite_channel_credentials_create(
+    grpc_channel_credentials *channel_creds,
+    grpc_call_credentials *call_creds) {
+  return grpc_composite_channel_credentials_create(channel_creds, call_creds,
+                                                   NULL);
 }
 
-GPR_EXPORT grpc_call_credentials *GPR_CALLTYPE grpcsharp_composite_call_credentials_create(
-  grpc_call_credentials *creds1,
-  grpc_call_credentials *creds2) {
+GPR_EXPORT grpc_call_credentials *GPR_CALLTYPE
+grpcsharp_composite_call_credentials_create(grpc_call_credentials *creds1,
+                                            grpc_call_credentials *creds2) {
   return grpc_composite_call_credentials_create(creds1, creds2, NULL);
 }
 
-
 /* Metadata credentials plugin */
 
 GPR_EXPORT void GPR_CALLTYPE grpcsharp_metadata_credentials_notify_from_plugin(
-    grpc_credentials_plugin_metadata_cb cb,
-    void *user_data, grpc_metadata_array *metadata,
-  grpc_status_code status, const char *error_details) {
+    grpc_credentials_plugin_metadata_cb cb, void *user_data,
+    grpc_metadata_array *metadata, grpc_status_code status,
+    const char *error_details) {
   if (metadata) {
     cb(user_data, metadata->metadata, metadata->count, status, error_details);
   } else {
@@ -995,16 +994,17 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_metadata_credentials_notify_from_plugin(
 }
 
 typedef void(GPR_CALLTYPE *grpcsharp_metadata_interceptor_func)(
-  void *state, const char *service_url, const char *method_name,
-  grpc_credentials_plugin_metadata_cb cb,
-  void *user_data, int32_t is_destroy);
+    void *state, const char *service_url, const char *method_name,
+    grpc_credentials_plugin_metadata_cb cb, void *user_data,
+    int32_t is_destroy);
 
 static void grpcsharp_get_metadata_handler(
     void *state, grpc_auth_metadata_context context,
     grpc_credentials_plugin_metadata_cb cb, void *user_data) {
   grpcsharp_metadata_interceptor_func interceptor =
       (grpcsharp_metadata_interceptor_func)(intptr_t)state;
-  interceptor(state, context.service_url, context.method_name, cb, user_data, 0);
+  interceptor(state, context.service_url, context.method_name, cb, user_data,
+              0);
 }
 
 static void grpcsharp_metadata_credentials_destroy_handler(void *state) {
@@ -1013,16 +1013,45 @@ static void grpcsharp_metadata_credentials_destroy_handler(void *state) {
   interceptor(state, NULL, NULL, NULL, NULL, 1);
 }
 
-GPR_EXPORT grpc_call_credentials *GPR_CALLTYPE grpcsharp_metadata_credentials_create_from_plugin(
-  grpcsharp_metadata_interceptor_func metadata_interceptor) {
+GPR_EXPORT grpc_call_credentials *GPR_CALLTYPE
+grpcsharp_metadata_credentials_create_from_plugin(
+    grpcsharp_metadata_interceptor_func metadata_interceptor) {
   grpc_metadata_credentials_plugin plugin;
   plugin.get_metadata = grpcsharp_get_metadata_handler;
   plugin.destroy = grpcsharp_metadata_credentials_destroy_handler;
-  plugin.state = (void*)(intptr_t)metadata_interceptor;
+  plugin.state = (void *)(intptr_t)metadata_interceptor;
   plugin.type = "";
   return grpc_metadata_credentials_create_from_plugin(plugin, NULL);
 }
 
+/* Auth context */
+
+GPR_EXPORT grpc_auth_context *GPR_CALLTYPE
+grpcsharp_call_auth_context(grpc_call *call) {
+  return grpc_call_auth_context(call);
+}
+
+GPR_EXPORT const char *GPR_CALLTYPE
+grpcsharp_auth_context_peer_identity_property_name(
+    const grpc_auth_context *ctx) {
+  return grpc_auth_context_peer_identity_property_name(ctx);
+}
+
+GPR_EXPORT grpc_auth_property_iterator GPR_CALLTYPE
+grpcsharp_auth_context_property_iterator(const grpc_auth_context *ctx) {
+  return grpc_auth_context_property_iterator(ctx);
+}
+
+GPR_EXPORT const grpc_auth_property *GPR_CALLTYPE
+grpcsharp_auth_property_iterator_next(grpc_auth_property_iterator *it) {
+  return grpc_auth_property_iterator_next(it);
+}
+
+GPR_EXPORT void GPR_CALLTYPE
+grpcsharp_auth_context_release(grpc_auth_context *ctx) {
+  grpc_auth_context_release(ctx);
+}
+
 /* Logging */
 
 typedef void(GPR_CALLTYPE *grpcsharp_log_func)(const char *file, int32_t line,
diff --git a/src/csharp/tests.json b/src/csharp/tests.json
index 4ce6769eee5f61e74c2d80bc2581e159783bac5e..707d140f62cd109154941f712aab9e3dd18952bb 100644
--- a/src/csharp/tests.json
+++ b/src/csharp/tests.json
@@ -8,6 +8,8 @@
     "Grpc.Core.Internal.Tests.MetadataArraySafeHandleTest",
     "Grpc.Core.Internal.Tests.TimespecTest",
     "Grpc.Core.Tests.AppDomainUnloadTest",
+    "Grpc.Core.Tests.AuthContextTest",
+    "Grpc.Core.Tests.AuthPropertyTest",
     "Grpc.Core.Tests.CallCredentialsTest",
     "Grpc.Core.Tests.CallOptionsTest",
     "Grpc.Core.Tests.ChannelCredentialsTest",
@@ -20,7 +22,6 @@
     "Grpc.Core.Tests.HalfcloseTest",
     "Grpc.Core.Tests.MarshallingErrorsTest",
     "Grpc.Core.Tests.MetadataTest",
-    "Grpc.Core.Tests.NUnitVersionTest",
     "Grpc.Core.Tests.PerformanceTest",
     "Grpc.Core.Tests.PInvokeTest",
     "Grpc.Core.Tests.ResponseHeadersTest",
diff --git a/src/node/ext/byte_buffer.cc b/src/node/ext/byte_buffer.cc
index 7d6fb198603b75f384cdfb80905e4be8931f40d4..470c7ed90198b67b7df2aec8bce70a7da8064f24 100644
--- a/src/node/ext/byte_buffer.cc
+++ b/src/node/ext/byte_buffer.cc
@@ -33,10 +33,10 @@
 
 #include <string.h>
 
-#include <node.h>
 #include <nan.h>
-#include "grpc/grpc.h"
+#include <node.h>
 #include "grpc/byte_buffer_reader.h"
+#include "grpc/grpc.h"
 #include "grpc/slice.h"
 
 #include "byte_buffer.h"
@@ -45,6 +45,7 @@
 namespace grpc {
 namespace node {
 
+using Nan::Callback;
 using Nan::MaybeLocal;
 
 using v8::Function;
@@ -62,7 +63,11 @@ grpc_byte_buffer *BufferToByteBuffer(Local<Value> buffer) {
 }
 
 namespace {
-void delete_buffer(char *data, void *hint) { delete[] data; }
+void delete_buffer(char *data, void *hint) {
+  grpc_slice *slice = static_cast<grpc_slice *>(hint);
+  grpc_slice_unref(*slice);
+  delete slice;
+}
 }
 
 Local<Value> ByteBufferToBuffer(grpc_byte_buffer *buffer) {
@@ -75,31 +80,15 @@ Local<Value> ByteBufferToBuffer(grpc_byte_buffer *buffer) {
     Nan::ThrowError("Error initializing byte buffer reader.");
     return scope.Escape(Nan::Undefined());
   }
-  grpc_slice slice = grpc_byte_buffer_reader_readall(&reader);
-  size_t length = GRPC_SLICE_LENGTH(slice);
-  char *result = new char[length];
-  memcpy(result, GRPC_SLICE_START_PTR(slice), length);
-  grpc_slice_unref(slice);
-  return scope.Escape(MakeFastBuffer(
-      Nan::NewBuffer(result, length, delete_buffer, NULL).ToLocalChecked()));
+  grpc_slice *slice = new grpc_slice;
+  *slice = grpc_byte_buffer_reader_readall(&reader);
+  grpc_byte_buffer_reader_destroy(&reader);
+  char *result = reinterpret_cast<char *>(GRPC_SLICE_START_PTR(*slice));
+  size_t length = GRPC_SLICE_LENGTH(*slice);
+  Local<Value> buf =
+      Nan::NewBuffer(result, length, delete_buffer, slice).ToLocalChecked();
+  return scope.Escape(buf);
 }
 
-Local<Value> MakeFastBuffer(Local<Value> slowBuffer) {
-  Nan::EscapableHandleScope scope;
-  Local<Object> globalObj = Nan::GetCurrentContext()->Global();
-  MaybeLocal<Value> constructorValue = Nan::Get(
-      globalObj, Nan::New("Buffer").ToLocalChecked());
-  Local<Function> bufferConstructor = Local<Function>::Cast(
-      constructorValue.ToLocalChecked());
-  const int argc = 3;
-  Local<Value> consArgs[argc] = {
-    slowBuffer,
-    Nan::New<Number>(::node::Buffer::Length(slowBuffer)),
-    Nan::New<Number>(0)
-  };
-  MaybeLocal<Object> fastBuffer = Nan::NewInstance(bufferConstructor,
-                                                   argc, consArgs);
-  return scope.Escape(fastBuffer.ToLocalChecked());
-}
 }  // namespace node
 }  // namespace grpc
diff --git a/src/node/ext/byte_buffer.h b/src/node/ext/byte_buffer.h
index 55bc0ab3771e989b96f0f8b9e20bc2c4d3cb1836..6cb7a2601bd97b6779cc5cd8f866d13206cc0aca 100644
--- a/src/node/ext/byte_buffer.h
+++ b/src/node/ext/byte_buffer.h
@@ -36,8 +36,8 @@
 
 #include <string.h>
 
-#include <node.h>
 #include <nan.h>
+#include <node.h>
 #include "grpc/grpc.h"
 
 namespace grpc {
@@ -50,10 +50,6 @@ grpc_byte_buffer *BufferToByteBuffer(v8::Local<v8::Value> buffer);
 /* Convert a grpc_byte_buffer to a Node.js Buffer */
 v8::Local<v8::Value> ByteBufferToBuffer(grpc_byte_buffer *buffer);
 
-/* Convert a ::node::Buffer to a fast Buffer, as defined in the Node
-   Buffer documentation */
-v8::Local<v8::Value> MakeFastBuffer(v8::Local<v8::Value> slowBuffer);
-
 }  // namespace node
 }  // namespace grpc
 
diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc
index 244546d3d785dfe919af05f7fc93ec4e30df78fb..49179ab359688083a4035a94f05f0c27fc9585ba 100644
--- a/src/node/ext/call.cc
+++ b/src/node/ext/call.cc
@@ -31,23 +31,22 @@
  *
  */
 
+#include <map>
 #include <memory>
 #include <vector>
-#include <map>
 
 #include <node.h>
 
-#include "grpc/support/log.h"
-#include "grpc/grpc.h"
-#include "grpc/grpc_security.h"
-#include "grpc/support/alloc.h"
-#include "grpc/support/time.h"
 #include "byte_buffer.h"
 #include "call.h"
+#include "call_credentials.h"
 #include "channel.h"
 #include "completion_queue.h"
-#include "completion_queue_async_worker.h"
-#include "call_credentials.h"
+#include "grpc/grpc.h"
+#include "grpc/grpc_security.h"
+#include "grpc/support/alloc.h"
+#include "grpc/support/log.h"
+#include "grpc/support/time.h"
 #include "slice.h"
 #include "timeval.h"
 
@@ -99,30 +98,31 @@ Local<Value> nanErrorWithCode(const char *msg, grpc_call_error code) {
 
 bool CreateMetadataArray(Local<Object> metadata, grpc_metadata_array *array) {
   HandleScope scope;
-  grpc_metadata_array_init(array);
   Local<Array> keys = Nan::GetOwnPropertyNames(metadata).ToLocalChecked();
   for (unsigned int i = 0; i < keys->Length(); i++) {
-    Local<String> current_key = Nan::To<String>(
-        Nan::Get(keys, i).ToLocalChecked()).ToLocalChecked();
+    Local<String> current_key =
+        Nan::To<String>(Nan::Get(keys, i).ToLocalChecked()).ToLocalChecked();
     Local<Value> value_array = Nan::Get(metadata, current_key).ToLocalChecked();
     if (!value_array->IsArray()) {
       return false;
     }
     array->capacity += Local<Array>::Cast(value_array)->Length();
   }
-  array->metadata = reinterpret_cast<grpc_metadata*>(
-      gpr_malloc(array->capacity * sizeof(grpc_metadata)));
+  array->metadata = reinterpret_cast<grpc_metadata *>(
+      gpr_zalloc(array->capacity * sizeof(grpc_metadata)));
   for (unsigned int i = 0; i < keys->Length(); i++) {
     Local<String> current_key(Nan::To<String>(keys->Get(i)).ToLocalChecked());
-    Local<Array> values = Local<Array>::Cast(
-        Nan::Get(metadata, current_key).ToLocalChecked());
-    grpc_slice key_slice = grpc_slice_intern(CreateSliceFromString(current_key));
+    Local<Array> values =
+        Local<Array>::Cast(Nan::Get(metadata, current_key).ToLocalChecked());
+    grpc_slice key_slice = CreateSliceFromString(current_key);
+    grpc_slice key_intern_slice = grpc_slice_intern(key_slice);
+    grpc_slice_unref(key_slice);
     for (unsigned int j = 0; j < values->Length(); j++) {
       Local<Value> value = Nan::Get(values, j).ToLocalChecked();
       grpc_metadata *current = &array->metadata[array->count];
-      current->key = key_slice;
+      current->key = key_intern_slice;
       // Only allow binary headers for "-bin" keys
-      if (grpc_is_binary_header(key_slice)) {
+      if (grpc_is_binary_header(key_intern_slice)) {
         if (::node::Buffer::HasInstance(value)) {
           current->value = CreateSliceFromBuffer(value);
         } else {
@@ -142,13 +142,21 @@ bool CreateMetadataArray(Local<Object> metadata, grpc_metadata_array *array) {
   return true;
 }
 
+void DestroyMetadataArray(grpc_metadata_array *array) {
+  for (size_t i = 0; i < array->count; i++) {
+    // Don't unref keys because they are interned
+    grpc_slice_unref(array->metadata[i].value);
+  }
+  grpc_metadata_array_destroy(array);
+}
+
 Local<Value> ParseMetadata(const grpc_metadata_array *metadata_array) {
   EscapableHandleScope scope;
   grpc_metadata *metadata_elements = metadata_array->metadata;
   size_t length = metadata_array->count;
   Local<Object> metadata_object = Nan::New<Object>();
   for (unsigned int i = 0; i < length; i++) {
-    grpc_metadata* elem = &metadata_elements[i];
+    grpc_metadata *elem = &metadata_elements[i];
     // TODO(murgatroid99): Use zero-copy string construction instead
     Local<String> key_string = CopyStringFromSlice(elem->key);
     Local<Array> array;
@@ -174,11 +182,12 @@ Local<Value> Op::GetOpType() const {
   return scope.Escape(Nan::New(GetTypeString()).ToLocalChecked());
 }
 
-Op::~Op() {
-}
+Op::~Op() {}
 
 class SendMetadataOp : public Op {
  public:
+  SendMetadataOp() { grpc_metadata_array_init(&send_metadata); }
+  ~SendMetadataOp() { DestroyMetadataArray(&send_metadata); }
   Local<Value> GetNodeValue() const {
     EscapableHandleScope scope;
     return scope.Escape(Nan::True());
@@ -187,33 +196,30 @@ class SendMetadataOp : public Op {
     if (!value->IsObject()) {
       return false;
     }
-    grpc_metadata_array array;
     MaybeLocal<Object> maybe_metadata = Nan::To<Object>(value);
     if (maybe_metadata.IsEmpty()) {
       return false;
     }
-    if (!CreateMetadataArray(maybe_metadata.ToLocalChecked(),
-                             &array)) {
+    if (!CreateMetadataArray(maybe_metadata.ToLocalChecked(), &send_metadata)) {
       return false;
     }
-    out->data.send_initial_metadata.count = array.count;
-    out->data.send_initial_metadata.metadata = array.metadata;
+    out->data.send_initial_metadata.count = send_metadata.count;
+    out->data.send_initial_metadata.metadata = send_metadata.metadata;
     return true;
   }
-  bool IsFinalOp() {
-    return false;
-  }
+  bool IsFinalOp() { return false; }
+  void OnComplete(bool success) {}
+
  protected:
-  std::string GetTypeString() const {
-    return "send_metadata";
-  }
+  std::string GetTypeString() const { return "send_metadata"; }
+
+ private:
+  grpc_metadata_array send_metadata;
 };
 
 class SendMessageOp : public Op {
  public:
-  SendMessageOp() {
-    send_message = NULL;
-  }
+  SendMessageOp() { send_message = NULL; }
   ~SendMessageOp() {
     if (send_message != NULL) {
       grpc_byte_buffer_destroy(send_message);
@@ -228,8 +234,8 @@ class SendMessageOp : public Op {
       return false;
     }
     Local<Object> object_value = Nan::To<Object>(value).ToLocalChecked();
-    MaybeLocal<Value> maybe_flag_value = Nan::Get(
-        object_value, Nan::New("grpcWriteFlags").ToLocalChecked());
+    MaybeLocal<Value> maybe_flag_value =
+        Nan::Get(object_value, Nan::New("grpcWriteFlags").ToLocalChecked());
     if (!maybe_flag_value.IsEmpty()) {
       Local<Value> flag_value = maybe_flag_value.ToLocalChecked();
       if (flag_value->IsUint32()) {
@@ -241,13 +247,13 @@ class SendMessageOp : public Op {
     out->data.send_message.send_message = send_message;
     return true;
   }
-  bool IsFinalOp() {
-    return false;
-  }
+
+  bool IsFinalOp() { return false; }
+  void OnComplete(bool success) {}
+
  protected:
-  std::string GetTypeString() const {
-    return "send_message";
-  }
+  std::string GetTypeString() const { return "send_message"; }
+
  private:
   grpc_byte_buffer *send_message;
 };
@@ -258,22 +264,21 @@ class SendClientCloseOp : public Op {
     EscapableHandleScope scope;
     return scope.Escape(Nan::True());
   }
-  bool ParseOp(Local<Value> value, grpc_op *out) {
-    return true;
-  }
-  bool IsFinalOp() {
-    return false;
-  }
+
+  bool ParseOp(Local<Value> value, grpc_op *out) { return true; }
+  bool IsFinalOp() { return false; }
+  void OnComplete(bool success) {}
+
  protected:
-  std::string GetTypeString() const {
-    return "client_close";
-  }
+  std::string GetTypeString() const { return "client_close"; }
 };
 
 class SendServerStatusOp : public Op {
  public:
+  SendServerStatusOp() { grpc_metadata_array_init(&status_metadata); }
   ~SendServerStatusOp() {
     grpc_slice_unref(details);
+    DestroyMetadataArray(&status_metadata);
   }
   Local<Value> GetNodeValue() const {
     EscapableHandleScope scope;
@@ -284,18 +289,18 @@ class SendServerStatusOp : public Op {
       return false;
     }
     Local<Object> server_status = Nan::To<Object>(value).ToLocalChecked();
-    MaybeLocal<Value> maybe_metadata = Nan::Get(
-        server_status, Nan::New("metadata").ToLocalChecked());
+    MaybeLocal<Value> maybe_metadata =
+        Nan::Get(server_status, Nan::New("metadata").ToLocalChecked());
     if (maybe_metadata.IsEmpty()) {
       return false;
     }
     if (!maybe_metadata.ToLocalChecked()->IsObject()) {
       return false;
     }
-    Local<Object> metadata = Nan::To<Object>(
-        maybe_metadata.ToLocalChecked()).ToLocalChecked();
-    MaybeLocal<Value> maybe_code = Nan::Get(server_status,
-                                            Nan::New("code").ToLocalChecked());
+    Local<Object> metadata =
+        Nan::To<Object>(maybe_metadata.ToLocalChecked()).ToLocalChecked();
+    MaybeLocal<Value> maybe_code =
+        Nan::Get(server_status, Nan::New("code").ToLocalChecked());
     if (maybe_code.IsEmpty()) {
       return false;
     }
@@ -303,49 +308,45 @@ class SendServerStatusOp : public Op {
       return false;
     }
     uint32_t code = Nan::To<uint32_t>(maybe_code.ToLocalChecked()).FromJust();
-    MaybeLocal<Value> maybe_details = Nan::Get(
-        server_status, Nan::New("details").ToLocalChecked());
+    MaybeLocal<Value> maybe_details =
+        Nan::Get(server_status, Nan::New("details").ToLocalChecked());
     if (maybe_details.IsEmpty()) {
       return false;
     }
     if (!maybe_details.ToLocalChecked()->IsString()) {
       return false;
     }
-    Local<String> details = Nan::To<String>(
-        maybe_details.ToLocalChecked()).ToLocalChecked();
-    grpc_metadata_array array;
-    if (!CreateMetadataArray(metadata, &array)) {
+    Local<String> details =
+        Nan::To<String>(maybe_details.ToLocalChecked()).ToLocalChecked();
+    if (!CreateMetadataArray(metadata, &status_metadata)) {
       return false;
     }
-    out->data.send_status_from_server.trailing_metadata_count = array.count;
-    out->data.send_status_from_server.trailing_metadata = array.metadata;
+    out->data.send_status_from_server.trailing_metadata_count =
+        status_metadata.count;
+    out->data.send_status_from_server.trailing_metadata =
+        status_metadata.metadata;
     out->data.send_status_from_server.status =
         static_cast<grpc_status_code>(code);
     this->details = CreateSliceFromString(details);
     out->data.send_status_from_server.status_details = &this->details;
     return true;
   }
-  bool IsFinalOp() {
-    return true;
-  }
+  bool IsFinalOp() { return true; }
+  void OnComplete(bool success) {}
+
  protected:
-  std::string GetTypeString() const {
-    return "send_status";
-  }
+  std::string GetTypeString() const { return "send_status"; }
 
  private:
   grpc_slice details;
+  grpc_metadata_array status_metadata;
 };
 
 class GetMetadataOp : public Op {
  public:
-  GetMetadataOp() {
-    grpc_metadata_array_init(&recv_metadata);
-  }
+  GetMetadataOp() { grpc_metadata_array_init(&recv_metadata); }
 
-  ~GetMetadataOp() {
-    grpc_metadata_array_destroy(&recv_metadata);
-  }
+  ~GetMetadataOp() { grpc_metadata_array_destroy(&recv_metadata); }
 
   Local<Value> GetNodeValue() const {
     EscapableHandleScope scope;
@@ -356,14 +357,11 @@ class GetMetadataOp : public Op {
     out->data.recv_initial_metadata.recv_initial_metadata = &recv_metadata;
     return true;
   }
-  bool IsFinalOp() {
-    return false;
-  }
+  bool IsFinalOp() { return false; }
+  void OnComplete(bool success) {}
 
  protected:
-  std::string GetTypeString() const {
-    return "metadata";
-  }
+  std::string GetTypeString() const { return "metadata"; }
 
  private:
   grpc_metadata_array recv_metadata;
@@ -371,9 +369,7 @@ class GetMetadataOp : public Op {
 
 class ReadMessageOp : public Op {
  public:
-  ReadMessageOp() {
-    recv_message = NULL;
-  }
+  ReadMessageOp() { recv_message = NULL; }
   ~ReadMessageOp() {
     if (recv_message != NULL) {
       grpc_byte_buffer_destroy(recv_message);
@@ -388,14 +384,11 @@ class ReadMessageOp : public Op {
     out->data.recv_message.recv_message = &recv_message;
     return true;
   }
-  bool IsFinalOp() {
-    return false;
-  }
+  bool IsFinalOp() { return false; }
+  void OnComplete(bool success) {}
 
  protected:
-  std::string GetTypeString() const {
-    return "read";
-  }
+  std::string GetTypeString() const { return "read"; }
 
  private:
   grpc_byte_buffer *recv_message;
@@ -403,13 +396,9 @@ class ReadMessageOp : public Op {
 
 class ClientStatusOp : public Op {
  public:
-  ClientStatusOp() {
-    grpc_metadata_array_init(&metadata_array);
-  }
+  ClientStatusOp() { grpc_metadata_array_init(&metadata_array); }
 
-  ~ClientStatusOp() {
-    grpc_metadata_array_destroy(&metadata_array);
-  }
+  ~ClientStatusOp() { grpc_metadata_array_destroy(&metadata_array); }
 
   bool ParseOp(Local<Value> value, grpc_op *out) {
     out->data.recv_status_on_client.trailing_metadata = &metadata_array;
@@ -422,20 +411,19 @@ class ClientStatusOp : public Op {
     EscapableHandleScope scope;
     Local<Object> status_obj = Nan::New<Object>();
     Nan::Set(status_obj, Nan::New("code").ToLocalChecked(),
-                    Nan::New<Number>(status));
+             Nan::New<Number>(status));
     Nan::Set(status_obj, Nan::New("details").ToLocalChecked(),
-               CopyStringFromSlice(status_details));
+             CopyStringFromSlice(status_details));
     Nan::Set(status_obj, Nan::New("metadata").ToLocalChecked(),
              ParseMetadata(&metadata_array));
     return scope.Escape(status_obj);
   }
-  bool IsFinalOp() {
-    return true;
-  }
+  bool IsFinalOp() { return true; }
+  void OnComplete(bool success) {}
+
  protected:
-  std::string GetTypeString() const {
-    return "status";
-  }
+  std::string GetTypeString() const { return "status"; }
+
  private:
   grpc_metadata_array metadata_array;
   grpc_status_code status;
@@ -453,21 +441,20 @@ class ServerCloseResponseOp : public Op {
     out->data.recv_close_on_server.cancelled = &cancelled;
     return true;
   }
-  bool IsFinalOp() {
-    return false;
-  }
+  bool IsFinalOp() { return false; }
+  void OnComplete(bool success) {}
 
  protected:
-  std::string GetTypeString() const {
-    return "cancelled";
-  }
+  std::string GetTypeString() const { return "cancelled"; }
 
  private:
   int cancelled;
 };
 
-tag::tag(Callback *callback, OpVec *ops, Call *call) :
-    callback(callback), ops(ops), call(call){
+tag::tag(Callback *callback, OpVec *ops, Call *call, Local<Value> call_value)
+    : callback(callback), ops(ops), call(call) {
+  HandleScope scope;
+  call_persist.Reset(call_value);
 }
 
 tag::~tag() {
@@ -475,36 +462,36 @@ tag::~tag() {
   delete ops;
 }
 
-Local<Value> GetTagNodeValue(void *tag) {
-  EscapableHandleScope scope;
+void CompleteTag(void *tag, const char *error_message) {
+  HandleScope scope;
   struct tag *tag_struct = reinterpret_cast<struct tag *>(tag);
-  Local<Object> tag_obj = Nan::New<Object>();
-  for (vector<unique_ptr<Op> >::iterator it = tag_struct->ops->begin();
-       it != tag_struct->ops->end(); ++it) {
-    Op *op_ptr = it->get();
-    Nan::Set(tag_obj, op_ptr->GetOpType(), op_ptr->GetNodeValue());
+  Callback *callback = tag_struct->callback;
+  if (error_message == NULL) {
+    Local<Object> tag_obj = Nan::New<Object>();
+    for (vector<unique_ptr<Op> >::iterator it = tag_struct->ops->begin();
+         it != tag_struct->ops->end(); ++it) {
+      Op *op_ptr = it->get();
+      Nan::Set(tag_obj, op_ptr->GetOpType(), op_ptr->GetNodeValue());
+    }
+    Local<Value> argv[] = {Nan::Null(), tag_obj};
+    callback->Call(2, argv);
+  } else {
+    Local<Value> argv[] = {Nan::Error(error_message)};
+    callback->Call(1, argv);
   }
-  return scope.Escape(tag_obj);
-}
-
-Callback *GetTagCallback(void *tag) {
-  struct tag *tag_struct = reinterpret_cast<struct tag *>(tag);
-  return tag_struct->callback;
-}
-
-void CompleteTag(void *tag) {
-  struct tag *tag_struct = reinterpret_cast<struct tag *>(tag);
+  bool success = (error_message == NULL);
   bool is_final_op = false;
-  if (tag_struct->call == NULL) {
-    return;
-  }
   for (vector<unique_ptr<Op> >::iterator it = tag_struct->ops->begin();
        it != tag_struct->ops->end(); ++it) {
     Op *op_ptr = it->get();
+    op_ptr->OnComplete(success);
     if (op_ptr->IsFinalOp()) {
       is_final_op = true;
     }
   }
+  if (tag_struct->call == NULL) {
+    return;
+  }
   tag_struct->call->CompleteBatch(is_final_op);
 }
 
@@ -513,17 +500,18 @@ void DestroyTag(void *tag) {
   delete tag_struct;
 }
 
-Call::Call(grpc_call *call) : wrapped_call(call),
-                              pending_batches(0),
-                              has_final_op_completed(false) {
-}
-
-Call::~Call() {
-  if (wrapped_call != NULL) {
-    grpc_call_destroy(wrapped_call);
+void Call::DestroyCall() {
+  if (this->wrapped_call != NULL) {
+    grpc_call_unref(this->wrapped_call);
+    this->wrapped_call = NULL;
   }
 }
 
+Call::Call(grpc_call *call)
+    : wrapped_call(call), pending_batches(0), has_final_op_completed(false) {}
+
+Call::~Call() { DestroyCall(); }
+
 void Call::Init(Local<Object> exports) {
   HandleScope scope;
   Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
@@ -551,10 +539,10 @@ Local<Value> Call::WrapStruct(grpc_call *call) {
     return scope.Escape(Nan::Null());
   }
   const int argc = 1;
-  Local<Value> argv[argc] = {Nan::New<External>(
-      reinterpret_cast<void *>(call))};
-  MaybeLocal<Object> maybe_instance = Nan::NewInstance(
-      constructor->GetFunction(), argc, argv);
+  Local<Value> argv[argc] = {
+      Nan::New<External>(reinterpret_cast<void *>(call))};
+  MaybeLocal<Object> maybe_instance =
+      Nan::NewInstance(constructor->GetFunction(), argc, argv);
   if (maybe_instance.IsEmpty()) {
     return scope.Escape(Nan::Null());
   } else {
@@ -568,19 +556,25 @@ void Call::CompleteBatch(bool is_final_op) {
   }
   this->pending_batches--;
   if (this->has_final_op_completed && this->pending_batches == 0) {
-    grpc_call_destroy(this->wrapped_call);
-    this->wrapped_call = NULL;
+    this->DestroyCall();
   }
 }
 
 NAN_METHOD(Call::New) {
+  /* Arguments:
+   * 0: Channel to make the call on
+   * 1: Method
+   * 2: Deadline
+   * 3: host
+   * 4: parent Call
+   * 5: propagation flags
+   */
   if (info.IsConstructCall()) {
     Call *call;
     if (info[0]->IsExternal()) {
       Local<External> ext = info[0].As<External>();
       // This option is used for wrapping an existing call
-      grpc_call *call_value =
-          reinterpret_cast<grpc_call *>(ext->Value());
+      grpc_call *call_value = reinterpret_cast<grpc_call *>(ext->Value());
       call = new Call(call_value);
     } else {
       if (!Channel::HasInstance(info[0])) {
@@ -596,8 +590,8 @@ NAN_METHOD(Call::New) {
       // These arguments are at the end because they are optional
       grpc_call *parent_call = NULL;
       if (Call::HasInstance(info[4])) {
-        Call *parent_obj = ObjectWrap::Unwrap<Call>(
-            Nan::To<Object>(info[4]).ToLocalChecked());
+        Call *parent_obj =
+            ObjectWrap::Unwrap<Call>(Nan::To<Object>(info[4]).ToLocalChecked());
         parent_call = parent_obj->wrapped_call;
       } else if (!(info[4]->IsUndefined() || info[4]->IsNull())) {
         return Nan::ThrowTypeError(
@@ -618,25 +612,24 @@ NAN_METHOD(Call::New) {
       double deadline = Nan::To<double>(info[2]).FromJust();
       grpc_channel *wrapped_channel = channel->GetWrappedChannel();
       grpc_call *wrapped_call;
+      grpc_slice method =
+          CreateSliceFromString(Nan::To<String>(info[1]).ToLocalChecked());
       if (info[3]->IsString()) {
         grpc_slice *host = new grpc_slice;
-        *host = CreateSliceFromString(
-            Nan::To<String>(info[3]).ToLocalChecked());
+        *host =
+            CreateSliceFromString(Nan::To<String>(info[3]).ToLocalChecked());
         wrapped_call = grpc_channel_create_call(
-            wrapped_channel, parent_call, propagate_flags,
-            GetCompletionQueue(), CreateSliceFromString(
-                Nan::To<String>(info[1]).ToLocalChecked()),
-            host, MillisecondsToTimespec(deadline), NULL);
+            wrapped_channel, parent_call, propagate_flags, GetCompletionQueue(),
+            method, host, MillisecondsToTimespec(deadline), NULL);
         delete host;
       } else if (info[3]->IsUndefined() || info[3]->IsNull()) {
         wrapped_call = grpc_channel_create_call(
-            wrapped_channel, parent_call, propagate_flags,
-            GetCompletionQueue(), CreateSliceFromString(
-                Nan::To<String>(info[1]).ToLocalChecked()),
-            NULL, MillisecondsToTimespec(deadline), NULL);
+            wrapped_channel, parent_call, propagate_flags, GetCompletionQueue(),
+            method, NULL, MillisecondsToTimespec(deadline), NULL);
       } else {
         return Nan::ThrowTypeError("Call's fourth argument must be a string");
       }
+      grpc_slice_unref(method);
       call = new Call(wrapped_call);
       Nan::Set(info.This(), Nan::New("channel_").ToLocalChecked(),
                channel_object);
@@ -646,8 +639,8 @@ NAN_METHOD(Call::New) {
   } else {
     const int argc = 4;
     Local<Value> argv[argc] = {info[0], info[1], info[2], info[3]};
-    MaybeLocal<Object> maybe_instance = Nan::NewInstance(
-        constructor->GetFunction(), argc, argv);
+    MaybeLocal<Object> maybe_instance =
+        Nan::NewInstance(constructor->GetFunction(), argc, argv);
     if (maybe_instance.IsEmpty()) {
       // There's probably a pending exception
       return;
@@ -720,8 +713,8 @@ NAN_METHOD(Call::StartBatch) {
   }
   Callback *callback = new Callback(callback_func);
   grpc_call_error error = grpc_call_start_batch(
-      call->wrapped_call, &ops[0], nops, new struct tag(
-          callback, op_vector.release(), call), NULL);
+      call->wrapped_call, &ops[0], nops,
+      new struct tag(callback, op_vector.release(), call, info.This()), NULL);
   if (error != GRPC_CALL_OK) {
     return Nan::ThrowError(nanErrorWithCode("startBatch failed", error));
   }
@@ -754,8 +747,8 @@ NAN_METHOD(Call::CancelWithStatus) {
         "cancelWithStatus's second argument must be a string");
   }
   Call *call = ObjectWrap::Unwrap<Call>(info.This());
-  grpc_status_code code = static_cast<grpc_status_code>(
-      Nan::To<uint32_t>(info[0]).FromJust());
+  grpc_status_code code =
+      static_cast<grpc_status_code>(Nan::To<uint32_t>(info[0]).FromJust());
   if (code == GRPC_STATUS_OK) {
     return Nan::ThrowRangeError(
         "cancelWithStatus cannot be called with OK status");
diff --git a/src/node/ext/call.h b/src/node/ext/call.h
index cffff00fce4d3e5165211ca2553d1a20d861192a..0bd24f56a9ac6f5b9a82e0c2937872c29bb5a338 100644
--- a/src/node/ext/call.h
+++ b/src/node/ext/call.h
@@ -37,14 +37,13 @@
 #include <memory>
 #include <vector>
 
-#include <node.h>
 #include <nan.h>
+#include <node.h>
 #include "grpc/grpc.h"
 #include "grpc/support/log.h"
 
 #include "channel.h"
 
-
 namespace grpc {
 namespace node {
 
@@ -58,6 +57,8 @@ v8::Local<v8::Value> ParseMetadata(const grpc_metadata_array *metadata_array);
 bool CreateMetadataArray(v8::Local<v8::Object> metadata,
                          grpc_metadata_array *array);
 
+void DestroyMetadataArray(grpc_metadata_array *array);
+
 /* Wrapper class for grpc_call structs. */
 class Call : public Nan::ObjectWrap {
  public:
@@ -76,6 +77,8 @@ class Call : public Nan::ObjectWrap {
   Call(const Call &);
   Call &operator=(const Call &);
 
+  void DestroyCall();
+
   static NAN_METHOD(New);
   static NAN_METHOD(StartBatch);
   static NAN_METHOD(Cancel);
@@ -102,6 +105,7 @@ class Op {
   virtual ~Op();
   v8::Local<v8::Value> GetOpType() const;
   virtual bool IsFinalOp() = 0;
+  virtual void OnComplete(bool success) = 0;
 
  protected:
   virtual std::string GetTypeString() const = 0;
@@ -109,20 +113,19 @@ class Op {
 
 typedef std::vector<unique_ptr<Op>> OpVec;
 struct tag {
-  tag(Nan::Callback *callback, OpVec *ops, Call *call);
+  tag(Nan::Callback *callback, OpVec *ops, Call *call,
+      v8::Local<v8::Value> call_value);
   ~tag();
   Nan::Callback *callback;
   OpVec *ops;
   Call *call;
+  Nan::Persistent<v8::Value, Nan::CopyablePersistentTraits<v8::Value>>
+      call_persist;
 };
 
-v8::Local<v8::Value> GetTagNodeValue(void *tag);
-
-Nan::Callback *GetTagCallback(void *tag);
-
 void DestroyTag(void *tag);
 
-void CompleteTag(void *tag);
+void CompleteTag(void *tag, const char *error_message);
 
 }  // namespace node
 }  // namespace grpc
diff --git a/src/node/ext/call_credentials.cc b/src/node/ext/call_credentials.cc
index afcc363131ed52bae1075d3742d37bbbf6e6d6d8..f88eb8293344b51f013d55a8e692a39fa61cd5f1 100644
--- a/src/node/ext/call_credentials.cc
+++ b/src/node/ext/call_credentials.cc
@@ -31,17 +31,17 @@
  *
  */
 
-#include <node.h>
 #include <nan.h>
+#include <node.h>
 #include <uv.h>
 
 #include <queue>
 
+#include "call.h"
+#include "call_credentials.h"
 #include "grpc/grpc.h"
 #include "grpc/grpc_security.h"
 #include "grpc/support/log.h"
-#include "call_credentials.h"
-#include "call.h"
 
 namespace grpc {
 namespace node {
@@ -86,15 +86,15 @@ void CallCredentials::Init(Local<Object> exports) {
   fun_tpl.Reset(tpl);
   Local<Function> ctr = Nan::GetFunction(tpl).ToLocalChecked();
   Nan::Set(ctr, Nan::New("createFromPlugin").ToLocalChecked(),
-           Nan::GetFunction(
-               Nan::New<FunctionTemplate>(CreateFromPlugin)).ToLocalChecked());
+           Nan::GetFunction(Nan::New<FunctionTemplate>(CreateFromPlugin))
+               .ToLocalChecked());
   Nan::Set(exports, Nan::New("CallCredentials").ToLocalChecked(), ctr);
   constructor = new Nan::Callback(ctr);
 
   Local<FunctionTemplate> callback_tpl =
       Nan::New<FunctionTemplate>(PluginCallback);
-  plugin_callback = new Callback(
-      Nan::GetFunction(callback_tpl).ToLocalChecked());
+  plugin_callback =
+      new Callback(Nan::GetFunction(callback_tpl).ToLocalChecked());
 }
 
 bool CallCredentials::HasInstance(Local<Value> val) {
@@ -109,9 +109,9 @@ Local<Value> CallCredentials::WrapStruct(grpc_call_credentials *credentials) {
     return scope.Escape(Nan::Null());
   }
   Local<Value> argv[argc] = {
-    Nan::New<External>(reinterpret_cast<void *>(credentials))};
-  MaybeLocal<Object> maybe_instance = Nan::NewInstance(
-      constructor->GetFunction(), argc, argv);
+      Nan::New<External>(reinterpret_cast<void *>(credentials))};
+  MaybeLocal<Object> maybe_instance =
+      Nan::NewInstance(constructor->GetFunction(), argc, argv);
   if (maybe_instance.IsEmpty()) {
     return scope.Escape(Nan::Null());
   } else {
@@ -160,8 +160,6 @@ NAN_METHOD(CallCredentials::Compose) {
   info.GetReturnValue().Set(WrapStruct(creds));
 }
 
-
-
 NAN_METHOD(CallCredentials::CreateFromPlugin) {
   if (!info[0]->IsFunction()) {
     return Nan::ThrowTypeError(
@@ -170,21 +168,19 @@ NAN_METHOD(CallCredentials::CreateFromPlugin) {
   grpc_metadata_credentials_plugin plugin;
   plugin_state *state = new plugin_state;
   state->callback = new Nan::Callback(info[0].As<Function>());
-  state->pending_callbacks = new std::queue<plugin_callback_data*>();
+  state->pending_callbacks = new std::queue<plugin_callback_data *>();
   uv_mutex_init(&state->plugin_mutex);
-  uv_async_init(uv_default_loop(),
-                &state->plugin_async,
-                SendPluginCallback);
-  uv_unref((uv_handle_t*)&state->plugin_async);
+  uv_async_init(uv_default_loop(), &state->plugin_async, SendPluginCallback);
+  uv_unref((uv_handle_t *)&state->plugin_async);
 
   state->plugin_async.data = state;
 
   plugin.get_metadata = plugin_get_metadata;
   plugin.destroy = plugin_destroy_state;
-  plugin.state = reinterpret_cast<void*>(state);
+  plugin.state = reinterpret_cast<void *>(state);
   plugin.type = "";
-  grpc_call_credentials *creds = grpc_metadata_credentials_create_from_plugin(
-      plugin, NULL);
+  grpc_call_credentials *creds =
+      grpc_metadata_credentials_create_from_plugin(plugin, NULL);
   info.GetReturnValue().Set(WrapStruct(creds));
 }
 
@@ -206,32 +202,35 @@ NAN_METHOD(PluginCallback) {
     return Nan::ThrowTypeError(
         "The callback's fourth argument must be an object");
   }
-  grpc_status_code code = static_cast<grpc_status_code>(
-      Nan::To<uint32_t>(info[0]).FromJust());
+  grpc_status_code code =
+      static_cast<grpc_status_code>(Nan::To<uint32_t>(info[0]).FromJust());
   Utf8String details_utf8_str(info[1]);
   char *details = *details_utf8_str;
   grpc_metadata_array array;
+  grpc_metadata_array_init(&array);
   Local<Object> callback_data = Nan::To<Object>(info[3]).ToLocalChecked();
-  if (!CreateMetadataArray(Nan::To<Object>(info[2]).ToLocalChecked(),
-                           &array)){
+  if (!CreateMetadataArray(Nan::To<Object>(info[2]).ToLocalChecked(), &array)) {
     return Nan::ThrowError("Failed to parse metadata");
   }
   grpc_credentials_plugin_metadata_cb cb =
       reinterpret_cast<grpc_credentials_plugin_metadata_cb>(
-          Nan::Get(callback_data,
-                   Nan::New("cb").ToLocalChecked()
-                   ).ToLocalChecked().As<External>()->Value());
+          Nan::Get(callback_data, Nan::New("cb").ToLocalChecked())
+              .ToLocalChecked()
+              .As<External>()
+              ->Value());
   void *user_data =
-      Nan::Get(callback_data,
-               Nan::New("user_data").ToLocalChecked()
-               ).ToLocalChecked().As<External>()->Value();
+      Nan::Get(callback_data, Nan::New("user_data").ToLocalChecked())
+          .ToLocalChecked()
+          .As<External>()
+          ->Value();
   cb(user_data, array.metadata, array.count, code, details);
+  DestroyMetadataArray(&array);
 }
 
 NAUV_WORK_CB(SendPluginCallback) {
   Nan::HandleScope scope;
-  plugin_state *state = reinterpret_cast<plugin_state*>(async->data);
-  std::queue<plugin_callback_data*> callbacks;
+  plugin_state *state = reinterpret_cast<plugin_state *>(async->data);
+  std::queue<plugin_callback_data *> callbacks;
   uv_mutex_lock(&state->plugin_mutex);
   state->pending_callbacks->swap(callbacks);
   uv_mutex_unlock(&state->plugin_mutex);
@@ -240,16 +239,14 @@ NAUV_WORK_CB(SendPluginCallback) {
     callbacks.pop();
     Local<Object> callback_data = Nan::New<Object>();
     Nan::Set(callback_data, Nan::New("cb").ToLocalChecked(),
-             Nan::New<v8::External>(reinterpret_cast<void*>(data->cb)));
+             Nan::New<v8::External>(reinterpret_cast<void *>(data->cb)));
     Nan::Set(callback_data, Nan::New("user_data").ToLocalChecked(),
              Nan::New<v8::External>(data->user_data));
     const int argc = 3;
     v8::Local<v8::Value> argv[argc] = {
-      Nan::New(data->service_url).ToLocalChecked(),
-      callback_data,
-      // Get Local<Function> from Nan::Callback*
-      **plugin_callback
-    };
+        Nan::New(data->service_url).ToLocalChecked(), callback_data,
+        // Get Local<Function> from Nan::Callback*
+        **plugin_callback};
     Nan::Callback *callback = state->callback;
     callback->Call(argc, argv);
     delete data;
@@ -259,7 +256,7 @@ NAUV_WORK_CB(SendPluginCallback) {
 void plugin_get_metadata(void *state, grpc_auth_metadata_context context,
                          grpc_credentials_plugin_metadata_cb cb,
                          void *user_data) {
-  plugin_state *p_state = reinterpret_cast<plugin_state*>(state);
+  plugin_state *p_state = reinterpret_cast<plugin_state *>(state);
   plugin_callback_data *data = new plugin_callback_data;
   data->service_url = context.service_url;
   data->cb = cb;
@@ -273,7 +270,7 @@ void plugin_get_metadata(void *state, grpc_auth_metadata_context context,
 }
 
 void plugin_uv_close_cb(uv_handle_t *handle) {
-  uv_async_t *async = reinterpret_cast<uv_async_t*>(handle);
+  uv_async_t *async = reinterpret_cast<uv_async_t *>(handle);
   plugin_state *state = reinterpret_cast<plugin_state *>(async->data);
   uv_mutex_destroy(&state->plugin_mutex);
   delete state->pending_callbacks;
@@ -283,7 +280,7 @@ void plugin_uv_close_cb(uv_handle_t *handle) {
 
 void plugin_destroy_state(void *ptr) {
   plugin_state *state = reinterpret_cast<plugin_state *>(ptr);
-  uv_close((uv_handle_t*)&state->plugin_async, plugin_uv_close_cb);
+  uv_close((uv_handle_t *)&state->plugin_async, plugin_uv_close_cb);
 }
 
 }  // namespace node
diff --git a/src/node/ext/call_credentials.h b/src/node/ext/call_credentials.h
index 21a4b8923e2223dbc76fbe3b192d9dcb2ab10b81..5a1741c606ff836679243a836e34ccf7e0052454 100644
--- a/src/node/ext/call_credentials.h
+++ b/src/node/ext/call_credentials.h
@@ -36,8 +36,8 @@
 
 #include <queue>
 
-#include <node.h>
 #include <nan.h>
+#include <node.h>
 #include <uv.h>
 #include "grpc/grpc_security.h"
 
@@ -84,7 +84,7 @@ typedef struct plugin_callback_data {
 
 typedef struct plugin_state {
   Nan::Callback *callback;
-  std::queue<plugin_callback_data*> *pending_callbacks;
+  std::queue<plugin_callback_data *> *pending_callbacks;
   uv_mutex_t plugin_mutex;
   // async.data == this
   uv_async_t plugin_async;
diff --git a/src/node/ext/channel.cc b/src/node/ext/channel.cc
index c795ff7f42f65ca164c835849eebd090cbabccb6..eb6bc0f53feb9c3e48c497d6762fb35a2fa65302 100644
--- a/src/node/ext/channel.cc
+++ b/src/node/ext/channel.cc
@@ -35,15 +35,14 @@
 
 #include "grpc/support/log.h"
 
-#include <node.h>
 #include <nan.h>
-#include "grpc/grpc.h"
-#include "grpc/grpc_security.h"
+#include <node.h>
 #include "call.h"
 #include "channel.h"
-#include "completion_queue.h"
-#include "completion_queue_async_worker.h"
 #include "channel_credentials.h"
+#include "completion_queue.h"
+#include "grpc/grpc.h"
+#include "grpc/grpc_security.h"
 #include "timeval.h"
 
 namespace grpc {
@@ -82,8 +81,8 @@ bool ParseChannelArgs(Local<Value> args_val,
     *channel_args_ptr = NULL;
     return false;
   }
-  grpc_channel_args *channel_args = reinterpret_cast<grpc_channel_args*>(
-      malloc(sizeof(grpc_channel_args)));
+  grpc_channel_args *channel_args =
+      reinterpret_cast<grpc_channel_args *>(malloc(sizeof(grpc_channel_args)));
   *channel_args_ptr = channel_args;
   Local<Object> args_hash = Nan::To<Object>(args_val).ToLocalChecked();
   Local<Array> keys = Nan::GetOwnPropertyNames(args_hash).ToLocalChecked();
@@ -104,16 +103,16 @@ bool ParseChannelArgs(Local<Value> args_val,
     } else if (value->IsString()) {
       Utf8String val_str(value);
       channel_args->args[i].type = GRPC_ARG_STRING;
-      channel_args->args[i].value.string = reinterpret_cast<char*>(
-          calloc(val_str.length() + 1,sizeof(char)));
-      memcpy(channel_args->args[i].value.string,
-             *val_str, val_str.length() + 1);
+      channel_args->args[i].value.string =
+          reinterpret_cast<char *>(calloc(val_str.length() + 1, sizeof(char)));
+      memcpy(channel_args->args[i].value.string, *val_str,
+             val_str.length() + 1);
     } else {
       // The value does not match either of the accepted types
       return false;
     }
-    channel_args->args[i].key = reinterpret_cast<char*>(
-        calloc(key_str.length() + 1, sizeof(char)));
+    channel_args->args[i].key =
+        reinterpret_cast<char *>(calloc(key_str.length() + 1, sizeof(char)));
     memcpy(channel_args->args[i].key, *key_str, key_str.length() + 1);
   }
   return true;
@@ -190,12 +189,13 @@ NAN_METHOD(Channel::New) {
     grpc_channel_args *channel_args_ptr = NULL;
     if (!ParseChannelArgs(info[2], &channel_args_ptr)) {
       DeallocateChannelArgs(channel_args_ptr);
-      return Nan::ThrowTypeError("Channel options must be an object with "
-                                 "string keys and integer or string values");
+      return Nan::ThrowTypeError(
+          "Channel options must be an object with "
+          "string keys and integer or string values");
     }
     if (creds == NULL) {
-      wrapped_channel = grpc_insecure_channel_create(*host, channel_args_ptr,
-                                                     NULL);
+      wrapped_channel =
+          grpc_insecure_channel_create(*host, channel_args_ptr, NULL);
     } else {
       wrapped_channel =
           grpc_secure_channel_create(creds, *host, channel_args_ptr, NULL);
@@ -208,8 +208,8 @@ NAN_METHOD(Channel::New) {
   } else {
     const int argc = 3;
     Local<Value> argv[argc] = {info[0], info[1], info[2]};
-    MaybeLocal<Object> maybe_instance = Nan::NewInstance(
-        constructor->GetFunction(), argc, argv);
+    MaybeLocal<Object> maybe_instance =
+        Nan::NewInstance(constructor->GetFunction(), argc, argv);
     if (maybe_instance.IsEmpty()) {
       // There's probably a pending exception
       return;
@@ -232,11 +232,13 @@ NAN_METHOD(Channel::Close) {
 
 NAN_METHOD(Channel::GetTarget) {
   if (!HasInstance(info.This())) {
-    return Nan::ThrowTypeError("getTarget can only be called on Channel objects");
+    return Nan::ThrowTypeError(
+        "getTarget can only be called on Channel objects");
   }
   Channel *channel = ObjectWrap::Unwrap<Channel>(info.This());
-  info.GetReturnValue().Set(Nan::New(
-      grpc_channel_get_target(channel->wrapped_channel)).ToLocalChecked());
+  info.GetReturnValue().Set(
+      Nan::New(grpc_channel_get_target(channel->wrapped_channel))
+          .ToLocalChecked());
 }
 
 NAN_METHOD(Channel::GetConnectivityState) {
@@ -246,9 +248,8 @@ NAN_METHOD(Channel::GetConnectivityState) {
   }
   Channel *channel = ObjectWrap::Unwrap<Channel>(info.This());
   int try_to_connect = (int)info[0]->Equals(Nan::True());
-  info.GetReturnValue().Set(
-      grpc_channel_check_connectivity_state(channel->wrapped_channel,
-                                            try_to_connect));
+  info.GetReturnValue().Set(grpc_channel_check_connectivity_state(
+      channel->wrapped_channel, try_to_connect));
 }
 
 NAN_METHOD(Channel::WatchConnectivityState) {
@@ -268,9 +269,8 @@ NAN_METHOD(Channel::WatchConnectivityState) {
     return Nan::ThrowTypeError(
         "watchConnectivityState's third argument must be a callback");
   }
-  grpc_connectivity_state last_state =
-      static_cast<grpc_connectivity_state>(
-          Nan::To<uint32_t>(info[0]).FromJust());
+  grpc_connectivity_state last_state = static_cast<grpc_connectivity_state>(
+      Nan::To<uint32_t>(info[0]).FromJust());
   double deadline = Nan::To<double>(info[1]).FromJust();
   Local<Function> callback_func = info[2].As<Function>();
   Nan::Callback *callback = new Callback(callback_func);
@@ -279,8 +279,7 @@ NAN_METHOD(Channel::WatchConnectivityState) {
   grpc_channel_watch_connectivity_state(
       channel->wrapped_channel, last_state, MillisecondsToTimespec(deadline),
       GetCompletionQueue(),
-      new struct tag(callback,
-                     ops.release(), NULL));
+      new struct tag(callback, ops.release(), NULL, Nan::Null()));
   CompletionQueueNext();
 }
 
diff --git a/src/node/ext/channel.h b/src/node/ext/channel.h
index 9ec28e15af04accf6499c800abd56947a417b513..6d42a5e04060da8bcdf5060fb1b6f15a3fa1a143 100644
--- a/src/node/ext/channel.h
+++ b/src/node/ext/channel.h
@@ -34,8 +34,8 @@
 #ifndef NET_GRPC_NODE_CHANNEL_H_
 #define NET_GRPC_NODE_CHANNEL_H_
 
-#include <node.h>
 #include <nan.h>
+#include <node.h>
 #include "grpc/grpc.h"
 
 namespace grpc {
diff --git a/src/node/ext/channel_credentials.cc b/src/node/ext/channel_credentials.cc
index 059bc8a890262d20e2042f4577fa8648120e569d..cf1dc318a8f6a76d0c96fa0a7ec2c29f78c22d94 100644
--- a/src/node/ext/channel_credentials.cc
+++ b/src/node/ext/channel_credentials.cc
@@ -33,12 +33,12 @@
 
 #include <node.h>
 
+#include "call.h"
+#include "call_credentials.h"
+#include "channel_credentials.h"
 #include "grpc/grpc.h"
 #include "grpc/grpc_security.h"
 #include "grpc/support/log.h"
-#include "channel_credentials.h"
-#include "call_credentials.h"
-#include "call.h"
 
 namespace grpc {
 namespace node {
@@ -80,12 +80,12 @@ void ChannelCredentials::Init(Local<Object> exports) {
   Nan::SetPrototypeMethod(tpl, "compose", Compose);
   fun_tpl.Reset(tpl);
   Local<Function> ctr = Nan::GetFunction(tpl).ToLocalChecked();
-  Nan::Set(ctr, Nan::New("createSsl").ToLocalChecked(),
-           Nan::GetFunction(
-               Nan::New<FunctionTemplate>(CreateSsl)).ToLocalChecked());
+  Nan::Set(
+      ctr, Nan::New("createSsl").ToLocalChecked(),
+      Nan::GetFunction(Nan::New<FunctionTemplate>(CreateSsl)).ToLocalChecked());
   Nan::Set(ctr, Nan::New("createInsecure").ToLocalChecked(),
-           Nan::GetFunction(
-               Nan::New<FunctionTemplate>(CreateInsecure)).ToLocalChecked());
+           Nan::GetFunction(Nan::New<FunctionTemplate>(CreateInsecure))
+               .ToLocalChecked());
   Nan::Set(exports, Nan::New("ChannelCredentials").ToLocalChecked(), ctr);
   constructor = new Nan::Callback(ctr);
 }
@@ -100,9 +100,9 @@ Local<Value> ChannelCredentials::WrapStruct(
   EscapableHandleScope scope;
   const int argc = 1;
   Local<Value> argv[argc] = {
-    Nan::New<External>(reinterpret_cast<void *>(credentials))};
-  MaybeLocal<Object> maybe_instance = Nan::NewInstance(
-      constructor->GetFunction(), argc, argv);
+      Nan::New<External>(reinterpret_cast<void *>(credentials))};
+  MaybeLocal<Object> maybe_instance =
+      Nan::NewInstance(constructor->GetFunction(), argc, argv);
   if (maybe_instance.IsEmpty()) {
     return scope.Escape(Nan::Null());
   } else {
@@ -179,11 +179,10 @@ NAN_METHOD(ChannelCredentials::Compose) {
     return Nan::ThrowTypeError(
         "compose's first argument must be a CallCredentials object");
   }
-  ChannelCredentials *self = ObjectWrap::Unwrap<ChannelCredentials>(
-      info.This());
+  ChannelCredentials *self =
+      ObjectWrap::Unwrap<ChannelCredentials>(info.This());
   if (self->wrapped_credentials == NULL) {
-    return Nan::ThrowTypeError(
-        "Cannot compose insecure credential");
+    return Nan::ThrowTypeError("Cannot compose insecure credential");
   }
   CallCredentials *other = ObjectWrap::Unwrap<CallCredentials>(
       Nan::To<Object>(info[0]).ToLocalChecked());
diff --git a/src/node/ext/channel_credentials.h b/src/node/ext/channel_credentials.h
index 89b115267f33e806ff8bb0d7154f152ba62773ad..e5c7439de27bff3dc55df2b7dfeeda6c6e64a25c 100644
--- a/src/node/ext/channel_credentials.h
+++ b/src/node/ext/channel_credentials.h
@@ -34,8 +34,8 @@
 #ifndef NET_GRPC_NODE_CHANNEL_CREDENTIALS_H_
 #define NET_GRPC_NODE_CHANNEL_CREDENTIALS_H_
 
-#include <node.h>
 #include <nan.h>
+#include <node.h>
 #include "grpc/grpc.h"
 #include "grpc/grpc_security.h"
 
diff --git a/src/node/ext/completion_queue_uv.cc b/src/node/ext/completion_queue.cc
similarity index 80%
rename from src/node/ext/completion_queue_uv.cc
rename to src/node/ext/completion_queue.cc
index 615973a6c9b8f0e67fc02bc2a068bf74b4098906..d01abad7572491fe6fdf818f793247dca60f1492 100644
--- a/src/node/ext/completion_queue_uv.cc
+++ b/src/node/ext/completion_queue.cc
@@ -31,12 +31,10 @@
  *
  */
 
-#ifdef GRPC_UV
-
-#include <uv.h>
+#include <grpc/grpc.h>
 #include <node.h>
+#include <uv.h>
 #include <v8.h>
-#include <grpc/grpc.h>
 
 #include "call.h"
 #include "completion_queue.h"
@@ -57,21 +55,17 @@ void drain_completion_queue(uv_prepare_t *handle) {
   grpc_event event;
   (void)handle;
   do {
-    event = grpc_completion_queue_next(
-        queue, gpr_inf_past(GPR_CLOCK_MONOTONIC), NULL);
+    event = grpc_completion_queue_next(queue, gpr_inf_past(GPR_CLOCK_MONOTONIC),
+                                       NULL);
 
     if (event.type == GRPC_OP_COMPLETE) {
-      Nan::Callback *callback = grpc::node::GetTagCallback(event.tag);
+      const char *error_message;
       if (event.success) {
-        Local<Value> argv[] = {Nan::Null(),
-                             grpc::node::GetTagNodeValue(event.tag)};
-        callback->Call(2, argv);
+        error_message = NULL;
       } else {
-        Local<Value> argv[] = {Nan::Error(
-            "The async function encountered an error")};
-        callback->Call(1, argv);
+        error_message = "The async function encountered an error";
       }
-      grpc::node::CompleteTag(event.tag);
+      CompleteTag(event.tag, error_message);
       grpc::node::DestroyTag(event.tag);
       pending_batches--;
       if (pending_batches == 0) {
@@ -81,9 +75,7 @@ void drain_completion_queue(uv_prepare_t *handle) {
   } while (event.type != GRPC_QUEUE_TIMEOUT);
 }
 
-grpc_completion_queue *GetCompletionQueue() {
-  return queue;
-}
+grpc_completion_queue *GetCompletionQueue() { return queue; }
 
 void CompletionQueueNext() {
   if (pending_batches == 0) {
@@ -94,12 +86,10 @@ void CompletionQueueNext() {
 }
 
 void CompletionQueueInit(Local<Object> exports) {
-  queue = grpc_completion_queue_create(NULL);
+  queue = grpc_completion_queue_create_for_next(NULL);
   uv_prepare_init(uv_default_loop(), &prepare);
   pending_batches = 0;
 }
 
 }  // namespace node
 }  // namespace grpc
-
-#endif /* GRPC_UV */
diff --git a/src/node/ext/completion_queue.h b/src/node/ext/completion_queue.h
index 9b01028ef173a42c9c0e2eaef9352702c787647f..a3a055c385a3c0c2c8a20a33528296a46f9836ea 100644
--- a/src/node/ext/completion_queue.h
+++ b/src/node/ext/completion_queue.h
@@ -31,8 +31,8 @@
  *
  */
 
-#include <v8.h>
 #include <grpc/grpc.h>
+#include <v8.h>
 
 namespace grpc {
 namespace node {
diff --git a/src/node/ext/completion_queue_threadpool.cc b/src/node/ext/completion_queue_threadpool.cc
deleted file mode 100644
index 1917074dc2dfe85ddd238513b6ae2199291b52ef..0000000000000000000000000000000000000000
--- a/src/node/ext/completion_queue_threadpool.cc
+++ /dev/null
@@ -1,187 +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.
- *
- */
-
-/* I don't like using #ifndef, but I don't see a better way to do this */
-#ifndef GRPC_UV
-
-#include <node.h>
-#include <nan.h>
-
-#include "grpc/grpc.h"
-#include "grpc/support/log.h"
-#include "grpc/support/time.h"
-#include "completion_queue.h"
-#include "call.h"
-
-namespace grpc {
-namespace node {
-
-namespace {
-
-/* A worker that asynchronously calls completion_queue_next, and queues onto the
-   node event loop a call to the function stored in the event's tag. */
-class CompletionQueueAsyncWorker : public Nan::AsyncWorker {
- public:
-  CompletionQueueAsyncWorker();
-
-  ~CompletionQueueAsyncWorker();
-  /* Calls completion_queue_next with the provided deadline, and stores the
-     event if there was one or sets an error message if there was not */
-  void Execute();
-
-  /* Returns the completion queue attached to this class */
-  static grpc_completion_queue *GetQueue();
-
-  /* Convenience function to create a worker with the given arguments and queue
-     it to run asynchronously */
-  static void Next();
-
-  /* Initialize the CompletionQueueAsyncWorker class */
-  static void Init(v8::Local<v8::Object> exports);
-
- protected:
-  /* Called when Execute has succeeded (completed without setting an error
-     message). Calls the saved callback with the event that came from
-     completion_queue_next */
-  void HandleOKCallback();
-
-  void HandleErrorCallback();
-
- private:
-  static void TryAddWorker();
-
-  grpc_event result;
-
-  static grpc_completion_queue *queue;
-
-  // Number of grpc_completion_queue_next calls in the thread pool
-  static int current_threads;
-  // Number of grpc_completion_queue_next calls waiting to enter the thread pool
-  static int waiting_next_calls;
-};
-
-const int max_queue_threads = 2;
-
-using v8::Function;
-using v8::Local;
-using v8::Object;
-using v8::Value;
-
-grpc_completion_queue *CompletionQueueAsyncWorker::queue;
-
-// Invariants: current_threads <= max_queue_threads
-// (current_threads == max_queue_threads) || (waiting_next_calls == 0)
-
-int CompletionQueueAsyncWorker::current_threads;
-int CompletionQueueAsyncWorker::waiting_next_calls;
-
-CompletionQueueAsyncWorker::CompletionQueueAsyncWorker()
-    : Nan::AsyncWorker(NULL) {}
-
-CompletionQueueAsyncWorker::~CompletionQueueAsyncWorker() {}
-
-void CompletionQueueAsyncWorker::Execute() {
-  result =
-      grpc_completion_queue_next(queue, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
-  if (!result.success) {
-    SetErrorMessage("The async function encountered an error");
-  }
-}
-
-grpc_completion_queue *CompletionQueueAsyncWorker::GetQueue() { return queue; }
-
-void CompletionQueueAsyncWorker::TryAddWorker() {
-  if (current_threads < max_queue_threads && waiting_next_calls > 0) {
-    current_threads += 1;
-    waiting_next_calls -= 1;
-    CompletionQueueAsyncWorker *worker = new CompletionQueueAsyncWorker();
-    Nan::AsyncQueueWorker(worker);
-  }
-  GPR_ASSERT(current_threads <= max_queue_threads);
-  GPR_ASSERT((current_threads == max_queue_threads) ||
-             (waiting_next_calls == 0));
-}
-
-void CompletionQueueAsyncWorker::Next() {
-  waiting_next_calls += 1;
-  TryAddWorker();
-}
-
-void CompletionQueueAsyncWorker::Init(Local<Object> exports) {
-  Nan::HandleScope scope;
-  current_threads = 0;
-  waiting_next_calls = 0;
-  queue = grpc_completion_queue_create(NULL);
-}
-
-void CompletionQueueAsyncWorker::HandleOKCallback() {
-  Nan::HandleScope scope;
-  current_threads -= 1;
-  TryAddWorker();
-  Nan::Callback *callback = GetTagCallback(result.tag);
-  Local<Value> argv[] = {Nan::Null(), GetTagNodeValue(result.tag)};
-  callback->Call(2, argv);
-
-  DestroyTag(result.tag);
-}
-
-void CompletionQueueAsyncWorker::HandleErrorCallback() {
-  Nan::HandleScope scope;
-  current_threads -= 1;
-  TryAddWorker();
-  Nan::Callback *callback = GetTagCallback(result.tag);
-  Local<Value> argv[] = {Nan::Error(ErrorMessage())};
-
-  callback->Call(1, argv);
-
-  DestroyTag(result.tag);
-}
-
-}  // namespace
-
-grpc_completion_queue *GetCompletionQueue() {
-  return CompletionQueueAsyncWorker::GetQueue();
-}
-
-void CompletionQueueNext() {
-  CompletionQueueAsyncWorker::Next();
-}
-
-void CompletionQueueInit(Local<Object> exports) {
-  CompletionQueueAsyncWorker::Init(exports);
-}
-
-}  // namespace node
-}  // namespace grpc
-
-#endif  /* GRPC_UV */
diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc
index 95e273f8ac9fc31d173116f19fa50442af77beb6..e193e82179aa12af62ccf2903bf007104173b613 100644
--- a/src/node/ext/node_grpc.cc
+++ b/src/node/ext/node_grpc.cc
@@ -33,8 +33,8 @@
 
 #include <queue>
 
-#include <node.h>
 #include <nan.h>
+#include <node.h>
 #include <v8.h>
 #include "grpc/grpc.h"
 #include "grpc/grpc_security.h"
@@ -43,22 +43,19 @@
 #include "grpc/support/time.h"
 
 // TODO(murgatroid99): Remove this when the endpoint API becomes public
-#ifdef GRPC_UV
 extern "C" {
 #include "src/core/lib/iomgr/pollset_uv.h"
 }
-#endif
 
 #include "call.h"
 #include "call_credentials.h"
 #include "channel.h"
 #include "channel_credentials.h"
+#include "completion_queue.h"
 #include "server.h"
-#include "completion_queue_async_worker.h"
 #include "server_credentials.h"
 #include "slice.h"
 #include "timeval.h"
-#include "completion_queue.h"
 
 using grpc::node::CreateSliceFromString;
 
@@ -188,8 +185,7 @@ void InitOpTypeConstants(Local<Object> exports) {
       Nan::New<Uint32, uint32_t>(GRPC_OP_SEND_INITIAL_METADATA));
   Nan::Set(op_type, Nan::New("SEND_INITIAL_METADATA").ToLocalChecked(),
            SEND_INITIAL_METADATA);
-  Local<Value> SEND_MESSAGE(
-      Nan::New<Uint32, uint32_t>(GRPC_OP_SEND_MESSAGE));
+  Local<Value> SEND_MESSAGE(Nan::New<Uint32, uint32_t>(GRPC_OP_SEND_MESSAGE));
   Nan::Set(op_type, Nan::New("SEND_MESSAGE").ToLocalChecked(), SEND_MESSAGE);
   Local<Value> SEND_CLOSE_FROM_CLIENT(
       Nan::New<Uint32, uint32_t>(GRPC_OP_SEND_CLOSE_FROM_CLIENT));
@@ -203,8 +199,7 @@ void InitOpTypeConstants(Local<Object> exports) {
       Nan::New<Uint32, uint32_t>(GRPC_OP_RECV_INITIAL_METADATA));
   Nan::Set(op_type, Nan::New("RECV_INITIAL_METADATA").ToLocalChecked(),
            RECV_INITIAL_METADATA);
-  Local<Value> RECV_MESSAGE(
-      Nan::New<Uint32, uint32_t>(GRPC_OP_RECV_MESSAGE));
+  Local<Value> RECV_MESSAGE(Nan::New<Uint32, uint32_t>(GRPC_OP_RECV_MESSAGE));
   Nan::Set(op_type, Nan::New("RECV_MESSAGE").ToLocalChecked(), RECV_MESSAGE);
   Local<Value> RECV_STATUS_ON_CLIENT(
       Nan::New<Uint32, uint32_t>(GRPC_OP_RECV_STATUS_ON_CLIENT));
@@ -252,8 +247,7 @@ void InitConnectivityStateConstants(Local<Object> exports) {
       Nan::New<Uint32, uint32_t>(GRPC_CHANNEL_TRANSIENT_FAILURE));
   Nan::Set(channel_state, Nan::New("TRANSIENT_FAILURE").ToLocalChecked(),
            TRANSIENT_FAILURE);
-  Local<Value> FATAL_FAILURE(
-      Nan::New<Uint32, uint32_t>(GRPC_CHANNEL_SHUTDOWN));
+  Local<Value> FATAL_FAILURE(Nan::New<Uint32, uint32_t>(GRPC_CHANNEL_SHUTDOWN));
   Nan::Set(channel_state, Nan::New("FATAL_FAILURE").ToLocalChecked(),
            FATAL_FAILURE);
 }
@@ -282,12 +276,12 @@ void InitLogConstants(Local<Object> exports) {
 
 NAN_METHOD(MetadataKeyIsLegal) {
   if (!info[0]->IsString()) {
-    return Nan::ThrowTypeError(
-        "headerKeyIsLegal's argument must be a string");
+    return Nan::ThrowTypeError("headerKeyIsLegal's argument must be a string");
   }
   Local<String> key = Nan::To<String>(info[0]).ToLocalChecked();
-  info.GetReturnValue().Set(static_cast<bool>(
-      grpc_header_key_is_legal(CreateSliceFromString(key))));
+  grpc_slice slice = CreateSliceFromString(key);
+  info.GetReturnValue().Set(static_cast<bool>(grpc_header_key_is_legal(slice)));
+  grpc_slice_unref(slice);
 }
 
 NAN_METHOD(MetadataNonbinValueIsLegal) {
@@ -296,8 +290,10 @@ NAN_METHOD(MetadataNonbinValueIsLegal) {
         "metadataNonbinValueIsLegal's argument must be a string");
   }
   Local<String> value = Nan::To<String>(info[0]).ToLocalChecked();
-  info.GetReturnValue().Set(static_cast<bool>(
-      grpc_header_nonbin_value_is_legal(CreateSliceFromString(value))));
+  grpc_slice slice = CreateSliceFromString(value);
+  info.GetReturnValue().Set(
+      static_cast<bool>(grpc_header_nonbin_value_is_legal(slice)));
+  grpc_slice_unref(slice);
 }
 
 NAN_METHOD(MetadataKeyIsBinary) {
@@ -306,8 +302,9 @@ NAN_METHOD(MetadataKeyIsBinary) {
         "metadataKeyIsLegal's argument must be a string");
   }
   Local<String> key = Nan::To<String>(info[0]).ToLocalChecked();
-  info.GetReturnValue().Set(static_cast<bool>(
-      grpc_is_binary_header(CreateSliceFromString(key))));
+  grpc_slice slice = CreateSliceFromString(key);
+  info.GetReturnValue().Set(static_cast<bool>(grpc_is_binary_header(slice)));
+  grpc_slice_unref(slice);
 }
 
 static grpc_ssl_roots_override_result get_ssl_roots_override(
@@ -348,11 +345,13 @@ NAUV_WORK_CB(LogMessagesCallback) {
     args.pop();
     Local<Value> file = Nan::New(arg->core_args.file).ToLocalChecked();
     Local<Value> line = Nan::New<Uint32, uint32_t>(arg->core_args.line);
-    Local<Value> severity = Nan::New(
-        gpr_log_severity_string(arg->core_args.severity)).ToLocalChecked();
+    Local<Value> severity =
+        Nan::New(gpr_log_severity_string(arg->core_args.severity))
+            .ToLocalChecked();
     Local<Value> message = Nan::New(arg->core_args.message).ToLocalChecked();
-    Local<Value> timestamp = Nan::New<v8::Date>(
-        grpc::node::TimespecToMilliseconds(arg->timestamp)).ToLocalChecked();
+    Local<Value> timestamp =
+        Nan::New<v8::Date>(grpc::node::TimespecToMilliseconds(arg->timestamp))
+            .ToLocalChecked();
     const int argc = 5;
     Local<Value> argv[argc] = {file, line, severity, message, timestamp};
     grpc_logger_state.callback->Call(argc, argv);
@@ -382,10 +381,9 @@ void init_logger() {
   memset(&grpc_logger_state, 0, sizeof(logger_state));
   grpc_logger_state.pending_args = new std::queue<log_args *>();
   uv_mutex_init(&grpc_logger_state.mutex);
-  uv_async_init(uv_default_loop(),
-                &grpc_logger_state.async,
+  uv_async_init(uv_default_loop(), &grpc_logger_state.async,
                 LogMessagesCallback);
-  uv_unref((uv_handle_t*)&grpc_logger_state.async);
+  uv_unref((uv_handle_t *)&grpc_logger_state.async);
   grpc_logger_state.logger_set = false;
 
   gpr_log_verbosity_init();
@@ -410,11 +408,10 @@ NAN_METHOD(SetDefaultLoggerCallback) {
 
 NAN_METHOD(SetLogVerbosity) {
   if (!info[0]->IsUint32()) {
-    return Nan::ThrowTypeError(
-        "setLogVerbosity's argument must be a number");
+    return Nan::ThrowTypeError("setLogVerbosity's argument must be a number");
   }
-  gpr_log_severity severity = static_cast<gpr_log_severity>(
-      Nan::To<uint32_t>(info[0]).FromJust());
+  gpr_log_severity severity =
+      static_cast<gpr_log_severity>(Nan::To<uint32_t>(info[0]).FromJust());
   gpr_set_log_verbosity(severity);
 }
 
@@ -432,9 +429,7 @@ void init(Local<Object> exports) {
   InitWriteFlags(exports);
   InitLogConstants(exports);
 
-#ifdef GRPC_UV
   grpc_pollset_work_run_loop = 0;
-#endif
 
   grpc::node::Call::Init(exports);
   grpc::node::CallCredentials::Init(exports);
@@ -447,28 +442,25 @@ void init(Local<Object> exports) {
 
   // Attach a few utility functions directly to the module
   Nan::Set(exports, Nan::New("metadataKeyIsLegal").ToLocalChecked(),
-           Nan::GetFunction(
-               Nan::New<FunctionTemplate>(MetadataKeyIsLegal)).ToLocalChecked());
-  Nan::Set(exports, Nan::New("metadataNonbinValueIsLegal").ToLocalChecked(),
-           Nan::GetFunction(
-               Nan::New<FunctionTemplate>(MetadataNonbinValueIsLegal)
-                            ).ToLocalChecked());
+           Nan::GetFunction(Nan::New<FunctionTemplate>(MetadataKeyIsLegal))
+               .ToLocalChecked());
+  Nan::Set(
+      exports, Nan::New("metadataNonbinValueIsLegal").ToLocalChecked(),
+      Nan::GetFunction(Nan::New<FunctionTemplate>(MetadataNonbinValueIsLegal))
+          .ToLocalChecked());
   Nan::Set(exports, Nan::New("metadataKeyIsBinary").ToLocalChecked(),
-           Nan::GetFunction(
-               Nan::New<FunctionTemplate>(MetadataKeyIsBinary)
-                            ).ToLocalChecked());
+           Nan::GetFunction(Nan::New<FunctionTemplate>(MetadataKeyIsBinary))
+               .ToLocalChecked());
   Nan::Set(exports, Nan::New("setDefaultRootsPem").ToLocalChecked(),
-           Nan::GetFunction(
-               Nan::New<FunctionTemplate>(SetDefaultRootsPem)
-                            ).ToLocalChecked());
-  Nan::Set(exports, Nan::New("setDefaultLoggerCallback").ToLocalChecked(),
-           Nan::GetFunction(
-               Nan::New<FunctionTemplate>(SetDefaultLoggerCallback)
-                            ).ToLocalChecked());
+           Nan::GetFunction(Nan::New<FunctionTemplate>(SetDefaultRootsPem))
+               .ToLocalChecked());
+  Nan::Set(
+      exports, Nan::New("setDefaultLoggerCallback").ToLocalChecked(),
+      Nan::GetFunction(Nan::New<FunctionTemplate>(SetDefaultLoggerCallback))
+          .ToLocalChecked());
   Nan::Set(exports, Nan::New("setLogVerbosity").ToLocalChecked(),
-           Nan::GetFunction(
-               Nan::New<FunctionTemplate>(SetLogVerbosity)
-                            ).ToLocalChecked());
+           Nan::GetFunction(Nan::New<FunctionTemplate>(SetLogVerbosity))
+               .ToLocalChecked());
 }
 
 NODE_MODULE(grpc_node, init)
diff --git a/src/node/ext/server.cc b/src/node/ext/server.cc
index ccb55aa54cfdfe4949b499d409cf6cb995c11065..a885a9f26845605d0ab368e6190a0e9323fda5ff 100644
--- a/src/node/ext/server.cc
+++ b/src/node/ext/server.cc
@@ -41,7 +41,6 @@
 #include <vector>
 #include "call.h"
 #include "completion_queue.h"
-#include "completion_queue_async_worker.h"
 #include "grpc/grpc.h"
 #include "grpc/grpc_security.h"
 #include "grpc/support/log.h"
@@ -78,6 +77,30 @@ using v8::Value;
 Nan::Callback *Server::constructor;
 Persistent<FunctionTemplate> Server::fun_tpl;
 
+static Callback *shutdown_callback = NULL;
+
+class ServerShutdownOp : public Op {
+ public:
+  ServerShutdownOp(grpc_server *server) : server(server) {}
+
+  ~ServerShutdownOp() {}
+
+  Local<Value> GetNodeValue() const { return Nan::Null(); }
+
+  bool ParseOp(Local<Value> value, grpc_op *out) { return true; }
+  bool IsFinalOp() { return false; }
+  void OnComplete(bool success) {
+    /* Because cancel_all_calls was called, we assume that shutdown_and_notify
+       completes successfully */
+    grpc_server_destroy(server);
+  }
+
+  grpc_server *server;
+
+ protected:
+  std::string GetTypeString() const { return "shutdown"; }
+};
+
 class NewCallOp : public Op {
  public:
   NewCallOp() {
@@ -111,12 +134,9 @@ class NewCallOp : public Op {
     return scope.Escape(obj);
   }
 
-  bool ParseOp(Local<Value> value, grpc_op *out) {
-    return true;
-  }
-  bool IsFinalOp() {
-    return false;
-  }
+  bool ParseOp(Local<Value> value, grpc_op *out) { return true; }
+  bool IsFinalOp() { return false; }
+  void OnComplete(bool success) {}
 
   grpc_call *call;
   grpc_call_details details;
@@ -126,6 +146,36 @@ class NewCallOp : public Op {
   std::string GetTypeString() const { return "new_call"; }
 };
 
+class TryShutdownOp : public Op {
+ public:
+  TryShutdownOp(Server *server, Local<Value> server_value) : server(server) {
+    server_persist.Reset(server_value);
+  }
+  Local<Value> GetNodeValue() const {
+    EscapableHandleScope scope;
+    return scope.Escape(Nan::New(server_persist));
+  }
+  bool ParseOp(Local<Value> value, grpc_op *out) { return true; }
+  bool IsFinalOp() { return false; }
+  void OnComplete(bool success) {
+    if (success) {
+      server->DestroyWrappedServer();
+    }
+  }
+
+ protected:
+  std::string GetTypeString() const { return "try_shutdown"; }
+
+ private:
+  Server *server;
+  Nan::Persistent<v8::Value, Nan::CopyablePersistentTraits<v8::Value>>
+      server_persist;
+};
+
+Server::Server(grpc_server *server) : wrapped_server(server) {}
+
+Server::~Server() { this->ShutdownServer(); }
+
 void Server::Init(Local<Object> exports) {
   HandleScope scope;
   Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
@@ -147,6 +197,43 @@ bool Server::HasInstance(Local<Value> val) {
   return Nan::New(fun_tpl)->HasInstance(val);
 }
 
+void Server::DestroyWrappedServer() {
+  if (this->wrapped_server != NULL) {
+    grpc_server_destroy(this->wrapped_server);
+    this->wrapped_server = NULL;
+  }
+}
+
+NAN_METHOD(ServerShutdownCallback) {
+  if (!info[0]->IsNull()) {
+    return Nan::ThrowError("forceShutdown failed somehow");
+  }
+}
+
+void Server::ShutdownServer() {
+  Nan::HandleScope scope;
+  if (this->wrapped_server != NULL) {
+    if (shutdown_callback == NULL) {
+      Local<FunctionTemplate> callback_tpl =
+          Nan::New<FunctionTemplate>(ServerShutdownCallback);
+      shutdown_callback =
+          new Callback(Nan::GetFunction(callback_tpl).ToLocalChecked());
+    }
+
+    ServerShutdownOp *op = new ServerShutdownOp(this->wrapped_server);
+    unique_ptr<OpVec> ops(new OpVec());
+    ops->push_back(unique_ptr<Op>(op));
+
+    grpc_server_shutdown_and_notify(
+        this->wrapped_server, GetCompletionQueue(),
+        new struct tag(new Callback(**shutdown_callback), ops.release(), NULL,
+                       Nan::Null()));
+    grpc_server_cancel_all_calls(this->wrapped_server);
+    CompletionQueueNext();
+    this->wrapped_server = NULL;
+  }
+}
+
 NAN_METHOD(Server::New) {
   /* If this is not a constructor call, make a constructor call and return
      the result */
@@ -190,10 +277,9 @@ NAN_METHOD(Server::RequestCall) {
   ops->push_back(unique_ptr<Op>(op));
   grpc_call_error error = grpc_server_request_call(
       server->wrapped_server, &op->call, &op->details, &op->request_metadata,
-      GetCompletionQueue(),
-      GetCompletionQueue(),
-      new struct tag(new Callback(info[0].As<Function>()), ops.release(),
-                     NULL));
+      GetCompletionQueue(), GetCompletionQueue(),
+      new struct tag(new Callback(info[0].As<Function>()), ops.release(), NULL,
+                     Nan::Null()));
   if (error != GRPC_CALL_OK) {
     return Nan::ThrowError(nanErrorWithCode("requestCall failed", error));
   }
@@ -242,11 +328,19 @@ NAN_METHOD(Server::TryShutdown) {
     return Nan::ThrowTypeError("tryShutdown can only be called on a Server");
   }
   Server *server = ObjectWrap::Unwrap<Server>(info.This());
+  if (server->wrapped_server == NULL) {
+    // Server is already shut down. Call callback immediately.
+    Nan::Callback callback(info[0].As<Function>());
+    callback.Call(0, {});
+    return;
+  }
+  TryShutdownOp *op = new TryShutdownOp(server, info.This());
   unique_ptr<OpVec> ops(new OpVec());
+  ops->push_back(unique_ptr<Op>(op));
   grpc_server_shutdown_and_notify(
       server->wrapped_server, GetCompletionQueue(),
       new struct tag(new Nan::Callback(info[0].As<Function>()), ops.release(),
-                     NULL));
+                     NULL, Nan::Null()));
   CompletionQueueNext();
 }
 
diff --git a/src/node/ext/server.h b/src/node/ext/server.h
index ab5fc210e8ace61e6021d197fc11577d166723cc..2d8cb4c44410b495bb7ce61d1b9db0f53393e3f0 100644
--- a/src/node/ext/server.h
+++ b/src/node/ext/server.h
@@ -34,8 +34,8 @@
 #ifndef NET_GRPC_NODE_SERVER_H_
 #define NET_GRPC_NODE_SERVER_H_
 
-#include <node.h>
 #include <nan.h>
+#include <node.h>
 #include "grpc/grpc.h"
 
 namespace grpc {
@@ -53,6 +53,8 @@ class Server : public Nan::ObjectWrap {
      JavaScript constructor */
   static bool HasInstance(v8::Local<v8::Value> val);
 
+  void DestroyWrappedServer();
+
  private:
   explicit Server(grpc_server *server);
   ~Server();
diff --git a/src/node/ext/server_credentials.cc b/src/node/ext/server_credentials.cc
index 0ff58bb20924101d3378530a23470752f9eab1e0..e070ff1f265ec7d3a3b7721ef8b218509f190e0b 100644
--- a/src/node/ext/server_credentials.cc
+++ b/src/node/ext/server_credentials.cc
@@ -78,12 +78,12 @@ void ServerCredentials::Init(Local<Object> exports) {
   tpl->SetClassName(Nan::New("ServerCredentials").ToLocalChecked());
   tpl->InstanceTemplate()->SetInternalFieldCount(1);
   Local<Function> ctr = tpl->GetFunction();
-  Nan::Set(ctr, Nan::New("createSsl").ToLocalChecked(),
-           Nan::GetFunction(
-               Nan::New<FunctionTemplate>(CreateSsl)).ToLocalChecked());
+  Nan::Set(
+      ctr, Nan::New("createSsl").ToLocalChecked(),
+      Nan::GetFunction(Nan::New<FunctionTemplate>(CreateSsl)).ToLocalChecked());
   Nan::Set(ctr, Nan::New("createInsecure").ToLocalChecked(),
-           Nan::GetFunction(
-               Nan::New<FunctionTemplate>(CreateInsecure)).ToLocalChecked());
+           Nan::GetFunction(Nan::New<FunctionTemplate>(CreateInsecure))
+               .ToLocalChecked());
   fun_tpl.Reset(tpl);
   constructor = new Nan::Callback(ctr);
   Nan::Set(exports, Nan::New("ServerCredentials").ToLocalChecked(), ctr);
@@ -99,9 +99,9 @@ Local<Value> ServerCredentials::WrapStruct(
   Nan::EscapableHandleScope scope;
   const int argc = 1;
   Local<Value> argv[argc] = {
-    Nan::New<External>(reinterpret_cast<void *>(credentials))};
-  MaybeLocal<Object> maybe_instance = Nan::NewInstance(
-      constructor->GetFunction(), argc, argv);
+      Nan::New<External>(reinterpret_cast<void *>(credentials))};
+  MaybeLocal<Object> maybe_instance =
+      Nan::NewInstance(constructor->GetFunction(), argc, argv);
   if (maybe_instance.IsEmpty()) {
     return scope.Escape(Nan::Null());
   } else {
@@ -160,13 +160,13 @@ NAN_METHOD(ServerCredentials::CreateSsl) {
   }
   Local<Array> pair_list = Local<Array>::Cast(info[1]);
   uint32_t key_cert_pair_count = pair_list->Length();
-  grpc_ssl_pem_key_cert_pair *key_cert_pairs = new grpc_ssl_pem_key_cert_pair[
-      key_cert_pair_count];
+  grpc_ssl_pem_key_cert_pair *key_cert_pairs =
+      new grpc_ssl_pem_key_cert_pair[key_cert_pair_count];
 
   Local<String> key_key = Nan::New("private_key").ToLocalChecked();
   Local<String> cert_key = Nan::New("cert_chain").ToLocalChecked();
 
-  for(uint32_t i = 0; i < key_cert_pair_count; i++) {
+  for (uint32_t i = 0; i < key_cert_pair_count; i++) {
     Local<Value> pair_val = Nan::Get(pair_list, i).ToLocalChecked();
     if (!pair_val->IsObject()) {
       delete[] key_cert_pairs;
diff --git a/src/node/ext/server_credentials.h b/src/node/ext/server_credentials.h
index bf279e481c64ec3768ab5ff9d490cf023cc13737..808088f6e24520c897dc5ce6a894bb3a7d1c04d7 100644
--- a/src/node/ext/server_credentials.h
+++ b/src/node/ext/server_credentials.h
@@ -34,8 +34,8 @@
 #ifndef NET_GRPC_NODE_SERVER_CREDENTIALS_H_
 #define NET_GRPC_NODE_SERVER_CREDENTIALS_H_
 
-#include <node.h>
 #include <nan.h>
+#include <node.h>
 #include "grpc/grpc.h"
 #include "grpc/grpc_security.h"
 
diff --git a/src/node/ext/server_uv.cc b/src/node/ext/server_uv.cc
deleted file mode 100644
index bf8b609a63f584798d4a8640487fb2382cd62f05..0000000000000000000000000000000000000000
--- a/src/node/ext/server_uv.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- *
- * Copyright 2017, 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.
- *
- */
-
-#ifdef GRPC_UV
-
-#include "server.h"
-
-#include <node.h>
-#include <nan.h>
-#include "grpc/grpc.h"
-#include "grpc/support/time.h"
-
-#include "call.h"
-#include "completion_queue.h"
-
-namespace grpc {
-namespace node {
-
-using Nan::Callback;
-
-using v8::External;
-using v8::Function;
-using v8::FunctionTemplate;
-using v8::Local;
-using v8::MaybeLocal;
-using v8::Object;
-using v8::Value;
-
-static Callback *shutdown_callback = NULL;
-
-class ServerShutdownOp : public Op {
- public:
-  ServerShutdownOp(grpc_server *server): server(server) {
-  }
-
-  ~ServerShutdownOp() {
-  }
-
-  Local<Value> GetNodeValue() const {
-    return Nan::New<External>(reinterpret_cast<void *>(server));
-  }
-
-  bool ParseOp(Local<Value> value, grpc_op *out) {
-    return true;
-  }
-  bool IsFinalOp() {
-    return false;
-  }
-
-  grpc_server *server;
-
- protected:
-  std::string GetTypeString() const { return "shutdown"; }
-};
-
-Server::Server(grpc_server *server) : wrapped_server(server) {
-}
-
-Server::~Server() {
-  this->ShutdownServer();
-}
-
-NAN_METHOD(ServerShutdownCallback) {
-  if (!info[0]->IsNull()) {
-    return Nan::ThrowError("forceShutdown failed somehow");
-  }
-  MaybeLocal<Object> maybe_result = Nan::To<Object>(info[1]);
-  Local<Object> result = maybe_result.ToLocalChecked();
-  Local<Value> server_val = Nan::Get(
-      result, Nan::New("shutdown").ToLocalChecked()).ToLocalChecked();
-  Local<External> server_extern = server_val.As<External>();
-  grpc_server *server = reinterpret_cast<grpc_server *>(server_extern->Value());
-  grpc_server_destroy(server);
-}
-
-void Server::ShutdownServer() {
-  if (this->wrapped_server != NULL) {
-    if (shutdown_callback == NULL) {
-      Local<FunctionTemplate>callback_tpl =
-          Nan::New<FunctionTemplate>(ServerShutdownCallback);
-      shutdown_callback = new Callback(
-          Nan::GetFunction(callback_tpl).ToLocalChecked());
-    }
-
-    ServerShutdownOp *op = new ServerShutdownOp(this->wrapped_server);
-    unique_ptr<OpVec> ops(new OpVec());
-    ops->push_back(unique_ptr<Op>(op));
-
-    grpc_server_shutdown_and_notify(
-        this->wrapped_server, GetCompletionQueue(),
-        new struct tag(new Callback(**shutdown_callback), ops.release(), NULL));
-    grpc_server_cancel_all_calls(this->wrapped_server);
-    CompletionQueueNext();
-    this->wrapped_server = NULL;
-  }
-}
-
-}  // namespace grpc
-}  // namespace node
-
-#endif /* GRPC_UV */
diff --git a/src/node/ext/slice.cc b/src/node/ext/slice.cc
index 98a80b3d2f9ae8461c6647f237a8d67955c34579..70e73628e79829099b305946d41e45f5c3457029 100644
--- a/src/node/ext/slice.cc
+++ b/src/node/ext/slice.cc
@@ -31,13 +31,12 @@
  *
  */
 
-#include <node.h>
-#include <nan.h>
 #include <grpc/slice.h>
 #include <grpc/support/alloc.h>
+#include <nan.h>
+#include <node.h>
 
 #include "slice.h"
-#include "byte_buffer.h"
 
 namespace grpc {
 namespace node {
@@ -50,19 +49,19 @@ using v8::Value;
 
 namespace {
 void SliceFreeCallback(char *data, void *hint) {
-  grpc_slice *slice = reinterpret_cast<grpc_slice*>(hint);
+  grpc_slice *slice = reinterpret_cast<grpc_slice *>(hint);
   grpc_slice_unref(*slice);
   delete slice;
 }
 
 void string_destroy_func(void *user_data) {
-  delete reinterpret_cast<Nan::Utf8String*>(user_data);
+  delete reinterpret_cast<Nan::Utf8String *>(user_data);
 }
 
 void buffer_destroy_func(void *user_data) {
-  delete reinterpret_cast<PersistentValue*>(user_data);
+  delete reinterpret_cast<PersistentValue *>(user_data);
 }
-} // namespace
+}  // namespace
 
 grpc_slice CreateSliceFromString(const Local<String> source) {
   Nan::HandleScope scope;
@@ -74,28 +73,32 @@ grpc_slice CreateSliceFromString(const Local<String> source) {
 grpc_slice CreateSliceFromBuffer(const Local<Value> source) {
   // Prerequisite: ::node::Buffer::HasInstance(source)
   Nan::HandleScope scope;
-  return grpc_slice_new_with_user_data(::node::Buffer::Data(source),
-                                       ::node::Buffer::Length(source),
-                                       buffer_destroy_func,
-                                       new PersistentValue(source));
+  return grpc_slice_new_with_user_data(
+      ::node::Buffer::Data(source), ::node::Buffer::Length(source),
+      buffer_destroy_func, new PersistentValue(source));
 }
 Local<String> CopyStringFromSlice(const grpc_slice slice) {
   Nan::EscapableHandleScope scope;
   if (GRPC_SLICE_LENGTH(slice) == 0) {
     return scope.Escape(Nan::EmptyString());
   }
-  return scope.Escape(Nan::New<String>(
-      const_cast<char *>(reinterpret_cast<const char *>(GRPC_SLICE_START_PTR(slice))),
-      GRPC_SLICE_LENGTH(slice)).ToLocalChecked());
+  return scope.Escape(
+      Nan::New<String>(const_cast<char *>(reinterpret_cast<const char *>(
+                           GRPC_SLICE_START_PTR(slice))),
+                       GRPC_SLICE_LENGTH(slice))
+          .ToLocalChecked());
 }
 
 Local<Value> CreateBufferFromSlice(const grpc_slice slice) {
   Nan::EscapableHandleScope scope;
   grpc_slice *slice_ptr = new grpc_slice;
   *slice_ptr = grpc_slice_ref(slice);
-  return scope.Escape(MakeFastBuffer(Nan::NewBuffer(
-      const_cast<char *>(reinterpret_cast<const char *>(GRPC_SLICE_START_PTR(*slice_ptr))),
-      GRPC_SLICE_LENGTH(*slice_ptr), SliceFreeCallback, slice_ptr).ToLocalChecked()));
+  return scope.Escape(
+      Nan::NewBuffer(
+          const_cast<char *>(
+              reinterpret_cast<const char *>(GRPC_SLICE_START_PTR(*slice_ptr))),
+          GRPC_SLICE_LENGTH(*slice_ptr), SliceFreeCallback, slice_ptr)
+          .ToLocalChecked());
 }
 
 }  // namespace node
diff --git a/src/node/ext/slice.h b/src/node/ext/slice.h
index 7dcb1bd45a8e3ae395335283722d8d4f7013572d..89c8ecaf7251336bb193258007e49f613a0c46ff 100644
--- a/src/node/ext/slice.h
+++ b/src/node/ext/slice.h
@@ -31,14 +31,15 @@
  *
  */
 
-#include <node.h>
-#include <nan.h>
 #include <grpc/slice.h>
+#include <nan.h>
+#include <node.h>
 
 namespace grpc {
 namespace node {
 
-typedef Nan::Persistent<v8::Value, Nan::CopyablePersistentTraits<v8::Value>> PersistentValue;
+typedef Nan::Persistent<v8::Value, Nan::CopyablePersistentTraits<v8::Value>>
+    PersistentValue;
 
 grpc_slice CreateSliceFromString(const v8::Local<v8::String> source);
 
diff --git a/src/node/ext/timeval.cc b/src/node/ext/timeval.cc
index 9284db62ef6a32b8a26f8555d59b9ad891370716..741c324c66bc0cb081e10c04880afc41a54fac80 100644
--- a/src/node/ext/timeval.cc
+++ b/src/node/ext/timeval.cc
@@ -31,8 +31,8 @@
  *
  */
 
-#include <limits>
 #include <cstdint>
+#include <limits>
 
 #include "grpc/grpc.h"
 #include "grpc/support/time.h"
diff --git a/src/node/health_check/package.json b/src/node/health_check/package.json
index 8376339debe13bb7f123da5551c6299e090788e6..37c9b7a54f5fd0f381937b860f16e54a77d32ae0 100644
--- a/src/node/health_check/package.json
+++ b/src/node/health_check/package.json
@@ -1,6 +1,6 @@
 {
   "name": "grpc-health-check",
-  "version": "1.2.0-dev",
+  "version": "1.4.0-dev",
   "author": "Google Inc.",
   "description": "Health check service for use with gRPC",
   "repository": {
@@ -15,7 +15,7 @@
     }
   ],
   "dependencies": {
-    "grpc": "^1.2.0-dev",
+    "grpc": "^1.4.0-dev",
     "lodash": "^3.9.3",
     "google-protobuf": "^3.0.0"
   },
diff --git a/src/node/index.js b/src/node/index.js
index a294aad8ee6ca2a7261b5281dea9492aa003fa5d..071bfd7927bab798c2bf0920355be32c54cd7242 100644
--- a/src/node/index.js
+++ b/src/node/index.js
@@ -52,42 +52,89 @@ var Metadata = require('./src/metadata.js');
 
 var grpc = require('./src/grpc_extension');
 
+var protobuf_js_5_common = require('./src/protobuf_js_5_common');
+var protobuf_js_6_common = require('./src/protobuf_js_6_common');
+
 grpc.setDefaultRootsPem(fs.readFileSync(SSL_ROOTS_PATH, 'ascii'));
 
 /**
- * Load a gRPC object from an existing ProtoBuf.Reflect object.
- * @param {ProtoBuf.Reflect.Namespace} value The ProtoBuf object to load.
- * @param {Object=} options Options to apply to the loaded object
+ * Load a ProtoBuf.js object as a gRPC object. The options object can provide
+ * the following options:
+ * - binaryAsBase64: deserialize bytes values as base64 strings instead of
+ *   Buffers. Defaults to false
+ * - longsAsStrings: deserialize long values as strings instead of objects.
+ *   Defaults to true
+ * - enumsAsStrings: deserialize enum values as strings instead of numbers.
+ *   Defaults to true
+ * - deprecatedArgumentOrder: Use the beta method argument order for client
+ *   methods, with optional arguments after the callback. Defaults to false.
+ *   This option is only a temporary stopgap measure to smooth an API breakage.
+ *   It is deprecated, and new code should not use it.
+ * - protobufjsVersion: Available values are 5, 6, and 'detect'. 5 and 6
+ *   respectively indicate that an object from the corresponding version of
+ *   ProtoBuf.js is provided in the value argument. If the option is 'detect',
+ *   gRPC will guess what the version is based on the structure of the value.
+ *   Defaults to 'detect'.
+ * @param {Object} value The ProtoBuf.js reflection object to load
+ * @param {Object=} options Options to apply to the loaded file
  * @return {Object<string, *>} The resulting gRPC object
  */
 exports.loadObject = function loadObject(value, options) {
-  var result = {};
-  if (value.className === 'Namespace') {
-    _.each(value.children, function(child) {
-      result[child.name] = loadObject(child, options);
-    });
-    return result;
-  } else if (value.className === 'Service') {
-    return client.makeProtobufClientConstructor(value, options);
-  } else if (value.className === 'Message' || value.className === 'Enum') {
-    return value.build();
+  options = _.defaults(options, common.defaultGrpcOptions);
+  options = _.defaults(options, {'protobufjsVersion': 'detect'});
+  var protobufjsVersion;
+  if (options.protobufjsVersion === 'detect') {
+    if (protobuf_js_6_common.isProbablyProtobufJs6(value)) {
+      protobufjsVersion = 6;
+    } else if (protobuf_js_5_common.isProbablyProtobufJs5(value)) {
+      protobufjsVersion = 5;
+    } else {
+      var error_message = 'Could not detect ProtoBuf.js version. Please ' +
+          'specify the version number with the "protobufjs_version" option';
+      throw new Error(error_message);
+    }
   } else {
-    return value;
+    protobufjsVersion = options.protobufjsVersion;
+  }
+  switch (protobufjsVersion) {
+    case 6: return protobuf_js_6_common.loadObject(value, options);
+    case 5:
+    var deprecation_message = 'Calling grpc.loadObject with an object ' +
+        'generated by ProtoBuf.js 5 is deprecated. Please upgrade to ' +
+        'ProtoBuf.js 6.';
+    common.log(grpc.logVerbosity.INFO, deprecation_message);
+    return protobuf_js_5_common.loadObject(value, options);
+    default:
+    throw new Error('Unrecognized protobufjsVersion', protobufjsVersion);
   }
 };
 
 var loadObject = exports.loadObject;
 
+function applyProtoRoot(filename, root) {
+  if (_.isString(filename)) {
+    return filename;
+  }
+  filename.root = path.resolve(filename.root) + '/';
+  root.resolvePath = function(originPath, importPath, alreadyNormalized) {
+    return ProtoBuf.util.path.resolve(filename.root,
+                                      importPath,
+                                      alreadyNormalized);
+  };
+  return filename.file;
+}
+
 /**
  * Load a gRPC object from a .proto file. The options object can provide the
  * following options:
- * - convertFieldsToCamelCase: Loads this file with that option on protobuf.js
- *   set as specified. See
- *   https://github.com/dcodeIO/protobuf.js/wiki/Advanced-options for details
+ * - convertFieldsToCamelCase: Load this file with field names in camel case
+ *   instead of their original case
  * - binaryAsBase64: deserialize bytes values as base64 strings instead of
  *   Buffers. Defaults to false
  * - longsAsStrings: deserialize long values as strings instead of objects.
  *   Defaults to true
+ * - enumsAsStrings: deserialize enum values as strings instead of numbers.
+ *   Defaults to true
  * - deprecatedArgumentOrder: Use the beta method argument order for client
  *   methods, with optional arguments after the callback. Defaults to false.
  *   This option is only a temporary stopgap measure to smooth an API breakage.
@@ -99,29 +146,17 @@ var loadObject = exports.loadObject;
  * @return {Object<string, *>} The resulting gRPC object
  */
 exports.load = function load(filename, format, options) {
-  if (!format) {
-    format = 'proto';
-  }
-  var convertFieldsToCamelCaseOriginal = ProtoBuf.convertFieldsToCamelCase;
-  if(options && options.hasOwnProperty('convertFieldsToCamelCase')) {
-    ProtoBuf.convertFieldsToCamelCase = options.convertFieldsToCamelCase;
-  }
-  var builder;
-  try {
-    switch(format) {
-      case 'proto':
-      builder = ProtoBuf.loadProtoFile(filename);
-      break;
-      case 'json':
-      builder = ProtoBuf.loadJsonFile(filename);
-      break;
-      default:
-      throw new Error('Unrecognized format "' + format + '"');
-    }
-  } finally {
-    ProtoBuf.convertFieldsToCamelCase = convertFieldsToCamelCaseOriginal;
-  }
-  return loadObject(builder.ns, options);
+  /* Note: format is currently unused, because the API for loading a proto
+     file or a JSON file is identical in Protobuf.js 6. In the future, there is
+     still the possibility of adding other formats that would be loaded
+     differently */
+  options = _.defaults(options, common.defaultGrpcOptions);
+  options.protobufjs_version = 6;
+  var root = new ProtoBuf.Root();
+  var parse_options = {keepCase: !options.convertFieldsToCamelCase};
+  return loadObject(root.loadSync(applyProtoRoot(filename, root),
+                                  parse_options),
+                    options);
 };
 
 var log_template = _.template(
diff --git a/src/node/interop/interop_server.js b/src/node/interop/interop_server.js
index 05f52a1083de9d6a2e54d876405af7427518f775..83b8a7c1ec3c36b4e133f0e66950d1bdbaa08c21 100644
--- a/src/node/interop/interop_server.js
+++ b/src/node/interop/interop_server.js
@@ -228,7 +228,7 @@ function getServer(port, tls) {
     server_creds = grpc.ServerCredentials.createInsecure();
   }
   var server = new grpc.Server(options);
-  server.addProtoService(testProto.TestService.service, {
+  server.addService(testProto.TestService.service, {
     emptyCall: handleEmpty,
     unaryCall: handleUnary,
     streamingOutputCall: handleStreamingOutput,
diff --git a/src/node/performance/benchmark_client.js b/src/node/performance/benchmark_client.js
index 5ef5260a96d7e0e740e135372d80af659619a44f..e7c426b2ff5befde3572e2c48fdc41af16730d63 100644
--- a/src/node/performance/benchmark_client.js
+++ b/src/node/performance/benchmark_client.js
@@ -88,7 +88,10 @@ function timeDiffToNanos(time_diff) {
  */
 function BenchmarkClient(server_targets, channels, histogram_params,
     security_params) {
-  var options = {};
+  var options = {
+    "grpc.max_receive_message_length": -1,
+    "grpc.max_send_message_length": -1
+  };
   var creds;
   if (security_params) {
     var ca_path;
@@ -180,6 +183,8 @@ BenchmarkClient.prototype.startClosedLoop = function(
 
   self.last_wall_time = process.hrtime();
 
+  self.last_usage = process.cpuUsage();
+
   var makeCall;
 
   var argument;
@@ -270,6 +275,8 @@ BenchmarkClient.prototype.startPoisson = function(
 
   self.last_wall_time = process.hrtime();
 
+  self.last_usage = process.cpuUsage();
+
   var makeCall;
 
   var argument;
@@ -354,9 +361,11 @@ BenchmarkClient.prototype.startPoisson = function(
  */
 BenchmarkClient.prototype.mark = function(reset) {
   var wall_time_diff = process.hrtime(this.last_wall_time);
+  var usage_diff = process.cpuUsage(this.last_usage);
   var histogram = this.histogram;
   if (reset) {
     this.last_wall_time = process.hrtime();
+    this.last_usage = process.cpuUsage();
     this.histogram = new Histogram(histogram.resolution,
                                    histogram.max_possible);
   }
@@ -371,9 +380,8 @@ BenchmarkClient.prototype.mark = function(reset) {
       count: histogram.getCount()
     },
     time_elapsed: wall_time_diff[0] + wall_time_diff[1] / 1e9,
-    // Not sure how to measure these values
-    time_user: 0,
-    time_system: 0
+    time_user: usage_diff.user / 1000000,
+    time_system: usage_diff.system / 1000000
   };
 };
 
diff --git a/src/node/performance/benchmark_client_express.js b/src/node/performance/benchmark_client_express.js
index 675eb5f28847926f7832c615eec82d7091b5ad79..157bf1b6dece10b2f8fd679de5b70ffa2d82f047 100644
--- a/src/node/performance/benchmark_client_express.js
+++ b/src/node/performance/benchmark_client_express.js
@@ -93,9 +93,8 @@ function BenchmarkClient(server_targets, channels, histogram_params,
 
   for (var i = 0; i < channels; i++) {
     var host_port;
-    host_port = server_targets[i % server_targets.length].split(':')
+    host_port = server_targets[i % server_targets.length].split(':');
     var new_options = _.assign({hostname: host_port[0], port: +host_port[1]}, options);
-    new_options.agent = new protocol.Agent(new_options);
     this.client_options[i] = new_options;
   }
 
@@ -137,6 +136,7 @@ BenchmarkClient.prototype.startClosedLoop = function(
   }
 
   self.last_wall_time = process.hrtime();
+  self.last_usage = process.cpuUsage();
 
   var argument = {
     response_size: resp_size,
@@ -149,6 +149,17 @@ BenchmarkClient.prototype.startClosedLoop = function(
     if (self.running) {
       self.pending_calls++;
       var start_time = process.hrtime();
+      function finishCall(success) {
+        if (success) {
+          var time_diff = process.hrtime(start_time);
+          self.histogram.add(timeDiffToNanos(time_diff));
+        }
+        makeCall(client_options);
+        self.pending_calls--;
+        if ((!self.running) && self.pending_calls == 0) {
+          self.emit('finished');
+        }
+      }
       var req = self.request(client_options, function(res) {
         var res_data = '';
         res.on('data', function(data) {
@@ -156,18 +167,16 @@ BenchmarkClient.prototype.startClosedLoop = function(
         });
         res.on('end', function() {
           JSON.parse(res_data);
-          var time_diff = process.hrtime(start_time);
-          self.histogram.add(timeDiffToNanos(time_diff));
-          makeCall(client_options);
-          self.pending_calls--;
-          if ((!self.running) && self.pending_calls == 0) {
-            self.emit('finished');
-          }
+          finishCall(true);
         });
       });
       req.write(JSON.stringify(argument));
       req.end();
       req.on('error', function(error) {
+        if (error.code === 'ECONNRESET' || error.code === 'ETIMEDOUT') {
+          finishCall(false);
+          return;
+        }
         self.emit('error', new Error('Client error: ' + error.message));
         self.running = false;
       });
@@ -198,6 +207,7 @@ BenchmarkClient.prototype.startPoisson = function(
   }
 
   self.last_wall_time = process.hrtime();
+  self.last_usage = process.cpuUsage();
 
   var argument = {
     response_size: resp_size,
@@ -255,9 +265,11 @@ BenchmarkClient.prototype.startPoisson = function(
  */
 BenchmarkClient.prototype.mark = function(reset) {
   var wall_time_diff = process.hrtime(this.last_wall_time);
+  var usage_diff = process.cpuUsage(this.last_usage);
   var histogram = this.histogram;
   if (reset) {
     this.last_wall_time = process.hrtime();
+    this.last_usage = process.cpuUsage();
     this.histogram = new Histogram(histogram.resolution,
                                    histogram.max_possible);
   }
@@ -272,9 +284,8 @@ BenchmarkClient.prototype.mark = function(reset) {
       count: histogram.getCount()
     },
     time_elapsed: wall_time_diff[0] + wall_time_diff[1] / 1e9,
-    // Not sure how to measure these values
-    time_user: 0,
-    time_system: 0
+    time_user: usage_diff.user / 1000000,
+    time_system: usage_diff.system / 1000000
   };
 };
 
diff --git a/src/node/performance/benchmark_server.js b/src/node/performance/benchmark_server.js
index 6abde2e17afb26722efc88c34a26fbc9198d0d28..a4d5ee1c26c29cc749395340c49e350f137bc40d 100644
--- a/src/node/performance/benchmark_server.js
+++ b/src/node/performance/benchmark_server.js
@@ -88,6 +88,13 @@ function streamingCall(call) {
   });
 }
 
+function makeUnaryGenericCall(response_size) {
+  var response = zeroBuffer(response_size);
+  return function unaryGenericCall(call, callback) {
+    callback(null, response);
+  };
+}
+
 function makeStreamingGenericCall(response_size) {
   var response = zeroBuffer(response_size);
   return function streamingGenericCall(call) {
@@ -125,14 +132,20 @@ function BenchmarkServer(host, port, tls, generic, response_size) {
     server_creds = grpc.ServerCredentials.createInsecure();
   }
 
-  var server = new grpc.Server();
+  var options = {
+    "grpc.max_receive_message_length": -1,
+    "grpc.max_send_message_length": -1
+  };
+
+  var server = new grpc.Server(options);
   this.port = server.bind(host + ':' + port, server_creds);
   if (generic) {
     server.addService(genericService, {
+      unaryCall: makeUnaryGenericCall(response_size),
       streamingCall: makeStreamingGenericCall(response_size)
     });
   } else {
-    server.addProtoService(serviceProto.BenchmarkService.service, {
+    server.addService(serviceProto.BenchmarkService.service, {
       unaryCall: unaryCall,
       streamingCall: streamingCall
     });
@@ -148,6 +161,7 @@ util.inherits(BenchmarkServer, EventEmitter);
 BenchmarkServer.prototype.start = function() {
   this.server.start();
   this.last_wall_time = process.hrtime();
+  this.last_usage = process.cpuUsage();
   this.emit('started');
 };
 
@@ -167,14 +181,15 @@ BenchmarkServer.prototype.getPort = function() {
  */
 BenchmarkServer.prototype.mark = function(reset) {
   var wall_time_diff = process.hrtime(this.last_wall_time);
+  var usage_diff = process.cpuUsage(this.last_usage);
   if (reset) {
     this.last_wall_time = process.hrtime();
+    this.last_usage = process.cpuUsage();
   }
   return {
     time_elapsed: wall_time_diff[0] + wall_time_diff[1] / 1e9,
-    // Not sure how to measure these values
-    time_user: 0,
-    time_system: 0
+    time_user: usage_diff.user / 1000000,
+    time_system: usage_diff.system / 1000000
   };
 };
 
diff --git a/src/node/performance/benchmark_server_express.js b/src/node/performance/benchmark_server_express.js
index 065bcf660b6e5c0e4dc0a49b59d1513b52a55fb1..fab4f5307c1cd9f93e59555f3984d27db3aab07a 100644
--- a/src/node/performance/benchmark_server_express.js
+++ b/src/node/performance/benchmark_server_express.js
@@ -46,7 +46,7 @@ var EventEmitter = require('events');
 var util = require('util');
 
 var express = require('express');
-var bodyParser = require('body-parser')
+var bodyParser = require('body-parser');
 
 function unaryCall(req, res) {
   var reqObj = req.body;
@@ -56,7 +56,7 @@ function unaryCall(req, res) {
 
 function BenchmarkServer(host, port, tls, generic, response_size) {
   var app = express();
-  app.use(bodyParser.json())
+  app.use(bodyParser.json());
   app.put('/serviceProto.BenchmarkService.service/unaryCall', unaryCall);
   this.input_host = host;
   this.input_port = port;
@@ -81,6 +81,7 @@ BenchmarkServer.prototype.start = function() {
   var self = this;
   this.server.listen(this.input_port, this.input_hostname, function() {
     self.last_wall_time = process.hrtime();
+    self.last_usage = process.cpuUsage();
     self.emit('started');
   });
 };
@@ -91,14 +92,15 @@ BenchmarkServer.prototype.getPort = function() {
 
 BenchmarkServer.prototype.mark = function(reset) {
   var wall_time_diff = process.hrtime(this.last_wall_time);
+  var usage_diff = process.cpuUsage(this.last_usage);
   if (reset) {
     this.last_wall_time = process.hrtime();
+    this.last_usage = process.cpuUsage();
   }
   return {
     time_elapsed: wall_time_diff[0] + wall_time_diff[1] / 1e9,
-    // Not sure how to measure these values
-    time_user: 0,
-    time_system: 0
+    time_user: usage_diff.user / 1000000,
+    time_system: usage_diff.system / 1000000
   };
 };
 
diff --git a/src/node/performance/generic_service.js b/src/node/performance/generic_service.js
index ce09cc4336cd6ba23889ee20c4e5e7a5fc54d63f..c936ac30bca57d4dbd4308229938393c338e6c22 100644
--- a/src/node/performance/generic_service.js
+++ b/src/node/performance/generic_service.js
@@ -34,8 +34,17 @@
 var _ = require('lodash');
 
 module.exports = {
+  'unaryCall' : {
+    path: '/grpc.testing.BenchmarkService/UnaryCall',
+    requestStream: false,
+    responseStream: false,
+    requestSerialize: _.identity,
+    requestDeserialize: _.identity,
+    responseSerialize: _.identity,
+    responseDeserialize: _.identity
+  },
   'streamingCall' : {
-    path: '/grpc.testing/BenchmarkService',
+    path: '/grpc.testing.BenchmarkService/StreamingCall',
     requestStream: true,
     responseStream: true,
     requestSerialize: _.identity,
diff --git a/src/node/performance/worker.js b/src/node/performance/worker.js
index 030bf7d7ba052683d46800e4be581930909203a3..90a9b7d59cd779f29aa195c037aa4486ba2eb020 100644
--- a/src/node/performance/worker.js
+++ b/src/node/performance/worker.js
@@ -44,8 +44,8 @@ var serviceProto = grpc.load({
 function runServer(port, benchmark_impl) {
   var server_creds = grpc.ServerCredentials.createInsecure();
   var server = new grpc.Server();
-  server.addProtoService(serviceProto.WorkerService.service,
-                         new WorkerServiceImpl(benchmark_impl, server));
+  server.addService(serviceProto.WorkerService.service,
+                    new WorkerServiceImpl(benchmark_impl, server));
   var address = '0.0.0.0:' + port;
   server.bind(address, server_creds);
   server.start();
diff --git a/src/node/performance/worker_service_impl.js b/src/node/performance/worker_service_impl.js
index 38888a7219a6ca8123709d0956c20162106dbb2c..fa864f992557f7316b052a2c75b67a5a5e59aa57 100644
--- a/src/node/performance/worker_service_impl.js
+++ b/src/node/performance/worker_service_impl.js
@@ -89,6 +89,7 @@ module.exports = function WorkerServiceImpl(benchmark_impl, server) {
           default:
           call.emit('error', new Error('Unsupported PayloadConfig type' +
               setup.payload_config.payload));
+          return;
         }
         switch (setup.load_params.load) {
           case 'closed_loop':
@@ -103,6 +104,7 @@ module.exports = function WorkerServiceImpl(benchmark_impl, server) {
           default:
           call.emit('error', new Error('Unsupported LoadParams type' +
               setup.load_params.load));
+          return;
         }
         stats = client.mark();
         call.write({
@@ -137,8 +139,27 @@ module.exports = function WorkerServiceImpl(benchmark_impl, server) {
       switch (request.argtype) {
         case 'setup':
         console.log('ServerConfig %j', request.setup);
+        var setup = request.setup;
+        var resp_size, generic;
+        if (setup.payload_config) {
+          switch (setup.payload_config.payload) {
+            case 'bytebuf_params':
+            resp_size = setup.payload_config.bytebuf_params.resp_size;
+            generic = true;
+            break;
+            case 'simple_params':
+            resp_size = setup.payload_config.simple_params.resp_size;
+            generic = false;
+            break;
+            default:
+            call.emit('error', new Error('Unsupported PayloadConfig type' +
+                setup.payload_config.payload));
+            return;
+          }
+        }
         server = new BenchmarkServer('[::]', request.setup.port,
-                                     request.setup.security_params);
+                                     request.setup.security_params,
+                                     generic, resp_size);
         server.on('started', function() {
           stats = server.mark();
           call.write({
diff --git a/src/node/src/client.js b/src/node/src/client.js
index 44081a3a6cd42965d0364d3e3c09fa438be3d6ab..1aaf35c16cbc918bdd220e3ba04b2832817576db 100644
--- a/src/node/src/client.js
+++ b/src/node/src/client.js
@@ -780,6 +780,8 @@ exports.makeClientConstructor = function(methods, serviceName,
     _.assign(Client.prototype[name], attrs);
   });
 
+  Client.service = methods;
+
   return Client;
 };
 
@@ -822,26 +824,6 @@ exports.waitForClientReady = function(client, deadline, callback) {
   checkState();
 };
 
-/**
- * Creates a constructor for clients for the given service
- * @param {ProtoBuf.Reflect.Service} service The service to generate a client
- *     for
- * @param {Object=} options Options to apply to the client
- * @return {function(string, Object)} New client constructor
- */
-exports.makeProtobufClientConstructor =  function(service, options) {
-  var method_attrs = common.getProtobufServiceAttrs(service, options);
-  if (!options) {
-    options = {deprecatedArgumentOrder: false};
-  }
-  var Client = exports.makeClientConstructor(
-      method_attrs, common.fullyQualifiedName(service),
-      options);
-  Client.service = service;
-  Client.service.grpc_options = options;
-  return Client;
-};
-
 /**
  * Map of status code names to status codes
  */
diff --git a/src/node/src/common.js b/src/node/src/common.js
index 98eabf5c0b895cc5f7783ee10588069e6f3ef744..757969dbddb147a162738d6e61977cd6904d7229 100644
--- a/src/node/src/common.js
+++ b/src/node/src/common.js
@@ -41,74 +41,6 @@
 
 var _ = require('lodash');
 
-/**
- * Get a function that deserializes a specific type of protobuf.
- * @param {function()} cls The constructor of the message type to deserialize
- * @param {bool=} binaryAsBase64 Deserialize bytes fields as base64 strings
- *     instead of Buffers. Defaults to false
- * @param {bool=} longsAsStrings Deserialize long values as strings instead of
- *     objects. Defaults to true
- * @return {function(Buffer):cls} The deserialization function
- */
-exports.deserializeCls = function deserializeCls(cls, binaryAsBase64,
-                                                 longsAsStrings) {
-  if (binaryAsBase64 === undefined || binaryAsBase64 === null) {
-    binaryAsBase64 = false;
-  }
-  if (longsAsStrings === undefined || longsAsStrings === null) {
-    longsAsStrings = true;
-  }
-  /**
-   * Deserialize a buffer to a message object
-   * @param {Buffer} arg_buf The buffer to deserialize
-   * @return {cls} The resulting object
-   */
-  return function deserialize(arg_buf) {
-    // Convert to a native object with binary fields as Buffers (first argument)
-    // and longs as strings (second argument)
-    return cls.decode(arg_buf).toRaw(binaryAsBase64, longsAsStrings);
-  };
-};
-
-var deserializeCls = exports.deserializeCls;
-
-/**
- * Get a function that serializes objects to a buffer by protobuf class.
- * @param {function()} Cls The constructor of the message type to serialize
- * @return {function(Cls):Buffer} The serialization function
- */
-exports.serializeCls = function serializeCls(Cls) {
-  /**
-   * Serialize an object to a Buffer
-   * @param {Object} arg The object to serialize
-   * @return {Buffer} The serialized object
-   */
-  return function serialize(arg) {
-    return new Buffer(new Cls(arg).encode().toBuffer());
-  };
-};
-
-var serializeCls = exports.serializeCls;
-
-/**
- * Get the fully qualified (dotted) name of a ProtoBuf.Reflect value.
- * @param {ProtoBuf.Reflect.Namespace} value The value to get the name of
- * @return {string} The fully qualified name of the value
- */
-exports.fullyQualifiedName = function fullyQualifiedName(value) {
-  if (value === null || value === undefined) {
-    return '';
-  }
-  var name = value.name;
-  var parent_name = fullyQualifiedName(value.parent);
-  if (parent_name !== '') {
-    name = parent_name + '.' + name;
-  }
-  return name;
-};
-
-var fullyQualifiedName = exports.fullyQualifiedName;
-
 /**
  * Wrap a function to pass null-like values through without calling it. If no
  * function is given, just uses the identity;
@@ -127,43 +59,6 @@ exports.wrapIgnoreNull = function wrapIgnoreNull(func) {
   };
 };
 
-/**
- * Return a map from method names to method attributes for the service.
- * @param {ProtoBuf.Reflect.Service} service The service to get attributes for
- * @param {Object=} options Options to apply to these attributes
- * @return {Object} The attributes map
- */
-exports.getProtobufServiceAttrs = function getProtobufServiceAttrs(service,
-                                                                   options) {
-  var prefix = '/' + fullyQualifiedName(service) + '/';
-  var binaryAsBase64, longsAsStrings;
-  if (options) {
-    binaryAsBase64 = options.binaryAsBase64;
-    longsAsStrings = options.longsAsStrings;
-  }
-  /* This slightly awkward construction is used to make sure we only use
-     lodash@3.10.1-compatible functions. A previous version used
-     _.fromPairs, which would be cleaner, but was introduced in lodash
-     version 4 */
-  return _.zipObject(_.map(service.children, function(method) {
-    return _.camelCase(method.name);
-  }), _.map(service.children, function(method) {
-    return {
-      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),
-      responseSerialize: serializeCls(method.resolvedResponseType.build()),
-      responseDeserialize: deserializeCls(method.resolvedResponseType.build(),
-                                          binaryAsBase64, longsAsStrings)
-    };
-  }));
-};
-
 /**
  * The logger object for the gRPC module. Defaults to console.
  */
@@ -184,3 +79,14 @@ exports.log = function log(severity, message) {
     exports.logger.error(message);
   }
 };
+
+/**
+ * Default options for loading proto files into gRPC
+ */
+exports.defaultGrpcOptions = {
+  convertFieldsToCamelCase: false,
+  binaryAsBase64: false,
+  longsAsStrings: true,
+  enumsAsStrings: true,
+  deprecatedArgumentOrder: false
+};
diff --git a/src/node/src/protobuf_js_5_common.js b/src/node/src/protobuf_js_5_common.js
new file mode 100644
index 0000000000000000000000000000000000000000..62cf2f4acaa4ffffc600200ac7ace73d575a09d8
--- /dev/null
+++ b/src/node/src/protobuf_js_5_common.js
@@ -0,0 +1,181 @@
+/*
+ *
+ * Copyright 2017, 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.
+ *
+ */
+
+'use strict';
+
+var _ = require('lodash');
+var client = require('./client');
+
+/**
+ * Get a function that deserializes a specific type of protobuf.
+ * @param {function()} cls The constructor of the message type to deserialize
+ * @param {bool=} binaryAsBase64 Deserialize bytes fields as base64 strings
+ *     instead of Buffers. Defaults to false
+ * @param {bool=} longsAsStrings Deserialize long values as strings instead of
+ *     objects. Defaults to true
+ * @return {function(Buffer):cls} The deserialization function
+ */
+exports.deserializeCls = function deserializeCls(cls, binaryAsBase64,
+                                                 longsAsStrings) {
+  /**
+   * Deserialize a buffer to a message object
+   * @param {Buffer} arg_buf The buffer to deserialize
+   * @return {cls} The resulting object
+   */
+  return function deserialize(arg_buf) {
+    // Convert to a native object with binary fields as Buffers (first argument)
+    // and longs as strings (second argument)
+    return cls.decode(arg_buf).toRaw(binaryAsBase64, longsAsStrings);
+  };
+};
+
+var deserializeCls = exports.deserializeCls;
+
+/**
+ * Get a function that serializes objects to a buffer by protobuf class.
+ * @param {function()} Cls The constructor of the message type to serialize
+ * @return {function(Cls):Buffer} The serialization function
+ */
+exports.serializeCls = function serializeCls(Cls) {
+  /**
+   * Serialize an object to a Buffer
+   * @param {Object} arg The object to serialize
+   * @return {Buffer} The serialized object
+   */
+  return function serialize(arg) {
+    return new Buffer(new Cls(arg).encode().toBuffer());
+  };
+};
+
+var serializeCls = exports.serializeCls;
+
+/**
+ * Get the fully qualified (dotted) name of a ProtoBuf.Reflect value.
+ * @param {ProtoBuf.Reflect.Namespace} value The value to get the name of
+ * @return {string} The fully qualified name of the value
+ */
+exports.fullyQualifiedName = function fullyQualifiedName(value) {
+  if (value === null || value === undefined) {
+    return '';
+  }
+  var name = value.name;
+  var parent_name = fullyQualifiedName(value.parent);
+  if (parent_name !== '') {
+    name = parent_name + '.' + name;
+  }
+  return name;
+};
+
+var fullyQualifiedName = exports.fullyQualifiedName;
+
+/**
+ * Return a map from method names to method attributes for the service.
+ * @param {ProtoBuf.Reflect.Service} service The service to get attributes for
+ * @param {Object=} options Options to apply to these attributes
+ * @return {Object} The attributes map
+ */
+exports.getProtobufServiceAttrs = function getProtobufServiceAttrs(service,
+                                                                   options) {
+  var prefix = '/' + fullyQualifiedName(service) + '/';
+  var binaryAsBase64, longsAsStrings;
+  if (options) {
+    binaryAsBase64 = options.binaryAsBase64;
+    longsAsStrings = options.longsAsStrings;
+  }
+  /* This slightly awkward construction is used to make sure we only use
+     lodash@3.10.1-compatible functions. A previous version used
+     _.fromPairs, which would be cleaner, but was introduced in lodash
+     version 4 */
+  return _.zipObject(_.map(service.children, function(method) {
+    return _.camelCase(method.name);
+  }), _.map(service.children, function(method) {
+    return {
+      originalName: method.name,
+      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),
+      responseSerialize: serializeCls(method.resolvedResponseType.build()),
+      responseDeserialize: deserializeCls(method.resolvedResponseType.build(),
+                                          binaryAsBase64, longsAsStrings)
+    };
+  }));
+};
+
+var getProtobufServiceAttrs = exports.getProtobufServiceAttrs;
+
+/**
+ * Load a gRPC object from an existing ProtoBuf.Reflect object.
+ * @param {ProtoBuf.Reflect.Namespace} value The ProtoBuf object to load.
+ * @param {Object=} options Options to apply to the loaded object
+ * @return {Object<string, *>} The resulting gRPC object
+ */
+exports.loadObject = function loadObject(value, options) {
+  var result = {};
+  if (!value) {
+    return value;
+  }
+  if (value.hasOwnProperty('ns')) {
+    return loadObject(value.ns, options);
+  }
+  if (value.className === 'Namespace') {
+    _.each(value.children, function(child) {
+      result[child.name] = loadObject(child, options);
+    });
+    return result;
+  } else if (value.className === 'Service') {
+    return client.makeClientConstructor(getProtobufServiceAttrs(value, options),
+                                        options);
+  } else if (value.className === 'Message' || value.className === 'Enum') {
+    return value.build();
+  } else {
+    return value;
+  }
+};
+
+/**
+ * The primary purpose of this method is to distinguish between reflection
+ * objects from different versions of ProtoBuf.js. This is just a heuristic,
+ * checking for properties that are (currently) specific to this version of
+ * ProtoBuf.js
+ * @param {Object} obj The object to check
+ * @return {boolean} Whether the object appears to be a Protobuf.js 5
+ *   ReflectionObject
+ */
+exports.isProbablyProtobufJs5 = function isProbablyProtobufJs5(obj) {
+  return _.isArray(obj.children) && (typeof obj.build === 'function');
+};
diff --git a/src/node/src/protobuf_js_6_common.js b/src/node/src/protobuf_js_6_common.js
new file mode 100644
index 0000000000000000000000000000000000000000..00f11f27363857ea30dfeb2f567fcf955040783a
--- /dev/null
+++ b/src/node/src/protobuf_js_6_common.js
@@ -0,0 +1,170 @@
+/*
+ *
+ * Copyright 2017, 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.
+ *
+ */
+
+'use strict';
+
+var _ = require('lodash');
+var client = require('./client');
+
+/**
+ * Get a function that deserializes a specific type of protobuf.
+ * @param {function()} cls The constructor of the message type to deserialize
+ * @param {bool=} binaryAsBase64 Deserialize bytes fields as base64 strings
+ *     instead of Buffers. Defaults to false
+ * @param {bool=} longsAsStrings Deserialize long values as strings instead of
+ *     objects. Defaults to true
+ * @return {function(Buffer):cls} The deserialization function
+ */
+exports.deserializeCls = function deserializeCls(cls, options) {
+  var conversion_options = {
+    defaults: true,
+    bytes: options.binaryAsBase64 ? String : Buffer,
+    longs: options.longsAsStrings ? String : null,
+    enums: options.enumsAsStrings ? String : null,
+    oneofs: true
+  };
+  /**
+   * Deserialize a buffer to a message object
+   * @param {Buffer} arg_buf The buffer to deserialize
+   * @return {cls} The resulting object
+   */
+  return function deserialize(arg_buf) {
+    return cls.decode(arg_buf).toObject(conversion_options);
+  };
+};
+
+var deserializeCls = exports.deserializeCls;
+
+/**
+ * Get a function that serializes objects to a buffer by protobuf class.
+ * @param {function()} Cls The constructor of the message type to serialize
+ * @return {function(Cls):Buffer} The serialization function
+ */
+exports.serializeCls = function serializeCls(cls) {
+  /**
+   * Serialize an object to a Buffer
+   * @param {Object} arg The object to serialize
+   * @return {Buffer} The serialized object
+   */
+  return function serialize(arg) {
+    var message = cls.fromObject(arg);
+    return cls.encode(message).finish();
+  };
+};
+
+var serializeCls = exports.serializeCls;
+
+/**
+ * Get the fully qualified (dotted) name of a ProtoBuf.Reflect value.
+ * @param {ProtoBuf.ReflectionObject} value The value to get the name of
+ * @return {string} The fully qualified name of the value
+ */
+exports.fullyQualifiedName = function fullyQualifiedName(value) {
+  if (value === null || value === undefined) {
+    return '';
+  }
+  var name = value.name;
+  var parent_fqn = fullyQualifiedName(value.parent);
+  if (parent_fqn !== '') {
+    name = parent_fqn + '.' + name;
+  }
+  return name;
+};
+
+var fullyQualifiedName = exports.fullyQualifiedName;
+
+/**
+ * Return a map from method names to method attributes for the service.
+ * @param {ProtoBuf.Service} service The service to get attributes for
+ * @param {Object=} options Options to apply to these attributes
+ * @return {Object} The attributes map
+ */
+exports.getProtobufServiceAttrs = function getProtobufServiceAttrs(service,
+                                                                   options) {
+  var prefix = '/' + fullyQualifiedName(service) + '/';
+  service.resolveAll();
+  return _.zipObject(_.map(service.methods, function(method) {
+    return _.camelCase(method.name);
+  }), _.map(service.methods, function(method) {
+    return {
+      originalName: method.name,
+      path: prefix + method.name,
+      requestStream: !!method.requestStream,
+      responseStream: !!method.responseStream,
+      requestType: method.resolvedRequestType,
+      responseType: method.resolvedResponseType,
+      requestSerialize: serializeCls(method.resolvedRequestType),
+      requestDeserialize: deserializeCls(method.resolvedRequestType, options),
+      responseSerialize: serializeCls(method.resolvedResponseType),
+      responseDeserialize: deserializeCls(method.resolvedResponseType, options)
+    };
+  }));
+};
+
+var getProtobufServiceAttrs = exports.getProtobufServiceAttrs;
+
+exports.loadObject = function loadObject(value, options) {
+  var result = {};
+  if (!value) {
+    return value;
+  }
+  if (value.hasOwnProperty('methods')) {
+    // It's a service object
+    var service_attrs = getProtobufServiceAttrs(value, options);
+    return client.makeClientConstructor(service_attrs);
+  }
+
+  if (value.hasOwnProperty('nested')) {
+    // It's a namespace or root object
+    _.each(value.nested, function(nested, name) {
+      result[name] = loadObject(nested, options);
+    });
+    return result;
+  }
+
+  // Otherwise, it's not something we need to change
+  return value;
+};
+
+/**
+ * The primary purpose of this method is to distinguish between reflection
+ * objects from different versions of ProtoBuf.js. This is just a heuristic,
+ * checking for properties that are (currently) specific to this version of
+ * ProtoBuf.js
+ * @param {Object} obj The object to check
+ * @return {boolean} Whether the object appears to be a Protobuf.js 6
+ *   ReflectionObject
+ */
+exports.isProbablyProtobufJs6 = function isProbablyProtobufJs6(obj) {
+  return (typeof obj.root === 'object') && (typeof obj.resolve === 'function');
+};
diff --git a/src/node/src/server.js b/src/node/src/server.js
index 8a7eff507d03a691a8cd412475ca56928f7a02c8..3450abed08f57fc90c43bb91491e92288ac684e1 100644
--- a/src/node/src/server.js
+++ b/src/node/src/server.js
@@ -728,7 +728,7 @@ var defaultHandler = {
  *     method implementation for the provided service.
  */
 Server.prototype.addService = function(service, implementation) {
-  if (!_.isObjectLike(service) || !_.isObjectLike(implementation)) {
+  if (!_.isObject(service) || !_.isObject(implementation)) {
     throw new Error('addService requires two objects as arguments');
   }
   if (_.keys(service).length === 0) {
@@ -755,9 +755,16 @@ Server.prototype.addService = function(service, implementation) {
     }
     var impl;
     if (implementation[name] === undefined) {
-      common.log(grpc.logVerbosity.ERROR, 'Method handler for ' +
-          attrs.path + ' expected but not provided');
-      impl = defaultHandler[method_type];
+      /* Handle the case where the method is passed with the name exactly as
+         written in the proto file, instead of using JavaScript function
+         naming style */
+      if (implementation[attrs.originalName] === undefined) {
+        common.log(grpc.logVerbosity.ERROR, 'Method handler ' + name + ' for ' +
+            attrs.path + ' expected but not provided');
+        impl = defaultHandler[method_type];
+      } else {
+        impl = _.bind(implementation[attrs.originalName], implementation);
+      }
     } else {
       impl = _.bind(implementation[name], implementation);
     }
@@ -774,17 +781,31 @@ Server.prototype.addService = function(service, implementation) {
 
 /**
  * Add a proto service to the server, with a corresponding implementation
+ * @deprecated Use grpc.load and Server#addService instead
  * @param {Protobuf.Reflect.Service} service The proto service descriptor
  * @param {Object<String, function>} implementation Map of method names to
  *     method implementation for the provided service.
  */
 Server.prototype.addProtoService = function(service, implementation) {
   var options;
-  if (service.grpc_options) {
-    options = service.grpc_options;
+  var protobuf_js_5_common = require('./protobuf_js_5_common');
+  var protobuf_js_6_common = require('./protobuf_js_6_common');
+  common.log(grpc.logVerbosity.INFO,
+             'Server#addProtoService is deprecated. Use addService instead');
+  if (protobuf_js_5_common.isProbablyProtobufJs5(service)) {
+    options = _.defaults(service.grpc_options, common.defaultGrpcOptions);
+    this.addService(
+        protobuf_js_5_common.getProtobufServiceAttrs(service, options),
+        implementation);
+  } else if (protobuf_js_6_common.isProbablyProtobufJs6(service)) {
+    options = _.defaults(service.grpc_options, common.defaultGrpcOptions);
+    this.addService(
+        protobuf_js_6_common.getProtobufServiceAttrs(service, options),
+        implementation);
+  } else {
+    // We assume that this is a service attributes object
+    this.addService(service, implementation);
   }
-  this.addService(common.getProtobufServiceAttrs(service, options),
-                  implementation);
 };
 
 /**
diff --git a/src/node/stress/metrics_server.js b/src/node/stress/metrics_server.js
index 3ab4b4c82d3e69bfba15e5b10a1700c779bf8fa5..b3f939e8f3d2c69d28c9755b5d5b72869312576e 100644
--- a/src/node/stress/metrics_server.js
+++ b/src/node/stress/metrics_server.js
@@ -63,7 +63,7 @@ function getAllGauges(call) {
 
 function MetricsServer(port) {
   var server = new grpc.Server();
-  server.addProtoService(metrics.MetricsService.service, {
+  server.addService(metrics.MetricsService.service, {
     getGauge: _.bind(getGauge, this),
     getAllGauges: _.bind(getAllGauges, this)
   });
diff --git a/src/node/test/common_test.js b/src/node/test/common_test.js
index c57b7388f67f5e7fde9e3d4a0055addb8f4b2ad5..e1ce864f97513a5b1bcc2a21ca25fcff197c1a3c 100644
--- a/src/node/test/common_test.js
+++ b/src/node/test/common_test.js
@@ -34,17 +34,26 @@
 'use strict';
 
 var assert = require('assert');
+var _ = require('lodash');
 
-var common = require('../src/common.js');
+var common = require('../src/common');
+var protobuf_js_6_common = require('../src/protobuf_js_6_common');
+
+var serializeCls = protobuf_js_6_common.serializeCls;
+var deserializeCls = protobuf_js_6_common.deserializeCls;
 
 var ProtoBuf = require('protobufjs');
 
-var messages_proto = ProtoBuf.loadProtoFile(
-    __dirname + '/test_messages.proto').build();
+var messages_proto = new ProtoBuf.Root();
+messages_proto = messages_proto.loadSync(
+    __dirname + '/test_messages.proto', {keepCase: true}).resolveAll();
+
+var default_options = common.defaultGrpcOptions;
 
 describe('Proto message long int serialize and deserialize', function() {
-  var longSerialize = common.serializeCls(messages_proto.LongValues);
-  var longDeserialize = common.deserializeCls(messages_proto.LongValues);
+  var longSerialize = serializeCls(messages_proto.LongValues);
+  var longDeserialize = deserializeCls(messages_proto.LongValues,
+                                       default_options);
   var pos_value = '314159265358979';
   var neg_value = '-27182818284590';
   it('should preserve positive int64 values', function() {
@@ -88,8 +97,9 @@ describe('Proto message long int serialize and deserialize', function() {
                        neg_value);
   });
   it('should deserialize as a number with the right option set', function() {
-    var longNumDeserialize = common.deserializeCls(messages_proto.LongValues,
-                                                   false, false);
+    var num_options = _.defaults({longsAsStrings: false}, default_options);
+    var longNumDeserialize = deserializeCls(messages_proto.LongValues,
+                                            num_options);
     var serialized = longSerialize({int_64: pos_value});
     assert.strictEqual(typeof longDeserialize(serialized).int_64, 'string');
     /* With the longsAsStrings option disabled, long values are represented as
@@ -98,11 +108,12 @@ describe('Proto message long int serialize and deserialize', function() {
   });
 });
 describe('Proto message bytes serialize and deserialize', function() {
-  var sequenceSerialize = common.serializeCls(messages_proto.SequenceValues);
-  var sequenceDeserialize = common.deserializeCls(
-      messages_proto.SequenceValues);
-  var sequenceBase64Deserialize = common.deserializeCls(
-      messages_proto.SequenceValues, true);
+  var sequenceSerialize = serializeCls(messages_proto.SequenceValues);
+  var sequenceDeserialize = deserializeCls(
+      messages_proto.SequenceValues, default_options);
+  var b64_options = _.defaults({binaryAsBase64: true}, default_options);
+  var sequenceBase64Deserialize = deserializeCls(
+      messages_proto.SequenceValues, b64_options);
   var buffer_val = new Buffer([0x69, 0xb7]);
   var base64_val = 'abc=';
   it('should preserve a buffer', function() {
@@ -120,19 +131,73 @@ describe('Proto message bytes serialize and deserialize', function() {
     var deserialized = sequenceBase64Deserialize(serialized);
     assert.strictEqual(deserialized.bytes_field, base64_val);
   });
-  /* The next two tests are specific tests to verify that issue
-   * https://github.com/grpc/grpc/issues/5174 has been fixed. They are skipped
-   * because they will not pass until a protobuf.js release has been published
-   * with a fix for https://github.com/dcodeIO/protobuf.js/issues/390 */
-  it.skip('should serialize a repeated field as packed by default', function() {
-    var expected_serialize = new Buffer([0x12, 0x01, 0x01, 0x0a]);
+  it('should serialize a repeated field as packed by default', function() {
+    var expected_serialize = new Buffer([0x12, 0x01, 0x0a]);
     var serialized = sequenceSerialize({repeated_field: [10]});
     assert.strictEqual(expected_serialize.compare(serialized), 0);
   });
-  it.skip('should deserialize packed or unpacked repeated', function() {
-    var serialized = new Buffer([0x12, 0x01, 0x01, 0x0a]);
+  it('should deserialize packed or unpacked repeated', function() {
+    var expectedDeserialize = {
+      bytes_field: new Buffer(''),
+      repeated_field: [10]
+    };
+    var packedSerialized = new Buffer([0x12, 0x01, 0x0a]);
+    var unpackedSerialized = new Buffer([0x10, 0x0a]);
+    var packedDeserialized;
+    var unpackedDeserialized;
     assert.doesNotThrow(function() {
-      sequenceDeserialize(serialized);
+      packedDeserialized = sequenceDeserialize(packedSerialized);
     });
+    assert.doesNotThrow(function() {
+      unpackedDeserialized = sequenceDeserialize(unpackedSerialized);
+    });
+    assert.deepEqual(packedDeserialized, expectedDeserialize);
+    assert.deepEqual(unpackedDeserialized, expectedDeserialize);
+  });
+});
+describe('Proto message oneof serialize and deserialize', function() {
+  var oneofSerialize = serializeCls(messages_proto.OneOfValues);
+  var oneofDeserialize = deserializeCls(
+      messages_proto.OneOfValues, default_options);
+  it('Should have idempotent round trips', function() {
+    var test_message = {oneof_choice: 'int_choice', int_choice: 5};
+    var serialized1 = oneofSerialize(test_message);
+    var deserialized1 = oneofDeserialize(serialized1);
+    assert.equal(deserialized1.int_choice, 5);
+    var serialized2 = oneofSerialize(deserialized1);
+    var deserialized2 = oneofDeserialize(serialized2);
+    assert.deepEqual(deserialized1, deserialized2);
+  });
+  it('Should emit a property indicating which field was chosen', function() {
+    var test_message1 = {oneof_choice: 'int_choice', int_choice: 5};
+    var serialized1 = oneofSerialize(test_message1);
+    var deserialized1 = oneofDeserialize(serialized1);
+    assert.equal(deserialized1.oneof_choice, 'int_choice');
+    var test_message2 = {oneof_choice: 'string_choice', string_choice: 'abc'};
+    var serialized2 = oneofSerialize(test_message2);
+    var deserialized2 = oneofDeserialize(serialized2);
+    assert.equal(deserialized2.oneof_choice, 'string_choice');
+  });
+});
+describe('Proto message enum serialize and deserialize', function() {
+  var enumSerialize = serializeCls(messages_proto.EnumValues);
+  var enumDeserialize = deserializeCls(
+      messages_proto.EnumValues, default_options);
+  var enumIntOptions = _.defaults({enumsAsStrings: false}, default_options);
+  var enumIntDeserialize = deserializeCls(
+      messages_proto.EnumValues, enumIntOptions);
+  it('Should accept both names and numbers', function() {
+    var nameSerialized = enumSerialize({enum_value: 'ONE'});
+    var numberSerialized = enumSerialize({enum_value: 1});
+    assert.strictEqual(messages_proto.TestEnum.ONE, 1);
+    assert.deepEqual(enumDeserialize(nameSerialized),
+                     enumDeserialize(numberSerialized));
+  });
+  it('Should deserialize as a string the enumsAsStrings option', function() {
+    var serialized = enumSerialize({enum_value: 'TWO'});
+    var nameDeserialized = enumDeserialize(serialized);
+    var numberDeserialized = enumIntDeserialize(serialized);
+    assert.deepEqual(nameDeserialized, {enum_value: 'TWO'});
+    assert.deepEqual(numberDeserialized, {enum_value: 2});
   });
 });
diff --git a/src/node/test/credentials_test.js b/src/node/test/credentials_test.js
index 305843f665ed0418e8198cac7b6b9ef9300f307d..b66b4bf5ea47c498dec17e3288158ba3c88da755 100644
--- a/src/node/test/credentials_test.js
+++ b/src/node/test/credentials_test.js
@@ -228,7 +228,7 @@ describe('client credentials', function() {
   before(function() {
     var proto = grpc.load(__dirname + '/test_service.proto');
     server = new grpc.Server();
-    server.addProtoService(proto.TestService.service, {
+    server.addService(proto.TestService.service, {
       unary: function(call, cb) {
         call.sendMetadata(call.metadata);
         cb(null, {});
diff --git a/src/node/test/surface_test.js b/src/node/test/surface_test.js
index 2636ea85ac8e81113dc2e7c6db5c9c484d4b057f..783028fa99f6ce4345c02fea160fafe21c297a65 100644
--- a/src/node/test/surface_test.js
+++ b/src/node/test/surface_test.js
@@ -34,19 +34,22 @@
 'use strict';
 
 var assert = require('assert');
+var _ = require('lodash');
 
 var surface_client = require('../src/client.js');
+var common = require('../src/common');
 
 var ProtoBuf = require('protobufjs');
 
 var grpc = require('..');
 
-var math_proto = ProtoBuf.loadProtoFile(__dirname +
-    '/../../proto/math/math.proto');
+var math_proto = new ProtoBuf.Root();
+math_proto = math_proto.loadSync(__dirname +
+    '/../../proto/math/math.proto', {keepCase: true});
 
 var mathService = math_proto.lookup('math.Math');
-
-var _ = require('lodash');
+var mathServiceAttrs = grpc.loadObject(
+    mathService, common.defaultGrpcOptions).service;
 
 /**
  * This is used for testing functions with multiple asynchronous calls that
@@ -87,11 +90,6 @@ describe('File loader', function() {
       grpc.load(__dirname + '/test_service.json', 'json');
     });
   });
-  it('Should fail to load a file with an unknown format', function() {
-    assert.throws(function() {
-      grpc.load(__dirname + '/test_service.proto', 'fake_format');
-    });
-  });
 });
 describe('surface Server', function() {
   var server;
@@ -132,13 +130,64 @@ describe('Server.prototype.addProtoService', function() {
   afterEach(function() {
     server.forceShutdown();
   });
-  it('Should succeed with a single service', function() {
+  it('Should succeed with a single proto service', function() {
     assert.doesNotThrow(function() {
       server.addProtoService(mathService, dummyImpls);
     });
   });
+  it('Should succeed with a single service attributes object', function() {
+    assert.doesNotThrow(function() {
+      server.addProtoService(mathServiceAttrs, dummyImpls);
+    });
+  });
+});
+describe('Server.prototype.addService', function() {
+  var server;
+  var dummyImpls = {
+    'div': function() {},
+    'divMany': function() {},
+    'fib': function() {},
+    'sum': function() {}
+  };
+  beforeEach(function() {
+    server = new grpc.Server();
+  });
+  afterEach(function() {
+    server.forceShutdown();
+  });
+  it('Should succeed with a single service', function() {
+    assert.doesNotThrow(function() {
+      server.addService(mathServiceAttrs, dummyImpls);
+    });
+  });
   it('Should fail with conflicting method names', function() {
-    server.addProtoService(mathService, dummyImpls);
+    server.addService(mathServiceAttrs, dummyImpls);
+    assert.throws(function() {
+      server.addService(mathServiceAttrs, dummyImpls);
+    });
+  });
+  it('Should allow method names as originally written', function() {
+    var altDummyImpls = {
+      'Div': function() {},
+      'DivMany': function() {},
+      'Fib': function() {},
+      'Sum': function() {}
+    };
+    assert.doesNotThrow(function() {
+      server.addProtoService(mathService, altDummyImpls);
+    });
+  });
+  it('Should have a conflict between name variations', function() {
+    /* This is really testing that both name variations are actually used,
+       by checking that the method actually gets registered, for the
+       corresponding function, in both cases */
+    var altDummyImpls = {
+      'Div': function() {},
+      'DivMany': function() {},
+      'Fib': function() {},
+      'Sum': function() {}
+    };
+    server.addProtoService(mathService, altDummyImpls);
     assert.throws(function() {
       server.addProtoService(mathService, dummyImpls);
     });
@@ -146,15 +195,15 @@ describe('Server.prototype.addProtoService', function() {
   it('Should fail if the server has been started', function() {
     server.start();
     assert.throws(function() {
-      server.addProtoService(mathService, dummyImpls);
+      server.addService(mathServiceAttrs, dummyImpls);
     });
   });
   describe('Default handlers', function() {
     var client;
     beforeEach(function() {
-      server.addProtoService(mathService, {});
+      server.addService(mathServiceAttrs, {});
       var port = server.bind('localhost:0', server_insecure_creds);
-      var Client = surface_client.makeProtobufClientConstructor(mathService);
+      var Client = grpc.loadObject(mathService);
       client = new Client('localhost:' + port,
                           grpc.credentials.createInsecure());
       server.start();
@@ -226,7 +275,7 @@ describe('waitForClientReady', function() {
     server = new grpc.Server();
     port = server.bind('localhost:0', grpc.ServerCredentials.createInsecure());
     server.start();
-    Client = surface_client.makeProtobufClientConstructor(mathService);
+    Client = grpc.loadObject(mathService);
   });
   beforeEach(function() {
     client = new Client('localhost:' + port, grpc.credentials.createInsecure());
@@ -283,16 +332,18 @@ describe('Echo service', function() {
   var server;
   var client;
   before(function() {
-    var test_proto = ProtoBuf.loadProtoFile(__dirname + '/echo_service.proto');
+    var test_proto = new ProtoBuf.Root();
+    test_proto = test_proto.loadSync(__dirname + '/echo_service.proto',
+                                         {keepCase: true});
     var echo_service = test_proto.lookup('EchoService');
+    var Client = grpc.loadObject(echo_service);
     server = new grpc.Server();
-    server.addProtoService(echo_service, {
+    server.addService(Client.service, {
       echo: function(call, callback) {
         callback(null, call.request);
       }
     });
     var port = server.bind('localhost:0', server_insecure_creds);
-    var Client = surface_client.makeProtobufClientConstructor(echo_service);
     client = new Client('localhost:' + port, grpc.credentials.createInsecure());
     server.start();
   });
@@ -406,10 +457,13 @@ describe('Echo metadata', function() {
   var server;
   var metadata;
   before(function() {
-    var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
+    var test_proto = new ProtoBuf.Root();
+    test_proto = test_proto.loadSync(__dirname + '/test_service.proto',
+                                         {keepCase: true});
     var test_service = test_proto.lookup('TestService');
+    var Client = grpc.loadObject(test_service);
     server = new grpc.Server();
-    server.addProtoService(test_service, {
+    server.addService(Client.service, {
       unary: function(call, cb) {
         call.sendMetadata(call.metadata);
         cb(null, {});
@@ -434,7 +488,6 @@ describe('Echo metadata', function() {
       }
     });
     var port = server.bind('localhost:0', server_insecure_creds);
-    var Client = surface_client.makeProtobufClientConstructor(test_service);
     client = new Client('localhost:' + port, grpc.credentials.createInsecure());
     server.start();
     metadata = new grpc.Metadata();
@@ -507,7 +560,9 @@ describe('Client malformed response handling', function() {
   var client;
   var badArg = new Buffer([0xFF]);
   before(function() {
-    var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
+    var test_proto = new ProtoBuf.Root();
+    test_proto = test_proto.loadSync(__dirname + '/test_service.proto',
+                                         {keepCase: true});
     var test_service = test_proto.lookup('TestService');
     var malformed_test_service = {
       unary: {
@@ -565,7 +620,7 @@ describe('Client malformed response handling', function() {
       }
     });
     var port = server.bind('localhost:0', server_insecure_creds);
-    var Client = surface_client.makeProtobufClientConstructor(test_service);
+    var Client = grpc.loadObject(test_service);
     client = new Client('localhost:' + port, grpc.credentials.createInsecure());
     server.start();
   });
@@ -614,7 +669,9 @@ describe('Server serialization failure handling', function() {
   var client;
   var server;
   before(function() {
-    var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
+    var test_proto = new ProtoBuf.Root();
+    test_proto = test_proto.loadSync(__dirname + '/test_service.proto',
+                                         {keepCase: true});
     var test_service = test_proto.lookup('TestService');
     var malformed_test_service = {
       unary: {
@@ -672,7 +729,7 @@ describe('Server serialization failure handling', function() {
       }
     });
     var port = server.bind('localhost:0', server_insecure_creds);
-    var Client = surface_client.makeProtobufClientConstructor(test_service);
+    var Client = grpc.loadObject(test_service);
     client = new Client('localhost:' + port, grpc.credentials.createInsecure());
     server.start();
   });
@@ -721,12 +778,15 @@ describe('Other conditions', function() {
   var server;
   var port;
   before(function() {
-    var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
+    var test_proto = new ProtoBuf.Root();
+    test_proto = test_proto.loadSync(__dirname + '/test_service.proto',
+                                         {keepCase: true});
     test_service = test_proto.lookup('TestService');
+    Client = grpc.loadObject(test_service);
     server = new grpc.Server();
     var trailer_metadata = new grpc.Metadata();
     trailer_metadata.add('trailer-present', 'yes');
-    server.addProtoService(test_service, {
+    server.addService(Client.service, {
       unary: function(call, cb) {
         var req = call.request;
         if (req.error) {
@@ -786,7 +846,6 @@ describe('Other conditions', function() {
       }
     });
     port = server.bind('localhost:0', server_insecure_creds);
-    Client = surface_client.makeProtobufClientConstructor(test_service);
     client = new Client('localhost:' + port, grpc.credentials.createInsecure());
     server.start();
   });
@@ -1067,17 +1126,19 @@ describe('Call propagation', function() {
   var client;
   var server;
   before(function() {
-    var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
+    var test_proto = new ProtoBuf.Root();
+    test_proto = test_proto.loadSync(__dirname + '/test_service.proto',
+                                         {keepCase: true});
     test_service = test_proto.lookup('TestService');
     server = new grpc.Server();
-    server.addProtoService(test_service, {
+    Client = grpc.loadObject(test_service);
+    server.addService(Client.service, {
       unary: function(call) {},
       clientStream: function(stream) {},
       serverStream: function(stream) {},
       bidiStream: function(stream) {}
     });
     var port = server.bind('localhost:0', server_insecure_creds);
-    Client = surface_client.makeProtobufClientConstructor(test_service);
     client = new Client('localhost:' + port, grpc.credentials.createInsecure());
     server.start();
   });
@@ -1112,7 +1173,7 @@ describe('Call propagation', function() {
         });
         call.cancel();
       };
-      proxy.addProtoService(test_service, proxy_impl);
+      proxy.addService(Client.service, proxy_impl);
       var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
       proxy.start();
       var proxy_client = new Client('localhost:' + proxy_port,
@@ -1134,7 +1195,7 @@ describe('Call propagation', function() {
         });
         call.cancel();
       };
-      proxy.addProtoService(test_service, proxy_impl);
+      proxy.addService(Client.service, proxy_impl);
       var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
       proxy.start();
       var proxy_client = new Client('localhost:' + proxy_port,
@@ -1154,7 +1215,7 @@ describe('Call propagation', function() {
         });
         call.cancel();
       };
-      proxy.addProtoService(test_service, proxy_impl);
+      proxy.addService(Client.service, proxy_impl);
       var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
       proxy.start();
       var proxy_client = new Client('localhost:' + proxy_port,
@@ -1178,7 +1239,7 @@ describe('Call propagation', function() {
         });
         call.cancel();
       };
-      proxy.addProtoService(test_service, proxy_impl);
+      proxy.addService(Client.service, proxy_impl);
       var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
       proxy.start();
       var proxy_client = new Client('localhost:' + proxy_port,
@@ -1209,7 +1270,7 @@ describe('Call propagation', function() {
           }
         });
       };
-      proxy.addProtoService(test_service, proxy_impl);
+      proxy.addService(Client.service, proxy_impl);
       var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
       proxy.start();
       var proxy_client = new Client('localhost:' + proxy_port,
@@ -1233,7 +1294,7 @@ describe('Call propagation', function() {
           done();
         });
       };
-      proxy.addProtoService(test_service, proxy_impl);
+      proxy.addService(Client.service, proxy_impl);
       var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
       proxy.start();
       var proxy_client = new Client('localhost:' + proxy_port,
@@ -1253,14 +1314,14 @@ describe('Cancelling surface client', function() {
   var server;
   before(function() {
     server = new grpc.Server();
-    server.addProtoService(mathService, {
+    server.addService(mathServiceAttrs, {
       'div': function(stream) {},
       'divMany': function(stream) {},
       'fib': function(stream) {},
       'sum': function(stream) {}
     });
     var port = server.bind('localhost:0', server_insecure_creds);
-    var Client = surface_client.makeProtobufClientConstructor(mathService);
+    var Client = surface_client.makeClientConstructor(mathServiceAttrs);
     client = new Client('localhost:' + port, grpc.credentials.createInsecure());
     server.start();
   });
diff --git a/src/node/test/test_messages.proto b/src/node/test/test_messages.proto
index a1a6a32833db492e5eed6c39812c1865d00c3957..43c213dabb1fb87bca217f754e7d7f63f5963063 100644
--- a/src/node/test/test_messages.proto
+++ b/src/node/test/test_messages.proto
@@ -41,3 +41,20 @@ message SequenceValues {
   bytes bytes_field = 1;
   repeated int32 repeated_field = 2;
 }
+
+message OneOfValues {
+  oneof oneof_choice {
+    int32 int_choice = 1;
+    string string_choice = 2;
+  }
+}
+
+enum TestEnum {
+  ZERO = 0;
+  ONE = 1;
+  TWO = 2;
+}
+
+message EnumValues {
+  TestEnum enum_value = 1;
+}
diff --git a/src/node/tools/package.json b/src/node/tools/package.json
index 53dd53f539106b694ca75e1a57b0238a5337e63f..a81aa87f4bb7708a6582fae4607a1c5b058f7e01 100644
--- a/src/node/tools/package.json
+++ b/src/node/tools/package.json
@@ -1,6 +1,6 @@
 {
   "name": "grpc-tools",
-  "version": "1.2.0-dev",
+  "version": "1.4.0-dev",
   "author": "Google Inc.",
   "description": "Tools for developing with gRPC on Node.js",
   "homepage": "http://www.grpc.io/",
diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
index 1a3b775c60986c5c560cf1621b02668ef4f5160c..2f29058b59d4b721e1a3958c7acca9723a2f7413 100644
--- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
+++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
@@ -42,7 +42,7 @@ Pod::Spec.new do |s|
   # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
   # before them.
   s.name     = '!ProtoCompiler-gRPCPlugin'
-  v = '1.2.0-dev'
+  v = '1.4.0-dev'
   s.version  = v
   s.summary  = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
   s.description = <<-DESC
@@ -101,9 +101,9 @@ Pod::Spec.new do |s|
   s.preserve_paths = plugin
 
   # Restrict the protoc version to the one supported by this plugin.
-  s.dependency '!ProtoCompiler', '3.1.0'
+  s.dependency '!ProtoCompiler', '3.2.0'
   # For the Protobuf dependency not to complain:
-  s.ios.deployment_target = '7.1'
+  s.ios.deployment_target = '7.0'
   s.osx.deployment_target = '10.9'
   # Restrict the gRPC runtime version to the one supported by this plugin.
   s.dependency 'gRPC-ProtoRPC', v
diff --git a/src/objective-c/!ProtoCompiler.podspec b/src/objective-c/!ProtoCompiler.podspec
index dc4d8e964e62c5694a517c2a3211cdcab91f4ec8..2e9b944f33dc45a46cb6e5ab8117e024925129c8 100644
--- a/src/objective-c/!ProtoCompiler.podspec
+++ b/src/objective-c/!ProtoCompiler.podspec
@@ -36,7 +36,7 @@ Pod::Spec.new do |s|
   # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
   # before them.
   s.name     = '!ProtoCompiler'
-  v = '3.1.0'
+  v = '3.2.0'
   s.version  = v
   s.summary  = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files'
   s.description = <<-DESC
@@ -110,7 +110,7 @@ Pod::Spec.new do |s|
   # Restrict the protobuf runtime version to the one supported by this version of protoc.
   s.dependency 'Protobuf', '~> 3.0'
   # For the Protobuf dependency not to complain:
-  s.ios.deployment_target = '7.1'
+  s.ios.deployment_target = '7.0'
   s.osx.deployment_target = '10.9'
 
   # This is only for local development of protoc: If the Podfile brings this pod from a local
diff --git a/src/objective-c/BoringSSL.podspec b/src/objective-c/BoringSSL.podspec
index 908bb0b5e5e2f2c63ed68db5f8d7d954dc40fe45..651bd4977d81434b81aef9c9059d9a838327366e 100644
--- a/src/objective-c/BoringSSL.podspec
+++ b/src/objective-c/BoringSSL.podspec
@@ -31,7 +31,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'BoringSSL'
-  version = '8.0'
+  version = '8.2'
   s.version  = version
   s.summary  = 'BoringSSL is a fork of OpenSSL that is designed to meet Google’s needs.'
   # Adapted from the homepage:
@@ -69,8 +69,9 @@ Pod::Spec.new do |s|
 
   s.source = {
     :git => 'https://boringssl.googlesource.com/boringssl',
-    :tag => "version_for_cocoapods_#{version}",
-    # :commit => '4fec04b48406111cb88fdd8d196253adc54f7a31',
+    # Restore this version name hack in the next version!!
+    # :tag => "version_for_cocoapods_#{version}",
+    :tag => "version_for_cocoapods_8.0",
   }
 
   name = 'openssl'
@@ -95,7 +96,7 @@ Pod::Spec.new do |s|
   # The module map and umbrella header created automatically by Cocoapods don't work for C libraries
   # like this one. The following file, and a correct umbrella header, are created on the fly by the
   # `prepare_command` of this pod.
-  s.module_map = 'include/openssl/module.modulemap'
+  s.module_map = 'include/openssl/BoringSSL.modulemap'
 
   # We don't need to inhibit all warnings; only -Wno-shorten-64-to-32. But Cocoapods' linter doesn't
   # want that for some reason.
@@ -148,10 +149,10 @@ Pod::Spec.new do |s|
       #include "ssl.h"
       #include "crypto.h"
       #include "aes.h"
-      /* The following macros are defined by base.h. The latter is the first file included by the
-         other headers. */
-      #if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
-      #  include "arm_arch.h"
+      /* The following macros are defined by base.h. The latter is the first file included by the    
+         other headers. */    
+      #if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)    
+      #  include "arm_arch.h"   
       #endif
       #include "asn1.h"
       #include "asn1_mac.h"
@@ -186,7 +187,7 @@ Pod::Spec.new do |s|
       #include "x509.h"
       #include "x509v3.h"
     EOF
-    cat > include/openssl/module.modulemap <<EOF
+    cat > include/openssl/BoringSSL.modulemap <<EOF
       framework module openssl {
         umbrella header "umbrella.h"
         export *
diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h
index 7645bb1d34a99d2c6eca10f8ac71e9622f896414..5e9324c445627b2f36658cf3980d8e5590ae9e82 100644
--- a/src/objective-c/GRPCClient/GRPCCall.h
+++ b/src/objective-c/GRPCClient/GRPCCall.h
@@ -253,6 +253,13 @@ extern id const kGRPCTrailersKey;
  */
 + (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path;
 
+/**
+ * Set the dispatch queue to be used for callbacks.
+ *
+ * This configuration is only effective before the call starts.
+ */
+- (void)setResponseDispatchQueue:(dispatch_queue_t)queue;
+
 // TODO(jcanizales): Let specify a deadline. As a category of GRXWriter?
 @end
 
diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m
index 44393f6b9998d7fc7005f860fd0442e2266ff38e..f9d13fea578b7a5124e0ec27d280b9bfc088c182 100644
--- a/src/objective-c/GRPCClient/GRPCCall.m
+++ b/src/objective-c/GRPCClient/GRPCCall.m
@@ -36,6 +36,7 @@
 #include <grpc/grpc.h>
 #include <grpc/support/time.h>
 #import <RxLibrary/GRXConcurrentWriteable.h>
+#import <RxLibrary/GRXImmediateSingleWriter.h>
 
 #import "private/GRPCConnectivityMonitor.h"
 #import "private/GRPCHost.h"
@@ -45,6 +46,11 @@
 #import "private/NSDictionary+GRPC.h"
 #import "private/NSError+GRPC.h"
 
+// At most 6 ops can be in an op batch for a client: SEND_INITIAL_METADATA,
+// SEND_MESSAGE, SEND_CLOSE_FROM_CLIENT, RECV_INITIAL_METADATA, RECV_MESSAGE,
+// and RECV_STATUS_ON_CLIENT.
+NSInteger kMaxClientBatch = 6;
+
 NSString * const kGRPCHeadersKey = @"io.grpc.HeadersKey";
 NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
 static NSMutableDictionary *callFlags;
@@ -100,6 +106,17 @@ static NSMutableDictionary *callFlags;
   GRPCCall *_retainSelf;
 
   GRPCRequestHeaders *_requestHeaders;
+
+  // In the case that the call is a unary call (i.e. the writer to GRPCCall is of type
+  // GRXImmediateSingleWriter), GRPCCall will delay sending ops (not send them to C core
+  // immediately) and buffer them into a batch _unaryOpBatch. The batch is sent to C core when
+  // the SendClose op is added.
+  BOOL _unaryCall;
+  NSMutableArray *_unaryOpBatch;
+
+  // The dispatch queue to be used for enqueuing responses to user. Defaulted to the main dispatch
+  // queue
+  dispatch_queue_t _responseQueue;
 }
 
 @synthesize state = _state;
@@ -157,14 +174,31 @@ static NSMutableDictionary *callFlags;
     _requestWriter = requestWriter;
 
     _requestHeaders = [[GRPCRequestHeaders alloc] initWithCall:self];
+
+    if ([requestWriter isKindOfClass:[GRXImmediateSingleWriter class]]) {
+      _unaryCall = YES;
+      _unaryOpBatch = [NSMutableArray arrayWithCapacity:kMaxClientBatch];
+    }
+
+    _responseQueue = dispatch_get_main_queue();
   }
   return self;
 }
 
+- (void)setResponseDispatchQueue:(dispatch_queue_t)queue {
+  if (_state != GRXWriterStateNotStarted) {
+    return;
+  }
+  _responseQueue = queue;
+}
+
 #pragma mark Finish
 
 - (void)finishWithError:(NSError *)errorOrNil {
   @synchronized(self) {
+    if (_state == GRXWriterStateFinished) {
+      return;
+    }
     _state = GRXWriterStateFinished;
   }
 
@@ -254,15 +288,22 @@ static NSMutableDictionary *callFlags;
 
 - (void)sendHeaders:(NSDictionary *)headers {
   // TODO(jcanizales): Add error handlers for async failures
-  [_wrappedCall startBatchWithOperations:@[[[GRPCOpSendMetadata alloc] initWithMetadata:headers
-                                                                                  flags:[GRPCCall callFlagsForHost:_host path:_path]
-                                                                                handler:nil]]];
+  GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc] initWithMetadata:headers
+                                                                  flags:[GRPCCall callFlagsForHost:_host path:_path]
+                                                                handler:nil];  // No clean-up needed after SEND_INITIAL_METADATA
+  if (!_unaryCall) {
+    [_wrappedCall startBatchWithOperations:@[op]];
+  } else {
+    [_unaryOpBatch addObject:op];
+  }
 }
 
 #pragma mark GRXWriteable implementation
 
 // Only called from the call queue. The error handler will be called from the
 // network queue if the write didn't succeed.
+// If the call is a unary call, parameter \a errorHandler will be ignored and
+// the error handler of GRPCOpSendClose will be executed in case of error.
 - (void)writeMessage:(NSData *)message withErrorHandler:(void (^)())errorHandler {
 
   __weak GRPCCall *weakSelf = self;
@@ -275,9 +316,17 @@ static NSMutableDictionary *callFlags;
       }
     }
   };
-  [_wrappedCall startBatchWithOperations:@[[[GRPCOpSendMessage alloc] initWithMessage:message
-                                                                              handler:resumingHandler]]
-                            errorHandler:errorHandler];
+
+  GRPCOpSendMessage *op = [[GRPCOpSendMessage alloc] initWithMessage:message
+                                                             handler:resumingHandler];
+  if (!_unaryCall) {
+    [_wrappedCall startBatchWithOperations:@[op]
+                              errorHandler:errorHandler];
+  } else {
+    // Ignored errorHandler since it is the same as the one for GRPCOpSendClose.
+    // TODO (mxyan): unify the error handlers of all Ops into a single closure.
+    [_unaryOpBatch addObject:op];
+  }
 }
 
 - (void)writeValue:(id)value {
@@ -302,8 +351,14 @@ static NSMutableDictionary *callFlags;
 // Only called from the call queue. The error handler will be called from the
 // network queue if the requests stream couldn't be closed successfully.
 - (void)finishRequestWithErrorHandler:(void (^)())errorHandler {
-  [_wrappedCall startBatchWithOperations:@[[[GRPCOpSendClose alloc] init]]
-                            errorHandler:errorHandler];
+  if (!_unaryCall) {
+    [_wrappedCall startBatchWithOperations:@[[[GRPCOpSendClose alloc] init]]
+                              errorHandler:errorHandler];
+  } else {
+    [_unaryOpBatch addObject:[[GRPCOpSendClose alloc] init]];
+    [_wrappedCall startBatchWithOperations:_unaryOpBatch
+                              errorHandler:errorHandler];
+  }
 }
 
 - (void)writesFinishedWithError:(NSError *)errorOrNil {
@@ -382,7 +437,8 @@ static NSMutableDictionary *callFlags;
   // that the life of the instance is determined by this retain cycle.
   _retainSelf = self;
 
-  _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable];
+  _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable
+                                                           dispatchQueue:_responseQueue];
 
   _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host path:_path];
   NSAssert(_wrappedCall, @"Error allocating RPC objects. Low memory?");
diff --git a/src/objective-c/GRPCClient/internal_testing/GRPCCall+InternalTests.h b/src/objective-c/GRPCClient/internal_testing/GRPCCall+InternalTests.h
new file mode 100644
index 0000000000000000000000000000000000000000..29bd12f0cfb5dfafe6fb155d923715c8a976dd56
--- /dev/null
+++ b/src/objective-c/GRPCClient/internal_testing/GRPCCall+InternalTests.h
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright 2017, 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.
+ *
+ */
+
+#ifdef GRPC_TEST_OBJC
+
+#import "../GRPCCall.h"
+
+/**
+ * Methods used for gRPC internal tests. DO NOT USE.
+ */
+@interface GRPCCall (InternalTests)
+
+/**
+ * Enables logging of op batches. Memory consumption increases as more ops are logged.
+ *
+ * This function is for internal testing of gRPC only. It is not part of gRPC's public interface.
+ * Do not use in production. To enable, set the preprocessor flag GRPC_TEST_OBJC.
+ */
++ (void)enableOpBatchLog:(BOOL)enabled;
+
+/**
+ * Obtain the logged op batches. Invoking this method will clean the log.
+ *
+ * This function is for internal testing of gRPC only. It is not part of gRPC's public interface.
+ * Do not use in production. To enable, set the preprocessor flag GRPC_TEST_OBJC.
+ */
++ (NSArray *)obtainAndCleanOpBatchLog;
+
+@end
+
+#endif
diff --git a/src/core/ext/client_channel/initial_connect_string.c b/src/objective-c/GRPCClient/internal_testing/GRPCCall+InternalTests.m
similarity index 69%
rename from src/core/ext/client_channel/initial_connect_string.c
rename to src/objective-c/GRPCClient/internal_testing/GRPCCall+InternalTests.m
index 8ebd06c458a6d50b87ebe45ea620b704b651d6d4..6371df6739a4e184709bcf4b8142a39ffe44c177 100644
--- a/src/core/ext/client_channel/initial_connect_string.c
+++ b/src/objective-c/GRPCClient/internal_testing/GRPCCall+InternalTests.m
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2017, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,22 +31,22 @@
  *
  */
 
-#include "src/core/ext/client_channel/initial_connect_string.h"
+#ifdef GRPC_TEST_OBJC
 
-#include <stddef.h>
+#import "GRPCCall+InternalTests.h"
 
-extern void grpc_set_default_initial_connect_string(
-    grpc_resolved_address **addr, grpc_slice *initial_str);
+#import "../private/GRPCOpBatchLog.h"
 
-static grpc_set_initial_connect_string_func g_set_initial_connect_string_func =
-    grpc_set_default_initial_connect_string;
+@implementation GRPCCall (InternalTests)
 
-void grpc_test_set_initial_connect_string_function(
-    grpc_set_initial_connect_string_func func) {
-  g_set_initial_connect_string_func = func;
++ (void)enableOpBatchLog:(BOOL)enabled {
+  [GRPCOpBatchLog enableOpBatchLog:enabled];
 }
 
-void grpc_set_initial_connect_string(grpc_resolved_address **addr,
-                                     grpc_slice *initial_str) {
-  g_set_initial_connect_string_func(addr, initial_str);
++ (NSArray *)obtainAndCleanOpBatchLog {
+  return [GRPCOpBatchLog obtainAndCleanOpBatchLog];
 }
+
+@end
+
+#endif
diff --git a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m
index 539b5ab83ce251080e114d3dbcc606cde4b4329a..5ff77eac4c5b20ef502b152e9dc12fa2a6aba6fb 100644
--- a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m
+++ b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m
@@ -48,7 +48,7 @@
 
 - (instancetype)init {
   if ((self = [super init])) {
-    _unmanagedQueue = grpc_completion_queue_create(NULL);
+    _unmanagedQueue = grpc_completion_queue_create_for_next(NULL);
 
     // This is for the following block to capture the pointer by value (instead
     // of retaining self and doing self->_unmanagedQueue). This is essential
diff --git a/src/objective-c/GRPCClient/private/GRPCOpBatchLog.h b/src/objective-c/GRPCClient/private/GRPCOpBatchLog.h
new file mode 100644
index 0000000000000000000000000000000000000000..753c4cfee6fb2783a8213bc2267a298d4533222d
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/GRPCOpBatchLog.h
@@ -0,0 +1,59 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+
+#ifdef GRPC_TEST_OBJC
+
+/**
+ * Logs the op batches of a client. Used for testing.
+ */
+@interface GRPCOpBatchLog : NSObject
+
+/**
+ * Enables logging of op batches. Memory consumption increases as more ops are logged.
+ */
++ (void)enableOpBatchLog:(BOOL)enabled;
+
+/**
+ * Add an op batch to log.
+ */
++ (void)addOpBatchToLog:(NSArray *)batch;
+
+/**
+ * Obtain the logged op batches. Invoking this method will clean the log.
+ */
++ (NSArray *)obtainAndCleanOpBatchLog;
+
+@end
+
+#endif
diff --git a/src/objective-c/GRPCClient/private/GRPCOpBatchLog.m b/src/objective-c/GRPCClient/private/GRPCOpBatchLog.m
new file mode 100644
index 0000000000000000000000000000000000000000..4b40baf122bc73bf4c0ef3b21cd8244d97c6437f
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/GRPCOpBatchLog.m
@@ -0,0 +1,72 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifdef GRPC_TEST_OBJC
+
+#import "GRPCOpBatchLog.h"
+
+static NSMutableArray *opBatchLog = nil;
+
+@implementation GRPCOpBatchLog
+
++ (void)enableOpBatchLog:(BOOL)enabled {
+  @synchronized (opBatchLog) {
+    if (enabled) {
+      if (!opBatchLog) {
+        opBatchLog = [NSMutableArray array];
+      }
+    } else {
+      if (opBatchLog) {
+        opBatchLog = nil;
+      }
+    }
+  }
+}
+
++ (void)addOpBatchToLog:(NSArray *)batch {
+  @synchronized (opBatchLog) {
+    [opBatchLog addObject:batch];
+  }
+}
+
++ (NSArray *)obtainAndCleanOpBatchLog {
+  @synchronized (opBatchLog) {
+    NSArray *out = opBatchLog;
+    opBatchLog = [NSMutableArray array];
+    return out;
+  }
+}
+
+@end
+
+#endif
diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
index 9f1901ab30abc631f41cdc555cd0b1205919377f..1faba3e20b9fd031e2de0f6549f61d62afcac528 100644
--- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
+++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
@@ -44,6 +44,8 @@
 #import "NSData+GRPC.h"
 #import "NSError+GRPC.h"
 
+#import "GRPCOpBatchLog.h"
+
 @implementation GRPCOperation {
 @protected
   // Most operation subclasses don't set any flags in the grpc_op, and rely on the flag member being
@@ -274,6 +276,12 @@
 }
 
 - (void)startBatchWithOperations:(NSArray *)operations errorHandler:(void (^)())errorHandler {
+  // Keep logs of op batches when we are running tests. Disabled when in production for improved
+  // performance.
+#ifdef GRPC_TEST_OBJC
+  [GRPCOpBatchLog addOpBatchToLog:operations];
+#endif
+
   size_t nops = operations.count;
   grpc_op *ops_array = gpr_malloc(nops * sizeof(grpc_op));
   size_t i = 0;
@@ -307,7 +315,7 @@
 }
 
 - (void)dealloc {
-  grpc_call_destroy(_call);
+  grpc_call_unref(_call);
 }
 
 @end
diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h
index e569faa25bbef40e8dff4efb40ad958bb1402c0d..c846f4214c968a4f67f75d38238b967d7338424c 100644
--- a/src/objective-c/GRPCClient/private/version.h
+++ b/src/objective-c/GRPCClient/private/version.h
@@ -38,4 +38,4 @@
 // `tools/buildgen/generate_projects.sh`.
 
 
-#define GRPC_OBJC_VERSION_STRING @"1.2.0-dev"
+#define GRPC_OBJC_VERSION_STRING @"1.4.0-dev"
diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h
index b2775f98b56e5c19039d4eeb075e6dbf7b0a0562..07004f6d4dc66e7eb0fb4dc7c6d5c6479524b262 100644
--- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h
+++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h
@@ -53,7 +53,9 @@
  * The GRXWriteable instance is retained until writesFinishedWithError: is sent to it, and released
  * after that.
  */
-- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable
+                    dispatchQueue:(dispatch_queue_t)queue NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable;
 
 /**
  * Enqueues writeValue: to be sent to the writeable in the main thread.
diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m
index 08bd079aea59121f50e0040f9ce0350eb42c5485..88aa7a7282fbf7b94eba5e46dc2a8bd7f11cbdaa 100644
--- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m
+++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m
@@ -51,14 +51,20 @@
 }
 
 // Designated initializer
-- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable {
+- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable
+                    dispatchQueue:(dispatch_queue_t)queue {
   if (self = [super init]) {
-    _writeableQueue = dispatch_get_main_queue();
+    _writeableQueue = queue;
     _writeable = writeable;
   }
   return self;
 }
 
+- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable {
+  return [self initWithWriteable:writeable
+                   dispatchQueue:dispatch_get_main_queue()];
+}
+
 - (void)enqueueValue:(id)value completionHandler:(void (^)())handler {
   dispatch_async(_writeableQueue, ^{
     // We're racing a possible cancellation performed by another thread. To turn all already-
diff --git a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.h b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..0ec788f756b6ff205a392ab58c37ee45e505ed88
--- /dev/null
+++ b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.h
@@ -0,0 +1,50 @@
+/*
+ *
+ * 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 <Foundation/Foundation.h>
+
+#import "GRXImmediateWriter.h"
+
+/**
+ * Utility to construct GRXWriter instances from values that are immediately available when
+ * required.
+ */
+@interface GRXImmediateSingleWriter : GRXImmediateWriter
+
+/**
+ * Returns a writer that sends the passed value to its writeable and then finishes (releasing the
+ * value).
+ */
++ (GRXWriter *)writerWithValue:(id)value;
+
+@end
diff --git a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m
new file mode 100644
index 0000000000000000000000000000000000000000..0096c996d4c57fd0048c76a12a3c74597c4e7d2d
--- /dev/null
+++ b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m
@@ -0,0 +1,89 @@
+/*
+ *
+ * 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 "GRXImmediateSingleWriter.h"
+
+@implementation GRXImmediateSingleWriter {
+  id _value;
+  id<GRXWriteable> _writeable;
+}
+
+@synthesize state = _state;
+
+- (instancetype)initWithValue:(id)value {
+  if (self = [super init]) {
+    _value = value;
+    _state = GRXWriterStateNotStarted;
+  }
+  return self;
+}
+
++ (GRXWriter *)writerWithValue:(id)value {
+  return [[self alloc] initWithValue:value];
+}
+
+- (void)startWithWriteable:(id<GRXWriteable>)writeable {
+  _state = GRXWriterStateStarted;
+  _writeable = writeable;
+  [writeable writeValue:_value];
+  [self finish];
+}
+
+- (void)finish {
+  _state = GRXWriterStateFinished;
+  _value = nil;
+  id<GRXWriteable> writeable = _writeable;
+  _writeable = nil;
+  [writeable writesFinishedWithError:nil];
+}
+
+// Overwrite the setter to disallow manual state transition. The getter
+// of _state is synthesized.
+- (void)setState:(GRXWriterState)newState {
+  // Manual state transition is not allowed
+  return;
+}
+
+// Overrides [requestWriter(Transformations):map:] for Protocol Buffers
+// encoding.
+// We need the return value of this map to be a GRXImmediateSingleWriter but
+// the original \a map function returns a new Writer of another type. So we
+// need to override this function here.
+- (GRXWriter *)map:(id (^)(id))map {
+  // Since _value is available when creating the object, we can simply
+  // apply the map and store the output.
+  _value = map(_value);
+  return self;
+}
+
+@end
diff --git a/src/objective-c/RxLibrary/GRXWriter+Immediate.m b/src/objective-c/RxLibrary/GRXWriter+Immediate.m
index 1d55eb35293ecddf4757b792d8b0a764fb533a9d..ea6e6814063be76e8cfa0f6907f1cc5e58912865 100644
--- a/src/objective-c/RxLibrary/GRXWriter+Immediate.m
+++ b/src/objective-c/RxLibrary/GRXWriter+Immediate.m
@@ -34,6 +34,7 @@
 #import "GRXWriter+Immediate.h"
 
 #import "GRXImmediateWriter.h"
+#import "GRXImmediateSingleWriter.h"
 
 @implementation GRXWriter (Immediate)
 
@@ -50,7 +51,7 @@
 }
 
 + (instancetype)writerWithValue:(id)value {
-  return [GRXImmediateWriter writerWithValue:value];
+  return [GRXImmediateSingleWriter writerWithValue:value];
 }
 
 + (instancetype)writerWithError:(NSError *)error {
diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m
index 1e0c8024cab3363d219bf8813077dd76119284c5..3dd264718cb975840a511c64f4e8e6fbd6e7725f 100644
--- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m
+++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m
@@ -79,7 +79,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
   gpr_join_host_port(&ffd->localaddr, "127.0.0.1", port);
 
   f.fixture_data = ffd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
   return f;
 }
@@ -273,8 +274,7 @@ static char *roots_filename;
 }
 
 - (void)testCompressedPayload {
-  // NOT SUPPORTED
-  // [self testIndividualCase:"compressed_payload"];
+  [self testIndividualCase:"compressed_payload"];
 }
 
 - (void)testConnectivity {
diff --git a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m
index e97f3d2d1a9edbbc99b5a4f111f7df4d1c60390e..a78dd93993f9c4670d6497c5918fda7e40e762ba 100644
--- a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m
+++ b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m
@@ -160,7 +160,7 @@ unsigned int parse_h2_length(const char *field) {
   int port = grpc_pick_unused_port_or_die();
   char *addr;
   gpr_join_host_port(&addr, "127.0.0.1", port);
-  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+  grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
   stream_engine *cronetEngine = [Cronet getGlobalEngine];
   grpc_channel *client =
       grpc_cronet_secure_channel_create(cronetEngine, addr, NULL, NULL);
@@ -187,6 +187,18 @@ unsigned int parse_h2_length(const char *field) {
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  int sl = socket(AF_INET, SOCK_STREAM, 0);
+  GPR_ASSERT(sl >= 0);
+
+  // Make an TCP endpoint to accept the connection
+  struct sockaddr_in s_addr;
+  memset(&s_addr, 0, sizeof(s_addr));
+  s_addr.sin_family = AF_INET;
+  s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+  s_addr.sin_port = htons(port);
+  GPR_ASSERT(0 == bind(sl, (struct sockaddr *)&s_addr, sizeof(s_addr)));
+  GPR_ASSERT(0 == listen(sl, 5));
+
   memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
@@ -226,17 +238,6 @@ unsigned int parse_h2_length(const char *field) {
 
   dispatch_async(
       dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
-        int sl = socket(AF_INET, SOCK_STREAM, 0);
-        GPR_ASSERT(sl >= 0);
-
-        // Make and TCP endpoint to accept the connection
-        struct sockaddr_in s_addr;
-        memset(&s_addr, 0, sizeof(s_addr));
-        s_addr.sin_family = AF_INET;
-        s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-        s_addr.sin_port = htons(port);
-        GPR_ASSERT(0 == bind(sl, (struct sockaddr *)&s_addr, sizeof(s_addr)));
-        GPR_ASSERT(0 == listen(sl, 5));
         int s = accept(sl, NULL, NULL);
         GPR_ASSERT(s >= 0);
 
@@ -257,7 +258,7 @@ unsigned int parse_h2_length(const char *field) {
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
 
   cq_verifier_destroy(cqv);
 
@@ -294,7 +295,7 @@ unsigned int parse_h2_length(const char *field) {
   int port = grpc_pick_unused_port_or_die();
   char *addr;
   gpr_join_host_port(&addr, "127.0.0.1", port);
-  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+  grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
   stream_engine *cronetEngine = [Cronet getGlobalEngine];
   grpc_channel *client =
       grpc_cronet_secure_channel_create(cronetEngine, addr, args, NULL);
@@ -324,17 +325,18 @@ unsigned int parse_h2_length(const char *field) {
   __weak XCTestExpectation *expectation =
       [self expectationWithDescription:@"Coalescing"];
 
+  int sl = socket(AF_INET, SOCK_STREAM, 0);
+  GPR_ASSERT(sl >= 0);
+  struct sockaddr_in s_addr;
+  memset(&s_addr, 0, sizeof(s_addr));
+  s_addr.sin_family = AF_INET;
+  s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+  s_addr.sin_port = htons(port);
+  GPR_ASSERT(0 == bind(sl, (struct sockaddr *)&s_addr, sizeof(s_addr)));
+  GPR_ASSERT(0 == listen(sl, 5));
+
   dispatch_async(
       dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
-        int sl = socket(AF_INET, SOCK_STREAM, 0);
-        GPR_ASSERT(sl >= 0);
-        struct sockaddr_in s_addr;
-        memset(&s_addr, 0, sizeof(s_addr));
-        s_addr.sin_family = AF_INET;
-        s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-        s_addr.sin_port = htons(port);
-        GPR_ASSERT(0 == bind(sl, (struct sockaddr *)&s_addr, sizeof(s_addr)));
-        GPR_ASSERT(0 == listen(sl, 5));
         int s = accept(sl, NULL, NULL);
         GPR_ASSERT(s >= 0);
         struct timeval tv;
@@ -389,9 +391,6 @@ unsigned int parse_h2_length(const char *field) {
         [expectation fulfill];
       });
 
-  // Guarantees that server is listening to the port before client connects.
-  sleep(1);
-
   memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
@@ -438,7 +437,7 @@ unsigned int parse_h2_length(const char *field) {
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
 
   cq_verifier_destroy(cqv);
 
diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m
index 0b72a75f3d5b275cd5215a37d18b52548fcf775e..e36f5c3ee937e81db6148079988b69f8c91f858a 100644
--- a/src/objective-c/tests/GRPCClientTests.m
+++ b/src/objective-c/tests/GRPCClientTests.m
@@ -38,6 +38,7 @@
 #import <GRPCClient/GRPCCall+ChannelArg.h>
 #import <GRPCClient/GRPCCall+OAuth2.h>
 #import <GRPCClient/GRPCCall+Tests.h>
+#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
 #import <ProtoRPC/ProtoMethod.h>
 #import <RemoteTest/Messages.pbobjc.h>
 #import <RxLibrary/GRXWriteable.h>
@@ -352,4 +353,59 @@ static GRPCProtoMethod *kUnaryCallMethod;
   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
 }
 
+- (void)testAlternateDispatchQueue {
+  const int32_t kPayloadSize = 100;
+  RMTSimpleRequest *request = [RMTSimpleRequest message];
+  request.responseSize = kPayloadSize;
+
+  __weak XCTestExpectation *expectation1 = [self expectationWithDescription:@"AlternateDispatchQueue1"];
+
+  // Use default (main) dispatch queue
+  NSString *main_queue_label = [NSString stringWithUTF8String:dispatch_queue_get_label(dispatch_get_main_queue())];
+
+  GRXWriter *requestsWriter1 = [GRXWriter writerWithValue:[request data]];
+
+  GRPCCall *call1 = [[GRPCCall alloc] initWithHost:kHostAddress
+                                              path:kUnaryCallMethod.HTTPPath
+                                    requestsWriter:requestsWriter1];
+
+  id<GRXWriteable> responsesWriteable1 = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+    NSString *label = [NSString stringWithUTF8String:dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)];
+    XCTAssert([label isEqualToString:main_queue_label]);
+
+    [expectation1 fulfill];
+  } completionHandler:^(NSError *errorOrNil) {
+  }];
+
+  [call1 startWithWriteable:responsesWriteable1];
+
+  [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
+
+  // Use a custom  queue
+  __weak XCTestExpectation *expectation2 = [self expectationWithDescription:@"AlternateDispatchQueue2"];
+
+  NSString *queue_label = @"test.queue1";
+  dispatch_queue_t queue = dispatch_queue_create([queue_label UTF8String], DISPATCH_QUEUE_SERIAL);
+
+  GRXWriter *requestsWriter2 = [GRXWriter writerWithValue:[request data]];
+
+  GRPCCall *call2 = [[GRPCCall alloc] initWithHost:kHostAddress
+                                              path:kUnaryCallMethod.HTTPPath
+                                    requestsWriter:requestsWriter2];
+
+  [call2 setResponseDispatchQueue:queue];
+
+  id<GRXWriteable> responsesWriteable2 = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+    NSString *label = [NSString stringWithUTF8String:dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)];
+    XCTAssert([label isEqualToString:queue_label]);
+
+    [expectation2 fulfill];
+  } completionHandler:^(NSError *errorOrNil) {
+  }];
+
+  [call2 startWithWriteable:responsesWriteable2];
+
+  [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
+}
+
 @end
diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m
index 5584246ad94eb55a6d1c4c4cac9130c3428417a5..69968dcb609e591a63902d63c8d7f6781f6194e8 100644
--- a/src/objective-c/tests/InteropTests.m
+++ b/src/objective-c/tests/InteropTests.m
@@ -38,6 +38,7 @@
 #import <Cronet/Cronet.h>
 #import <GRPCClient/GRPCCall+ChannelArg.h>
 #import <GRPCClient/GRPCCall+Tests.h>
+#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
 #import <GRPCClient/GRPCCall+Cronet.h>
 #import <ProtoRPC/ProtoRPC.h>
 #import <RemoteTest/Messages.pbobjc.h>
@@ -45,6 +46,8 @@
 #import <RemoteTest/Test.pbrpc.h>
 #import <RxLibrary/GRXBufferedPipe.h>
 #import <RxLibrary/GRXWriter+Immediate.h>
+#import <grpc/support/log.h>
+#import <grpc/grpc.h>
 
 #define TEST_TIMEOUT 32
 
@@ -90,6 +93,9 @@
   return nil;
 }
 
+// This number indicates how many bytes of overhead does Protocol Buffers encoding add onto the
+// message. The number varies as different message.proto is used on different servers. The actual
+// number for each interop server is overridden in corresponding derived test classes.
 - (int32_t)encodingOverhead {
   return 0;
 }
@@ -152,6 +158,44 @@
   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
 }
 
+- (void)testPacketCoalescing {
+  XCTAssertNotNil(self.class.host);
+  __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"];
+
+  RMTSimpleRequest *request = [RMTSimpleRequest message];
+  request.responseType = RMTPayloadType_Compressable;
+  request.responseSize = 10;
+  request.payload.body = [NSMutableData dataWithLength:10];
+
+  [GRPCCall enableOpBatchLog:YES];
+  [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
+    XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+
+    RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message];
+    expectedResponse.payload.type = RMTPayloadType_Compressable;
+    expectedResponse.payload.body = [NSMutableData dataWithLength:10];
+    XCTAssertEqualObjects(response, expectedResponse);
+
+    // The test is a success if there is a batch of exactly 3 ops (SEND_INITIAL_METADATA,
+    // SEND_MESSAGE, SEND_CLOSE_FROM_CLIENT). Without packet coalescing each batch of ops contains
+    // only one op.
+    NSArray *opBatches = [GRPCCall obtainAndCleanOpBatchLog];
+    const NSInteger kExpectedOpBatchSize = 3;
+    for (NSObject *o in opBatches) {
+      if ([o isKindOfClass:[NSArray class]]) {
+        NSArray *batch = (NSArray *)o;
+        if ([batch count] == kExpectedOpBatchSize) {
+          [expectation fulfill];
+          break;
+        }
+      }
+    }
+  }];
+
+  [self waitForExpectationsWithTimeout:16 handler:nil];
+  [GRPCCall enableOpBatchLog:NO];
+}
+
 - (void)test4MBResponsesAreAccepted {
   XCTAssertNotNil(self.class.host);
   __weak XCTestExpectation *expectation = [self expectationWithDescription:@"MaxResponseSize"];
@@ -169,8 +213,6 @@
   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
 }
 
-#ifndef GRPC_COMPILE_WITH_CRONET
-// TODO (mxyan): Fix this test
 - (void)testResponsesOverMaxSizeFailWithActionableMessage {
   XCTAssertNotNil(self.class.host);
   __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ResponseOverMaxSize"];
@@ -191,7 +233,6 @@
 
   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
 }
-#endif
 
 - (void)testResponsesOver4MBAreAcceptedIfOptedIn {
   XCTAssertNotNil(self.class.host);
@@ -327,8 +368,6 @@
   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
 }
 
-#ifndef GRPC_COMPILE_WITH_CRONET
-// TODO(makdharma@): Fix this test
 - (void)testEmptyStreamRPC {
   XCTAssertNotNil(self.class.host);
   __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"];
@@ -342,7 +381,6 @@
   }];
   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
 }
-#endif
 
 - (void)testCancelAfterBeginRPC {
   XCTAssertNotNil(self.class.host);
diff --git a/src/objective-c/tests/InteropTestsLocalCleartext.m b/src/objective-c/tests/InteropTestsLocalCleartext.m
index b41210f50f85aca5d6c36837a585c08bfaf45e13..cdcdd8a88c705f706f66cbbbd89eff30b766589c 100644
--- a/src/objective-c/tests/InteropTestsLocalCleartext.m
+++ b/src/objective-c/tests/InteropTestsLocalCleartext.m
@@ -32,10 +32,19 @@
  */
 
 #import <GRPCClient/GRPCCall+Tests.h>
+#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
 
 #import "InteropTests.h"
 
-static NSString * const kLocalCleartextHost = @"localhost:5050";
+// The server address is derived from preprocessor macro, which is
+// in turn derived from environment variable of the same name.
+#define NSStringize_helper(x) #x
+#define NSStringize(x) @NSStringize_helper(x)
+static NSString * const kLocalCleartextHost = NSStringize(HOST_PORT_LOCAL);
+
+// The Protocol Buffers encoding overhead of local interop server. Acquired
+// by experiment. Adjust this when server's proto file changes.
+static int32_t kLocalInteropServerOverhead = 10;
 
 /** Tests in InteropTests.m, sending the RPCs to a local cleartext server. */
 @interface InteropTestsLocalCleartext : InteropTests
@@ -48,7 +57,7 @@ static NSString * const kLocalCleartextHost = @"localhost:5050";
 }
 
 - (int32_t)encodingOverhead {
-  return 10; // bytes
+  return kLocalInteropServerOverhead; // bytes
 }
 
 - (void)setUp {
diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m
index 1479c5896c39488960a88516ba332a60c058f26d..45e62d29b9a1e03da33a80531786e1f411c1295e 100644
--- a/src/objective-c/tests/InteropTestsLocalSSL.m
+++ b/src/objective-c/tests/InteropTestsLocalSSL.m
@@ -32,10 +32,18 @@
  */
 
 #import <GRPCClient/GRPCCall+Tests.h>
+#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
 
 #import "InteropTests.h"
+// The server address is derived from preprocessor macro, which is
+// in turn derived from environment variable of the same name.
+#define NSStringize_helper(x) #x
+#define NSStringize(x) @NSStringize_helper(x)
+static NSString * const kLocalSSLHost = NSStringize(HOST_PORT_LOCALSSL);
 
-static NSString * const kLocalSSLHost = @"localhost:5051";
+// The Protocol Buffers encoding overhead of local interop server. Acquired
+// by experiment. Adjust this when server's proto file changes.
+static int32_t kLocalInteropServerOverhead = 10;
 
 /** Tests in InteropTests.m, sending the RPCs to a local SSL server. */
 @interface InteropTestsLocalSSL : InteropTests
@@ -48,7 +56,7 @@ static NSString * const kLocalSSLHost = @"localhost:5051";
 }
 
 - (int32_t)encodingOverhead {
-  return 10; // bytes
+  return kLocalInteropServerOverhead; // bytes
 }
 
 - (void)setUp {
diff --git a/src/objective-c/tests/InteropTestsRemote.m b/src/objective-c/tests/InteropTestsRemote.m
index 70f84753bb6e3e140c3870bb98cdc1d0a974da06..5260fe4570b459d055faf0fa03aefe6eb135401c 100644
--- a/src/objective-c/tests/InteropTestsRemote.m
+++ b/src/objective-c/tests/InteropTestsRemote.m
@@ -32,10 +32,19 @@
  */
 
 #import <GRPCClient/GRPCCall+Tests.h>
+#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
 
 #import "InteropTests.h"
 
-static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.googleapis.com";
+// The server address is derived from preprocessor macro, which is
+// in turn derived from environment variable of the same name.
+#define NSStringize_helper(x) #x
+#define NSStringize(x) @NSStringize_helper(x)
+static NSString * const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE);
+
+// The Protocol Buffers encoding overhead of remote interop server. Acquired
+// by experiment. Adjust this when server's proto file changes.
+static int32_t kRemoteInteropServerOverhead = 12;
 
 /** Tests in InteropTests.m, sending the RPCs to a remote SSL server. */
 @interface InteropTestsRemote : InteropTests
@@ -48,7 +57,7 @@ static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.googleapis.com";
 }
 
 - (int32_t)encodingOverhead {
-  return 12; // bytes
+  return kRemoteInteropServerOverhead; // bytes
 }
 
 @end
diff --git a/src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m b/src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m
index fab8ad8d25f2cf594ef97a7efff244c56f5dc2b8..a7f190d2b4ad7e81edcec7374916e75fc2c81eac 100644
--- a/src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m
+++ b/src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m
@@ -32,10 +32,23 @@
  */
 
 #import <GRPCClient/GRPCCall+Tests.h>
+#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
+
+#import <Cronet/Cronet.h>
+#import <GRPCClient/GRPCCall+Cronet.h>
 
 #import "InteropTests.h"
 
-static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.googleapis.com";
+// The server address is derived from preprocessor macro, which is
+// in turn derived from environment variable of the same name.
+#define NSStringize_helper(x) #x
+#define NSStringize(x) @NSStringize_helper(x)
+static NSString * const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE);
+
+
+// The Protocol Buffers encoding overhead of remote interop server. Acquired
+// by experiment. Adjust this when server's proto file changes.
+static int32_t kRemoteInteropServerOverhead = 12;
 
 /** Tests in InteropTests.m, sending the RPCs to a remote SSL server. */
 @interface InteropTestsRemoteWithCronet : InteropTests
@@ -47,4 +60,8 @@ static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.googleapis.com";
   return kRemoteSSLHost;
 }
 
+- (int32_t)encodingOverhead {
+  return kRemoteInteropServerOverhead; // bytes
+}
+
 @end
diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile
index 3760330be9a19456d047c7a663d975e67e9955d9..8f1cb041d86df17354b84175cc01dddc3ec7d86d 100644
--- a/src/objective-c/tests/Podfile
+++ b/src/objective-c/tests/Podfile
@@ -97,15 +97,20 @@ post_install do |installer|
         # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void
         # function" warning
         config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO'
+        config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CRONET_WITH_PACKET_COALESCING=1'
       end
     end
 
     # Activate Cronet for the dedicated build configuration 'Cronet', which will be used solely by
     # the test target 'InteropTestsRemoteWithCronet'
+    # Activate GRPCCall+InternalTests functions for the dedicated build configuration 'Test', which will
+    # be used by all test targets using it.
     if target.name == 'gRPC'
       target.build_configurations.each do |config|
         if config.name == 'Cronet'
-          config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_COMPILE_WITH_CRONET=1'
+          config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_COMPILE_WITH_CRONET=1 GRPC_TEST_OBJC=1'
+        elsif config.name == 'Test'
+          config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_TEST_OBJC=1'
         end
       end
     end
diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
index 32b35ef333abe476d1ba736c02c4153da65b2ec1..b01d5ffceaaf006966af0e78bde3b6341e045389 100644
--- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
+++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
@@ -125,8 +125,10 @@
 		0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
 		0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.debug.xcconfig"; sourceTree = "<group>"; };
 		14B09A58FEE53A7A6B838920 /* Pods-InteropTestsLocalSSL.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.cronet.xcconfig"; sourceTree = "<group>"; };
+		1588C85DEAF7FC0ACDEA4C02 /* Pods-InteropTestsLocalCleartext.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.test.xcconfig"; sourceTree = "<group>"; };
 		17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; sourceTree = "<group>"; };
 		20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+		2B89F3037963E6EDDD48D8C3 /* Pods-InteropTestsRemoteWithCronet.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.test.xcconfig"; sourceTree = "<group>"; };
 		35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
 		386712AEACF7C2190C4B8B3F /* Pods-CronetUnitTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.cronet.xcconfig"; sourceTree = "<group>"; };
 		3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.release.xcconfig"; sourceTree = "<group>"; };
@@ -162,15 +164,22 @@
 		63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTestsLocalSSL.m; sourceTree = "<group>"; };
 		63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = TestCertificates.bundle; sourceTree = "<group>"; };
 		64F68A9A6A63CC930DD30A6E /* Pods-CronetUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.debug.xcconfig"; sourceTree = "<group>"; };
+		6793C9D019CB268C5BB491A2 /* Pods-CoreCronetEnd2EndTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.test.xcconfig"; sourceTree = "<group>"; };
+		781089FAE980F51F88A3BE0B /* Pods-RxLibraryUnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.test.xcconfig"; sourceTree = "<group>"; };
 		79C68EFFCB5533475D810B79 /* Pods-RxLibraryUnitTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.cronet.xcconfig"; sourceTree = "<group>"; };
 		7A2E97E3F469CC2A758D77DE /* Pods-InteropTestsLocalSSL.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.release.xcconfig"; sourceTree = "<group>"; };
 		9E9444C764F0FFF64A7EB58E /* libPods-InteropTestsRemoteWithCronet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemoteWithCronet.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+		A0361771A855917162911180 /* Pods-Tests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.test.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.test.xcconfig"; sourceTree = "<group>"; };
 		A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RxLibraryUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+		A6F832FCEFA6F6881E620F12 /* Pods-InteropTestsRemote.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.test.xcconfig"; sourceTree = "<group>"; };
 		AA7CB64B4DD9915AE7C03163 /* Pods-InteropTestsLocalCleartext.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.cronet.xcconfig"; sourceTree = "<group>"; };
 		AC414EF7A6BF76ED02B6E480 /* Pods-InteropTestsRemoteWithCronet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.release.xcconfig"; sourceTree = "<group>"; };
+		B226619DC4E709E0FFFF94B8 /* Pods-CronetUnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.test.xcconfig"; sourceTree = "<group>"; };
 		B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.debug.xcconfig"; sourceTree = "<group>"; };
 		C6134277D2EB8B380862A03F /* libPods-CronetUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CronetUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AllTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+		D13BEC8181B8E678A1B52F54 /* Pods-InteropTestsLocalSSL.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.test.xcconfig"; sourceTree = "<group>"; };
+		DB1F4391AF69D20D38D74B67 /* Pods-AllTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.test.xcconfig"; sourceTree = "<group>"; };
 		DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemote.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		DBEDE45BDA60DF1E1C8950C0 /* libPods-InteropTestsLocalSSL.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalSSL.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		DC3CA1D948F068E76957A861 /* Pods-InteropTestsRemote.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.debug.xcconfig"; sourceTree = "<group>"; };
@@ -317,6 +326,15 @@
 				64F68A9A6A63CC930DD30A6E /* Pods-CronetUnitTests.debug.xcconfig */,
 				386712AEACF7C2190C4B8B3F /* Pods-CronetUnitTests.cronet.xcconfig */,
 				02192CF1FF9534E3D18C65FC /* Pods-CronetUnitTests.release.xcconfig */,
+				DB1F4391AF69D20D38D74B67 /* Pods-AllTests.test.xcconfig */,
+				6793C9D019CB268C5BB491A2 /* Pods-CoreCronetEnd2EndTests.test.xcconfig */,
+				B226619DC4E709E0FFFF94B8 /* Pods-CronetUnitTests.test.xcconfig */,
+				1588C85DEAF7FC0ACDEA4C02 /* Pods-InteropTestsLocalCleartext.test.xcconfig */,
+				D13BEC8181B8E678A1B52F54 /* Pods-InteropTestsLocalSSL.test.xcconfig */,
+				A6F832FCEFA6F6881E620F12 /* Pods-InteropTestsRemote.test.xcconfig */,
+				2B89F3037963E6EDDD48D8C3 /* Pods-InteropTestsRemoteWithCronet.test.xcconfig */,
+				781089FAE980F51F88A3BE0B /* Pods-RxLibraryUnitTests.test.xcconfig */,
+				A0361771A855917162911180 /* Pods-Tests.test.xcconfig */,
 			);
 			name = Pods;
 			sourceTree = "<group>";
@@ -1237,6 +1255,213 @@
 /* End PBXTargetDependency section */
 
 /* Begin XCBuildConfiguration section */
+		5E1228981E4D400F00E8504F /* Test */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+					"HOST_PORT_LOCALSSL=$(HOST_PORT_LOCALSSL)",
+					"HOST_PORT_LOCAL=$(HOST_PORT_LOCAL)",
+					"HOST_PORT_REMOTE=$(HOST_PORT_REMOTE)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 8.3;
+				MTL_ENABLE_DEBUG_INFO = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = iphoneos;
+			};
+			name = Test;
+		};
+		5E1228991E4D400F00E8504F /* Test */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = A0361771A855917162911180 /* Pods-Tests.test.xcconfig */;
+			buildSettings = {
+				GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SKIP_INSTALL = YES;
+			};
+			name = Test;
+		};
+		5E12289A1E4D400F00E8504F /* Test */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = DB1F4391AF69D20D38D74B67 /* Pods-AllTests.test.xcconfig */;
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(SDKROOT)/Developer/Library/Frameworks",
+					"$(inherited)",
+				);
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+					"GRPC_TEST_OBJC=1",
+				);
+				INFOPLIST_FILE = Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Test;
+		};
+		5E12289B1E4D400F00E8504F /* Test */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 781089FAE980F51F88A3BE0B /* Pods-RxLibraryUnitTests.test.xcconfig */;
+			buildSettings = {
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_TESTABILITY = YES;
+				INFOPLIST_FILE = Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = io.grpc.RxLibraryUnitTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Test;
+		};
+		5E12289C1E4D400F00E8504F /* Test */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = A6F832FCEFA6F6881E620F12 /* Pods-InteropTestsRemote.test.xcconfig */;
+			buildSettings = {
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_TESTABILITY = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"$(inherited)",
+					"COCOAPODS=1",
+					"$(inherited)",
+					"GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1",
+					"GRPC_TEST_OBJC=1",
+				);
+				INFOPLIST_FILE = Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Test;
+		};
+		5E12289D1E4D400F00E8504F /* Test */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = D13BEC8181B8E678A1B52F54 /* Pods-InteropTestsLocalSSL.test.xcconfig */;
+			buildSettings = {
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_TESTABILITY = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"$(inherited)",
+					"COCOAPODS=1",
+					"$(inherited)",
+					"GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1",
+					"GRPC_TEST_OBJC=1",
+				);
+				INFOPLIST_FILE = Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSL;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Test;
+		};
+		5E12289E1E4D400F00E8504F /* Test */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 1588C85DEAF7FC0ACDEA4C02 /* Pods-InteropTestsLocalCleartext.test.xcconfig */;
+			buildSettings = {
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_TESTABILITY = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"$(inherited)",
+					"COCOAPODS=1",
+					"GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1",
+					"GRPC_TEST_OBJC=1",
+				);
+				INFOPLIST_FILE = Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartext;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Test;
+		};
+		5E12289F1E4D400F00E8504F /* Test */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 6793C9D019CB268C5BB491A2 /* Pods-CoreCronetEnd2EndTests.test.xcconfig */;
+			buildSettings = {
+				CLANG_ANALYZER_NONNULL = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_TESTABILITY = YES;
+				INFOPLIST_FILE = CoreCronetEnd2EndTests/Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CoreCronetEnd2EndTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				USER_HEADER_SEARCH_PATHS = "$(inherited) \"${PODS_ROOT}/../../../..\"";
+			};
+			name = Test;
+		};
+		5E1228A01E4D400F00E8504F /* Test */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 2B89F3037963E6EDDD48D8C3 /* Pods-InteropTestsRemoteWithCronet.test.xcconfig */;
+			buildSettings = {
+				CLANG_ANALYZER_NONNULL = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_TESTABILITY = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"$(inherited)",
+					"COCOAPODS=1",
+					"GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1",
+					"GRPC_TEST_OBJC=1",
+				);
+				INFOPLIST_FILE = InteropTestsRemoteWithCronet/Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteWithCronet;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Test;
+		};
+		5E1228A11E4D400F00E8504F /* Test */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = B226619DC4E709E0FFFF94B8 /* Pods-CronetUnitTests.test.xcconfig */;
+			buildSettings = {
+				CLANG_ANALYZER_NONNULL = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_TESTABILITY = YES;
+				INFOPLIST_FILE = CronetUnitTests/Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CronetUnitTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				USER_HEADER_SEARCH_PATHS = "\"${PODS_ROOT}/../../../..\" $(inherited)";
+			};
+			name = Test;
+		};
 		5E8A5DAC1D3840B4000F8BC4 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */;
@@ -1343,6 +1568,7 @@
 				GCC_PREPROCESSOR_DEFINITIONS = (
 					"DEBUG=1",
 					"$(inherited)",
+					"HOST_PORT_REMOTE=$(HOST_PORT_REMOTE)",
 				);
 				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
 				GCC_TREAT_WARNINGS_AS_ERRORS = YES;
@@ -1407,6 +1633,12 @@
 			buildSettings = {
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				ENABLE_TESTABILITY = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"$(inherited)",
+					"COCOAPODS=1",
+					"$(inherited)",
+					"GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1",
+				);
 				INFOPLIST_FILE = Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@@ -1471,10 +1703,10 @@
 				GCC_PREPROCESSOR_DEFINITIONS = (
 					"$(inherited)",
 					"COCOAPODS=1",
-					"$(inherited)",
 					"GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1",
 					"GRPC_COMPILE_WITH_CRONET=1",
 					"GRPC_CRONET_WITH_PACKET_COALESCING=1",
+					"GRPC_TEST_OBJC=1",
 				);
 				INFOPLIST_FILE = InteropTestsRemoteWithCronet/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 9.3;
@@ -1495,7 +1727,6 @@
 				GCC_PREPROCESSOR_DEFINITIONS = (
 					"$(inherited)",
 					"COCOAPODS=1",
-					"$(inherited)",
 					"GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1",
 				);
 				INFOPLIST_FILE = InteropTestsRemoteWithCronet/Info.plist;
@@ -1770,6 +2001,7 @@
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				5E8A5DAC1D3840B4000F8BC4 /* Debug */,
+				5E12289F1E4D400F00E8504F /* Test */,
 				5EC3C7A71D4FC18C000330E2 /* Cronet */,
 				5E8A5DAD1D3840B4000F8BC4 /* Release */,
 			);
@@ -1780,6 +2012,7 @@
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				5EAD6D2C1E27047400002378 /* Debug */,
+				5E1228A11E4D400F00E8504F /* Test */,
 				5EAD6D2D1E27047400002378 /* Cronet */,
 				5EAD6D2E1E27047400002378 /* Release */,
 			);
@@ -1790,6 +2023,7 @@
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				5EE84BF91D4717E40050C6CC /* Debug */,
+				5E1228A01E4D400F00E8504F /* Test */,
 				5EC3C7A81D4FC18C000330E2 /* Cronet */,
 				5EE84BFA1D4717E40050C6CC /* Release */,
 			);
@@ -1800,6 +2034,7 @@
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				63423F4E1B150A5F006CF63C /* Debug */,
+				5E12289A1E4D400F00E8504F /* Test */,
 				5EC3C7A21D4FC18C000330E2 /* Cronet */,
 				63423F4F1B150A5F006CF63C /* Release */,
 			);
@@ -1810,6 +2045,7 @@
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				635697D91B14FC11007A7283 /* Debug */,
+				5E1228981E4D400F00E8504F /* Test */,
 				5EC3C7A01D4FC18C000330E2 /* Cronet */,
 				635697DA1B14FC11007A7283 /* Release */,
 			);
@@ -1820,6 +2056,7 @@
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				635697DC1B14FC11007A7283 /* Debug */,
+				5E1228991E4D400F00E8504F /* Test */,
 				5EC3C7A11D4FC18C000330E2 /* Cronet */,
 				635697DD1B14FC11007A7283 /* Release */,
 			);
@@ -1830,6 +2067,7 @@
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				63DC841C1BE15179000708E8 /* Debug */,
+				5E12289B1E4D400F00E8504F /* Test */,
 				5EC3C7A31D4FC18C000330E2 /* Cronet */,
 				63DC841D1BE15179000708E8 /* Release */,
 			);
@@ -1840,6 +2078,7 @@
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				63DC842C1BE15267000708E8 /* Debug */,
+				5E12289C1E4D400F00E8504F /* Test */,
 				5EC3C7A41D4FC18C000330E2 /* Cronet */,
 				63DC842D1BE15267000708E8 /* Release */,
 			);
@@ -1850,6 +2089,7 @@
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				63DC843D1BE15294000708E8 /* Debug */,
+				5E12289D1E4D400F00E8504F /* Test */,
 				5EC3C7A51D4FC18C000330E2 /* Cronet */,
 				63DC843E1BE15294000708E8 /* Release */,
 			);
@@ -1860,6 +2100,7 @@
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				63DC844C1BE152B5000708E8 /* Debug */,
+				5E12289E1E4D400F00E8504F /* Test */,
 				5EC3C7A61D4FC18C000330E2 /* Cronet */,
 				63DC844D1BE152B5000708E8 /* Release */,
 			);
diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme
index 49dc3faa3d093223c0ee7b34f4d0337e85f61207..a2560fee0298638061b3660edf8ac063ce215713 100644
--- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme
+++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme
@@ -23,7 +23,7 @@
       </BuildActionEntries>
    </BuildAction>
    <TestAction
-      buildConfiguration = "Debug"
+      buildConfiguration = "Test"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       shouldUseLaunchSchemeArgsEnv = "YES">
@@ -49,26 +49,6 @@
                </Test>
             </SkippedTests>
          </TestableReference>
-         <TestableReference
-            skipped = "NO">
-            <BuildableReference
-               BuildableIdentifier = "primary"
-               BlueprintIdentifier = "5E8A5DA31D3840B4000F8BC4"
-               BuildableName = "CoreCronetEnd2EndTests.xctest"
-               BlueprintName = "CoreCronetEnd2EndTests"
-               ReferencedContainer = "container:Tests.xcodeproj">
-            </BuildableReference>
-         </TestableReference>
-         <TestableReference
-            skipped = "NO">
-            <BuildableReference
-               BuildableIdentifier = "primary"
-               BlueprintIdentifier = "5EAD6D231E27047400002378"
-               BuildableName = "CronetUnitTests.xctest"
-               BlueprintName = "CronetUnitTests"
-               ReferencedContainer = "container:Tests.xcodeproj">
-            </BuildableReference>
-         </TestableReference>
       </Testables>
       <MacroExpansion>
          <BuildableReference
@@ -83,7 +63,7 @@
       </AdditionalOptions>
    </TestAction>
    <LaunchAction
-      buildConfiguration = "Debug"
+      buildConfiguration = "Test"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       launchStyle = "0"
@@ -121,7 +101,7 @@
       </MacroExpansion>
    </ProfileAction>
    <AnalyzeAction
-      buildConfiguration = "Debug">
+      buildConfiguration = "Test">
    </AnalyzeAction>
    <ArchiveAction
       buildConfiguration = "Release"
diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme
index ce358bf69f5945e6da83b11eb4c47af4b7a75004..6d85b62fabf6e01e4c41db967ab16779a1ff6e77 100644
--- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme
+++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme
@@ -23,7 +23,7 @@
       </BuildActionEntries>
    </BuildAction>
    <TestAction
-      buildConfiguration = "Debug"
+      buildConfiguration = "Test"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       shouldUseLaunchSchemeArgsEnv = "YES">
@@ -54,7 +54,7 @@
       </AdditionalOptions>
    </TestAction>
    <LaunchAction
-      buildConfiguration = "Debug"
+      buildConfiguration = "Test"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       launchStyle = "0"
@@ -92,7 +92,7 @@
       </MacroExpansion>
    </ProfileAction>
    <AnalyzeAction
-      buildConfiguration = "Debug">
+      buildConfiguration = "Test">
    </AnalyzeAction>
    <ArchiveAction
       buildConfiguration = "Release"
diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSL.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSL.xcscheme
index f268da1fb0c1abdcdb3316385f1b284d16d00906..37135b3ad36b533d140318c5d499d28bb3921352 100644
--- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSL.xcscheme
+++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSL.xcscheme
@@ -23,7 +23,7 @@
       </BuildActionEntries>
    </BuildAction>
    <TestAction
-      buildConfiguration = "Debug"
+      buildConfiguration = "Test"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       shouldUseLaunchSchemeArgsEnv = "YES">
@@ -57,7 +57,7 @@
       </AdditionalOptions>
    </TestAction>
    <LaunchAction
-      buildConfiguration = "Debug"
+      buildConfiguration = "Test"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       launchStyle = "0"
@@ -86,7 +86,7 @@
       debugDocumentVersioning = "YES">
    </ProfileAction>
    <AnalyzeAction
-      buildConfiguration = "Debug">
+      buildConfiguration = "Test">
    </AnalyzeAction>
    <ArchiveAction
       buildConfiguration = "Release"
diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme
index 186d7208e04acc9c1bc9705d37d4e53ead431915..412bf6a0143168a1cd350fa775d2648fc0ea4407 100644
--- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme
+++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme
@@ -23,7 +23,7 @@
       </BuildActionEntries>
    </BuildAction>
    <TestAction
-      buildConfiguration = "Debug"
+      buildConfiguration = "Test"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       shouldUseLaunchSchemeArgsEnv = "YES">
@@ -57,7 +57,7 @@
       </AdditionalOptions>
    </TestAction>
    <LaunchAction
-      buildConfiguration = "Debug"
+      buildConfiguration = "Test"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       launchStyle = "0"
@@ -86,7 +86,7 @@
       debugDocumentVersioning = "YES">
    </ProfileAction>
    <AnalyzeAction
-      buildConfiguration = "Debug">
+      buildConfiguration = "Test">
    </AnalyzeAction>
    <ArchiveAction
       buildConfiguration = "Release"
diff --git a/src/objective-c/tests/build_example_test.sh b/src/objective-c/tests/build_example_test.sh
index ae75941ec613f630c538b80f9dfe3e8f5a0e8e96..5c50e831107165c6aec2cca684602a9b567e04cc 100755
--- a/src/objective-c/tests/build_example_test.sh
+++ b/src/objective-c/tests/build_example_test.sh
@@ -35,29 +35,38 @@ set -evo pipefail
 
 cd `dirname $0`
 
+trap 'echo "EXIT TIME:  $(date)"' EXIT
+
+echo "TIME:  $(date)"
 SCHEME=HelloWorld                              \
   EXAMPLE_PATH=examples/objective-c/helloworld \
   ./build_one_example.sh
 
+echo "TIME:  $(date)"
 SCHEME=RouteGuideClient                         \
   EXAMPLE_PATH=examples/objective-c/route_guide \
   ./build_one_example.sh
 
+echo "TIME:  $(date)"
 SCHEME=AuthSample                               \
   EXAMPLE_PATH=examples/objective-c/auth_sample \
   ./build_one_example.sh
 
 rm -f ../examples/RemoteTestClient/*.{h,m}
 
+echo "TIME:  $(date)"
 SCHEME=Sample                                  \
   EXAMPLE_PATH=src/objective-c/examples/Sample \
   ./build_one_example.sh
 
+echo "TIME:  $(date)"
 SCHEME=Sample                                  \
   EXAMPLE_PATH=src/objective-c/examples/Sample \
   FRAMEWORKS=YES                               \
   ./build_one_example.sh
 
+echo "TIME:  $(date)"
 SCHEME=SwiftSample                                  \
   EXAMPLE_PATH=src/objective-c/examples/SwiftSample \
   ./build_one_example.sh
+
diff --git a/src/objective-c/tests/build_one_example.sh b/src/objective-c/tests/build_one_example.sh
index 9fef6582a38b524e5383c605a0ebfdd1e7959819..bb55ca4ee1ee5dc21b2de897944d296ff7411c56 100755
--- a/src/objective-c/tests/build_one_example.sh
+++ b/src/objective-c/tests/build_one_example.sh
@@ -57,6 +57,4 @@ xcodebuild \
     build \
     -workspace *.xcworkspace \
     -scheme $SCHEME \
-    -destination name="iPhone 6" \
-    | egrep "$XCODEBUILD_FILTER" \
-    | egrep -v "(GPBDictionary|GPBArray)" -
+    -destination name="iPhone 6" | xcpretty
diff --git a/src/objective-c/tests/build_tests.sh b/src/objective-c/tests/build_tests.sh
index bc5bc0449436d59571f6548627563c6d76cbd21b..6602d510d94bc14b839a22114f6a2bdda4c863eb 100755
--- a/src/objective-c/tests/build_tests.sh
+++ b/src/objective-c/tests/build_tests.sh
@@ -50,4 +50,5 @@ rm -rf Tests.xcworkspace
 rm -f Podfile.lock
 rm -f RemoteTestClient/*.{h,m}
 
+echo "TIME:  $(date)"
 pod install
diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh
index 677459e0822b25f64d428d33e5b6104838883938..2432209f4f194755be0fa2385a8fdd952a424ceb 100755
--- a/src/objective-c/tests/run_tests.sh
+++ b/src/objective-c/tests/run_tests.sh
@@ -47,25 +47,45 @@ BINDIR=../../../bins/$CONFIG
 $BINDIR/interop_server --port=5050 --max_send_message_size=8388608 &
 $BINDIR/interop_server --port=5051 --max_send_message_size=8388608 --use_tls &
 # Kill them when this script exits.
-trap 'kill -9 `jobs -p`' EXIT
+trap 'kill -9 `jobs -p` ; echo "EXIT TIME:  $(date)"' EXIT
 
 # xcodebuild is very verbose. We filter its output and tell Bash to fail if any
 # element of the pipe fails.
 # TODO(jcanizales): Use xctool instead? Issue #2540.
 set -o pipefail
 XCODEBUILD_FILTER='(^===|^\*\*|\bfatal\b|\berror\b|\bwarning\b|\bfail)'
+echo "TIME:  $(date)"
 xcodebuild \
     -workspace Tests.xcworkspace \
     -scheme AllTests \
     -destination name="iPhone 6" \
-    test \
-    | egrep "$XCODEBUILD_FILTER" \
-    | egrep -v "(GPBDictionary|GPBArray)" -
+    HOST_PORT_LOCALSSL=localhost:5051 \
+    HOST_PORT_LOCAL=localhost:5050 \
+    HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \
+    test | xcpretty
 
+echo "TIME:  $(date)"
+xcodebuild \
+    -workspace Tests.xcworkspace \
+    -scheme CoreCronetEnd2EndTests \
+    -destination name="iPhone 6" \
+    test | xcpretty
+
+# Temporarily disabled for (possible) flakiness on Jenkins.
+# Fix or reenable after confirmation/disconfirmation that it is the source of
+# Jenkins problem.
+
+# echo "TIME:  $(date)"
+# xcodebuild \
+#     -workspace Tests.xcworkspace \
+#     -scheme CronetUnitTests \
+#     -destination name="iPhone 6" \
+#     test | xcpretty
+
+echo "TIME:  $(date)"
 xcodebuild \
     -workspace Tests.xcworkspace \
     -scheme InteropTestsRemoteWithCronet \
     -destination name="iPhone 6" \
-    test \
-    | egrep "$XCODEBUILD_FILTER" \
-    | egrep -v "(GPBDictionary|GPBArray)" -
+    HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \
+    test | xcpretty
diff --git a/src/php/README.md b/src/php/README.md
index f08541f16cf3783cdf9fa8ce51aa264126bc72fa..f9f93ba8159c093cecc83cf9a520566ac14621d7 100644
--- a/src/php/README.md
+++ b/src/php/README.md
@@ -1,5 +1,5 @@
 
-#Overview
+# Overview
 
 This directory contains source code for PHP implementation of gRPC layered on
 shared C library.
diff --git a/src/php/composer.json b/src/php/composer.json
index 491e34795ac0fd337c3443f93df04f9b4c270da5..24c17c3b572dacf45772a44005d11a71a09cda1e 100644
--- a/src/php/composer.json
+++ b/src/php/composer.json
@@ -2,7 +2,7 @@
   "name": "grpc/grpc-dev",
   "description": "gRPC library for PHP - for Developement use only",
   "license": "BSD-3-Clause",
-  "version": "1.2.0",
+  "version": "1.4.0",
   "require": {
     "php": ">=5.5.0",
     "google/protobuf": "^v3.1.0"
diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c
index 48a374fa08ef0127b8b987872a575e87d8d61d6d..d3fd88416b42518c87d8f29b02fea62797ddfdd6 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -65,7 +65,7 @@ static zend_object_handlers call_ce_handlers;
 /* Frees and destroys an instance of wrapped_grpc_call */
 PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_call)
   if (p->owned && p->wrapped != NULL) {
-    grpc_call_destroy(p->wrapped);
+    grpc_call_unref(p->wrapped);
   }
 PHP_GRPC_FREE_WRAPPED_FUNC_END()
 
diff --git a/src/php/ext/grpc/completion_queue.c b/src/php/ext/grpc/completion_queue.c
index 741204b0b10d4dfbe94072272956db1b4e1a3740..c75a524530e10ad148a24fabd3b56c7361693800 100644
--- a/src/php/ext/grpc/completion_queue.c
+++ b/src/php/ext/grpc/completion_queue.c
@@ -38,13 +38,10 @@
 grpc_completion_queue *completion_queue;
 
 void grpc_php_init_completion_queue(TSRMLS_D) {
-  completion_queue = grpc_completion_queue_create(NULL);
+  completion_queue = grpc_completion_queue_create_for_pluck(NULL);
 }
 
 void grpc_php_shutdown_completion_queue(TSRMLS_D) {
   grpc_completion_queue_shutdown(completion_queue);
-  while (grpc_completion_queue_next(completion_queue,
-                                    gpr_inf_future(GPR_CLOCK_REALTIME),
-                                    NULL).type != GRPC_QUEUE_SHUTDOWN);
   grpc_completion_queue_destroy(completion_queue);
 }
diff --git a/src/php/lib/Grpc/AbstractCall.php b/src/php/lib/Grpc/AbstractCall.php
index 40387abdc0727c7d793fb66cf5a667f33c663222..a59bfa3ba38d5cd628a4f3fd165e522f8dbdaa4b 100644
--- a/src/php/lib/Grpc/AbstractCall.php
+++ b/src/php/lib/Grpc/AbstractCall.php
@@ -131,6 +131,8 @@ abstract class AbstractCall
         // Proto3 implementation
         if (method_exists($data, 'encode')) {
             return $data->encode();
+        } elseif (method_exists($data, 'serializeToString')) {
+            return $data->serializeToString();
         }
 
         // Protobuf-PHP implementation
@@ -154,7 +156,11 @@ abstract class AbstractCall
         if (is_array($this->deserialize)) {
             list($className, $deserializeFunc) = $this->deserialize;
             $obj = new $className();
-            $obj->$deserializeFunc($value);
+            if (method_exists($obj, $deserializeFunc)) {
+                $obj->$deserializeFunc($value);
+            } else {
+                $obj->mergeFromString($value);
+            }
 
             return $obj;
         }
diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php
index ed504f85a869a193e48efd9e2726db9fbce2144a..24934491b4368d64b30599b46c7d99b718d14de3 100644
--- a/src/php/lib/Grpc/BaseStub.php
+++ b/src/php/lib/Grpc/BaseStub.php
@@ -87,7 +87,7 @@ class BaseStub
                                  'ChannelCredentials::create methods');
         }
         if ($channel) {
-            if (!is_a($channel, 'Channel')) {
+            if (!is_a($channel, 'Grpc\Channel')) {
                 throw new \Exception('The channel argument is not a'.
                                      'Channel object');
             }
diff --git a/src/php/tests/qps/client.php b/src/php/tests/qps/client.php
new file mode 100644
index 0000000000000000000000000000000000000000..d9ca35ba43d2ffa954bd24dfc400fcb672ce8ea5
--- /dev/null
+++ b/src/php/tests/qps/client.php
@@ -0,0 +1,166 @@
+<?php
+/*
+ *
+ * Copyright 2017, 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.
+ *
+ */
+
+/*
+ * PHP client for QPS testing works as follows:
+ * 1. Gets initiated by a call from a proxy that implements the worker service. The
+ *    argument to this client is the proxy connection information
+ * 2. Initiate an RPC to the proxy to get ClientConfig
+ * 3. Initiate a client-side telemetry RPC to the proxy
+ * 4. Parse the client config, which includes server target information and then start
+ *    a unary or streaming test as appropriate.
+ * 5. After each completed RPC, send its timing to the proxy. The proxy does all histogramming
+ * 6. Proxy will respond on the timing channel when it's time to complete. Our
+ *    next timing write will fail and we know that it's time to stop
+ * The above complex dance is since threading and async are not idiomatic and we
+ * shouldn't ever be waiting to read a mark
+ *
+ * This test only supports a single channel since threading/async is not idiomatic
+ * This test supports unary or streaming ping-pongs, as well as open-loop
+ * 
+ */
+
+require dirname(__FILE__).'/vendor/autoload.php';
+
+/**
+ * Assertion function that always exits with an error code if the assertion is
+ * falsy.
+ *
+ * @param $value Assertion value. Should be true.
+ * @param $error_message Message to display if the assertion is false
+ */
+function hardAssert($value, $error_message)
+{
+    if (!$value) {
+        echo $error_message."\n";
+        exit(1);
+    }
+}
+
+function hardAssertIfStatusOk($status)
+{
+    if ($status->code !== Grpc\STATUS_OK) {
+        echo "Call did not complete successfully. Status object:\n";
+        var_dump($status);
+        exit(1);
+    }
+}
+
+/* Start the actual client */
+
+function qps_client_main($proxy_address) {
+    echo "Initiating php client\n";
+
+    $proxystubopts = [];
+    $proxystubopts['credentials'] = Grpc\ChannelCredentials::createInsecure();
+    $proxystub = new Grpc\Testing\ProxyClientServiceClient($proxy_address, $proxystubopts);
+    list($config, $status) = $proxystub->GetConfig(new Grpc\Testing\Void())->wait();
+    hardAssertIfStatusOk($status);
+    hardAssert($config->getClientChannels() == 1, "Only 1 channel supported");
+    hardAssert($config->getOutstandingRpcsPerChannel() == 1, "Only 1 outstanding RPC supported");
+
+    echo "Got configuration from proxy, target is " . $config->getServerTargets()[0] . "\n";
+
+    $stubopts = [];
+    if ($config->getSecurityParams()) {
+        if ($config->getSecurityParams()->getUseTestCa()) {
+            $stubopts['credentials'] = Grpc\ChannelCredentials::createSsl(
+                file_get_contents(dirname(__FILE__).'/../data/ca.pem'));
+        } else {
+            $stubopts['credentials'] = Grpc\ChannelCredentials::createSsl(null);
+        }
+        $override = $config->getSecurityParams()->getServerHostOverride();
+        if ($override) {
+            $stubopts['grpc.ssl_target_name_override'] = $override;
+            $stubopts['grpc.default_authority'] = $override;
+        }
+    } else {
+        $stubopts['credentials'] = Grpc\ChannelCredentials::createInsecure();
+    }
+    echo "Initiating php benchmarking client\n";
+
+    $stub = new Grpc\Testing\BenchmarkServiceClient(
+        $config->getServerTargets()[0], $stubopts);
+    $req = new Grpc\Testing\SimpleRequest();
+
+    $req->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
+    $req->setResponseSize($config->getPayloadConfig()->getSimpleParams()->getRespSize());
+    $payload = new Grpc\Testing\Payload();
+    $payload->setType(Grpc\Testing\PayloadType::COMPRESSABLE);
+    $payload->setBody(str_repeat("\0", $config->getPayloadConfig()->getSimpleParams()->getReqSize()));
+    $req->setPayload($payload);
+
+    /* TODO(stanley-cheung): Enable the following by removing the 0&& once protobuf
+     * properly supports oneof in PHP */
+    if (0 && $config->getLoadParams()->getLoad() == "poisson") {
+        $poisson = true;
+        $lamrecip = 1.0/($config->getLoadParams()->getPoisson()->getOfferedLoad());
+        $issue = microtime(true) + $lamrecip * -log(1.0-rand()/(getrandmax()+1));
+    } else {
+        $poisson = false;
+    }
+    $metric = new Grpc\Testing\ProxyStat;
+    $telemetry = $proxystub->ReportTime();
+    if ($config->getRpcType() == Grpc\Testing\RpcType::UNARY) {
+        while (1) {
+            if ($poisson) {
+                time_sleep_until($issue);
+                $issue = $issue + $lamrecip * -log(1.0-rand()/(getrandmax()+1));
+            }
+            $startreq = microtime(true);
+            list($resp,$status) = $stub->UnaryCall($req)->wait();
+            hardAssertIfStatusOk($status);
+            $metric->setLatency(microtime(true)-$startreq);
+            $telemetry->write($metric);
+        }
+    } else {
+        $stream = $stub->StreamingCall();
+        while (1) {
+            if ($poisson) {
+                time_sleep_until($issue);
+                $issue = $issue + $lamrecip * -log(1.0-rand()/(getrandmax()+1));
+            }
+            $startreq = microtime(true);
+            $stream->write($req);
+            $resp = $stream->read();
+            $metric->setLatency(microtime(true)-$startreq);
+            $telemetry->write($metric);
+        }
+    }
+}
+
+ini_set('display_startup_errors', 1);
+ini_set('display_errors', 1);
+error_reporting(-1);
+qps_client_main($argv[1]);
diff --git a/src/php/tests/qps/composer.json b/src/php/tests/qps/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..0fc87098f573c60ab4f5b9c699c87855296e9409
--- /dev/null
+++ b/src/php/tests/qps/composer.json
@@ -0,0 +1,11 @@
+{
+  "minimum-stability": "dev",
+  "require": {
+    "grpc/grpc": "dev-master"
+  },
+  "autoload": {
+    "psr-4": {
+      "": "generated_code/"
+    }
+  }
+}
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Control.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Control.php
new file mode 100644
index 0000000000000000000000000000000000000000..efca18a0cb31b1abcc2b994487ceb0edf2816d31
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Control.php
@@ -0,0 +1,127 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class Control
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        \GPBMetadata\Src\Proto\Grpc\Testing\Payloads::initOnce();
+        \GPBMetadata\Src\Proto\Grpc\Testing\Stats::initOnce();
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0add170a247372632f70726f746f2f677270632f74657374696e672f636f" .
+            "6e74726f6c2e70726f746f120c677270632e74657374696e671a25737263" .
+            "2f70726f746f2f677270632f74657374696e672f7061796c6f6164732e70" .
+            "726f746f1a227372632f70726f746f2f677270632f74657374696e672f73" .
+            "746174732e70726f746f22250a0d506f6973736f6e506172616d7312140a" .
+            "0c6f6666657265645f6c6f616418012001280122120a10436c6f7365644c" .
+            "6f6f70506172616d73227b0a0a4c6f6164506172616d7312350a0b636c6f" .
+            "7365645f6c6f6f7018012001280b321e2e677270632e74657374696e672e" .
+            "436c6f7365644c6f6f70506172616d734800122e0a07706f6973736f6e18" .
+            "022001280b321b2e677270632e74657374696e672e506f6973736f6e5061" .
+            "72616d73480042060a046c6f616422430a0e536563757269747950617261" .
+            "6d7312130a0b7573655f746573745f6361180120012808121c0a14736572" .
+            "7665725f686f73745f6f76657272696465180220012809224d0a0a436861" .
+            "6e6e656c417267120c0a046e616d6518012001280912130a097374725f76" .
+            "616c7565180220012809480012130a09696e745f76616c75651803200128" .
+            "05480042070a0576616c756522a0040a0c436c69656e74436f6e66696712" .
+            "160a0e7365727665725f74617267657473180120032809122d0a0b636c69" .
+            "656e745f7479706518022001280e32182e677270632e74657374696e672e" .
+            "436c69656e745479706512350a0f73656375726974795f706172616d7318" .
+            "032001280b321c2e677270632e74657374696e672e536563757269747950" .
+            "6172616d7312240a1c6f75747374616e64696e675f727063735f7065725f" .
+            "6368616e6e656c18042001280512170a0f636c69656e745f6368616e6e65" .
+            "6c73180520012805121c0a146173796e635f636c69656e745f7468726561" .
+            "647318072001280512270a087270635f7479706518082001280e32152e67" .
+            "7270632e74657374696e672e52706354797065122d0a0b6c6f61645f7061" .
+            "72616d73180a2001280b32182e677270632e74657374696e672e4c6f6164" .
+            "506172616d7312330a0e7061796c6f61645f636f6e666967180b2001280b" .
+            "321b2e677270632e74657374696e672e5061796c6f6164436f6e66696712" .
+            "370a10686973746f6772616d5f706172616d73180c2001280b321d2e6772" .
+            "70632e74657374696e672e486973746f6772616d506172616d7312110a09" .
+            "636f72655f6c697374180d2003280512120a0a636f72655f6c696d697418" .
+            "0e2001280512180a106f746865725f636c69656e745f617069180f200128" .
+            "09122e0a0c6368616e6e656c5f6172677318102003280b32182e67727063" .
+            "2e74657374696e672e4368616e6e656c41726722380a0c436c69656e7453" .
+            "746174757312280a05737461747318012001280b32192e677270632e7465" .
+            "7374696e672e436c69656e74537461747322150a044d61726b120d0a0572" .
+            "6573657418012001280822680a0a436c69656e7441726773122b0a057365" .
+            "74757018012001280b321a2e677270632e74657374696e672e436c69656e" .
+            "74436f6e666967480012220a046d61726b18022001280b32122e67727063" .
+            "2e74657374696e672e4d61726b480042090a076172677479706522b4020a" .
+            "0c536572766572436f6e666967122d0a0b7365727665725f747970651801" .
+            "2001280e32182e677270632e74657374696e672e53657276657254797065" .
+            "12350a0f73656375726974795f706172616d7318022001280b321c2e6772" .
+            "70632e74657374696e672e5365637572697479506172616d73120c0a0470" .
+            "6f7274180420012805121c0a146173796e635f7365727665725f74687265" .
+            "61647318072001280512120a0a636f72655f6c696d697418082001280512" .
+            "330a0e7061796c6f61645f636f6e66696718092001280b321b2e67727063" .
+            "2e74657374696e672e5061796c6f6164436f6e66696712110a09636f7265" .
+            "5f6c697374180a2003280512180a106f746865725f7365727665725f6170" .
+            "69180b20012809121c0a137265736f757263655f71756f74615f73697a65" .
+            "18e9072001280522680a0a53657276657241726773122b0a057365747570" .
+            "18012001280b321a2e677270632e74657374696e672e536572766572436f" .
+            "6e666967480012220a046d61726b18022001280b32122e677270632e7465" .
+            "7374696e672e4d61726b480042090a076172677479706522550a0c536572" .
+            "76657253746174757312280a05737461747318012001280b32192e677270" .
+            "632e74657374696e672e5365727665725374617473120c0a04706f727418" .
+            "0220012805120d0a05636f726573180320012805220d0a0b436f72655265" .
+            "7175657374221d0a0c436f7265526573706f6e7365120d0a05636f726573" .
+            "18012001280522060a04566f696422fd010a085363656e6172696f120c0a" .
+            "046e616d6518012001280912310a0d636c69656e745f636f6e6669671802" .
+            "2001280b321a2e677270632e74657374696e672e436c69656e74436f6e66" .
+            "696712130a0b6e756d5f636c69656e747318032001280512310a0d736572" .
+            "7665725f636f6e66696718042001280b321a2e677270632e74657374696e" .
+            "672e536572766572436f6e66696712130a0b6e756d5f7365727665727318" .
+            "052001280512160a0e7761726d75705f7365636f6e647318062001280512" .
+            "190a1162656e63686d61726b5f7365636f6e647318072001280512200a18" .
+            "737061776e5f6c6f63616c5f776f726b65725f636f756e74180820012805" .
+            "22360a095363656e6172696f7312290a097363656e6172696f7318012003" .
+            "280b32162e677270632e74657374696e672e5363656e6172696f22f8020a" .
+            "155363656e6172696f526573756c7453756d6d617279120b0a0371707318" .
+            "0120012801121b0a137170735f7065725f7365727665725f636f72651802" .
+            "20012801121a0a127365727665725f73797374656d5f74696d6518032001" .
+            "280112180a107365727665725f757365725f74696d65180420012801121a" .
+            "0a12636c69656e745f73797374656d5f74696d6518052001280112180a10" .
+            "636c69656e745f757365725f74696d6518062001280112120a0a6c617465" .
+            "6e63795f353018072001280112120a0a6c6174656e63795f393018082001" .
+            "280112120a0a6c6174656e63795f393518092001280112120a0a6c617465" .
+            "6e63795f3939180a2001280112130a0b6c6174656e63795f393939180b20" .
+            "01280112180a107365727665725f6370755f7573616765180c2001280112" .
+            "260a1e7375636365737366756c5f72657175657374735f7065725f736563" .
+            "6f6e64180d2001280112220a1a6661696c65645f72657175657374735f70" .
+            "65725f7365636f6e64180e200128012283030a0e5363656e6172696f5265" .
+            "73756c7412280a087363656e6172696f18012001280b32162e677270632e" .
+            "74657374696e672e5363656e6172696f122e0a096c6174656e6369657318" .
+            "022001280b321b2e677270632e74657374696e672e486973746f6772616d" .
+            "44617461122f0a0c636c69656e745f737461747318032003280b32192e67" .
+            "7270632e74657374696e672e436c69656e745374617473122f0a0c736572" .
+            "7665725f737461747318042003280b32192e677270632e74657374696e67" .
+            "2e536572766572537461747312140a0c7365727665725f636f7265731805" .
+            "2003280512340a0773756d6d61727918062001280b32232e677270632e74" .
+            "657374696e672e5363656e6172696f526573756c7453756d6d6172791216" .
+            "0a0e636c69656e745f7375636365737318072003280812160a0e73657276" .
+            "65725f7375636365737318082003280812390a0f726571756573745f7265" .
+            "73756c747318092003280b32202e677270632e74657374696e672e526571" .
+            "75657374526573756c74436f756e742a410a0a436c69656e745479706512" .
+            "0f0a0b53594e435f434c49454e54100012100a0c4153594e435f434c4945" .
+            "4e54100112100a0c4f544845525f434c49454e5410022a5b0a0a53657276" .
+            "657254797065120f0a0b53594e435f534552564552100012100a0c415359" .
+            "4e435f534552564552100112180a144153594e435f47454e455249435f53" .
+            "4552564552100212100a0c4f544845525f53455256455210032a230a0752" .
+            "70635479706512090a05554e4152591000120d0a0953545245414d494e47" .
+            "1001620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Messages.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Messages.php
new file mode 100644
index 0000000000000000000000000000000000000000..c0880026264968798638e8e9f3ff6660e23d0959
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Messages.php
@@ -0,0 +1,69 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class Messages
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0ad50a0a257372632f70726f746f2f677270632f74657374696e672f6d65" .
+            "7373616765732e70726f746f120c677270632e74657374696e67221a0a09" .
+            "426f6f6c56616c7565120d0a0576616c756518012001280822400a075061" .
+            "796c6f616412270a047479706518012001280e32192e677270632e746573" .
+            "74696e672e5061796c6f616454797065120c0a04626f647918022001280c" .
+            "222b0a0a4563686f537461747573120c0a04636f6465180120012805120f" .
+            "0a076d65737361676518022001280922ce020a0d53696d706c6552657175" .
+            "65737412300a0d726573706f6e73655f7479706518012001280e32192e67" .
+            "7270632e74657374696e672e5061796c6f61645479706512150a0d726573" .
+            "706f6e73655f73697a6518022001280512260a077061796c6f6164180320" .
+            "01280b32152e677270632e74657374696e672e5061796c6f616412150a0d" .
+            "66696c6c5f757365726e616d6518042001280812180a1066696c6c5f6f61" .
+            "7574685f73636f706518052001280812340a13726573706f6e73655f636f" .
+            "6d7072657373656418062001280b32172e677270632e74657374696e672e" .
+            "426f6f6c56616c756512310a0f726573706f6e73655f7374617475731807" .
+            "2001280b32182e677270632e74657374696e672e4563686f537461747573" .
+            "12320a116578706563745f636f6d7072657373656418082001280b32172e" .
+            "677270632e74657374696e672e426f6f6c56616c7565225f0a0e53696d70" .
+            "6c65526573706f6e736512260a077061796c6f616418012001280b32152e" .
+            "677270632e74657374696e672e5061796c6f616412100a08757365726e61" .
+            "6d6518022001280912130a0b6f617574685f73636f706518032001280922" .
+            "770a1953747265616d696e67496e70757443616c6c526571756573741226" .
+            "0a077061796c6f616418012001280b32152e677270632e74657374696e67" .
+            "2e5061796c6f616412320a116578706563745f636f6d7072657373656418" .
+            "022001280b32172e677270632e74657374696e672e426f6f6c56616c7565" .
+            "223d0a1a53747265616d696e67496e70757443616c6c526573706f6e7365" .
+            "121f0a17616767726567617465645f7061796c6f61645f73697a65180120" .
+            "01280522640a12526573706f6e7365506172616d6574657273120c0a0473" .
+            "697a6518012001280512130a0b696e74657276616c5f7573180220012805" .
+            "122b0a0a636f6d7072657373656418032001280b32172e677270632e7465" .
+            "7374696e672e426f6f6c56616c756522e8010a1a53747265616d696e674f" .
+            "757470757443616c6c5265717565737412300a0d726573706f6e73655f74" .
+            "79706518012001280e32192e677270632e74657374696e672e5061796c6f" .
+            "616454797065123d0a13726573706f6e73655f706172616d657465727318" .
+            "022003280b32202e677270632e74657374696e672e526573706f6e736550" .
+            "6172616d657465727312260a077061796c6f616418032001280b32152e67" .
+            "7270632e74657374696e672e5061796c6f616412310a0f726573706f6e73" .
+            "655f73746174757318072001280b32182e677270632e74657374696e672e" .
+            "4563686f53746174757322450a1b53747265616d696e674f757470757443" .
+            "616c6c526573706f6e736512260a077061796c6f616418012001280b3215" .
+            "2e677270632e74657374696e672e5061796c6f616422330a0f5265636f6e" .
+            "6e656374506172616d7312200a186d61785f7265636f6e6e6563745f6261" .
+            "636b6f66665f6d7318012001280522330a0d5265636f6e6e656374496e66" .
+            "6f120e0a0670617373656418012001280812120a0a6261636b6f66665f6d" .
+            "731802200328052a1f0a0b5061796c6f61645479706512100a0c434f4d50" .
+            "5245535341424c451000620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Payloads.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Payloads.php
new file mode 100644
index 0000000000000000000000000000000000000000..279fe00ac820ebd8af13dd324cb903222b77fc81
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Payloads.php
@@ -0,0 +1,37 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/payloads.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class Payloads
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0a93030a257372632f70726f746f2f677270632f74657374696e672f7061" .
+            "796c6f6164732e70726f746f120c677270632e74657374696e6722370a10" .
+            "42797465427566666572506172616d7312100a087265715f73697a651801" .
+            "2001280512110a09726573705f73697a6518022001280522380a1153696d" .
+            "706c6550726f746f506172616d7312100a087265715f73697a6518012001" .
+            "280512110a09726573705f73697a6518022001280522140a12436f6d706c" .
+            "657850726f746f506172616d7322ca010a0d5061796c6f6164436f6e6669" .
+            "6712380a0e627974656275665f706172616d7318012001280b321e2e6772" .
+            "70632e74657374696e672e42797465427566666572506172616d73480012" .
+            "380a0d73696d706c655f706172616d7318022001280b321f2e677270632e" .
+            "74657374696e672e53696d706c6550726f746f506172616d734800123a0a" .
+            "0e636f6d706c65785f706172616d7318032001280b32202e677270632e74" .
+            "657374696e672e436f6d706c657850726f746f506172616d73480042090a" .
+            "077061796c6f6164620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/ProxyService.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/ProxyService.php
new file mode 100644
index 0000000000000000000000000000000000000000..e35944e1d821dd4a3a91a31e2ca7f00a3addfbd6
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/ProxyService.php
@@ -0,0 +1,34 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/proxy-service.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class ProxyService
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0a97020a2a7372632f70726f746f2f677270632f74657374696e672f7072" .
+            "6f78792d736572766963652e70726f746f120c677270632e74657374696e" .
+            "671a247372632f70726f746f2f677270632f74657374696e672f636f6e74" .
+            "726f6c2e70726f746f221c0a0950726f787953746174120f0a076c617465" .
+            "6e6379180120012801328e010a1250726f7879436c69656e745365727669" .
+            "6365123b0a09476574436f6e66696712122e677270632e74657374696e67" .
+            "2e566f69641a1a2e677270632e74657374696e672e436c69656e74436f6e" .
+            "666967123b0a0a5265706f727454696d6512172e677270632e7465737469" .
+            "6e672e50726f7879537461741a122e677270632e74657374696e672e566f" .
+            "69642801620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Services.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Services.php
new file mode 100644
index 0000000000000000000000000000000000000000..7a9439a5b934e045707a24c1f886c3110725325a
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Services.php
@@ -0,0 +1,45 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/services.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class Services
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0ad1040a257372632f70726f746f2f677270632f74657374696e672f7365" .
+            "7276696365732e70726f746f120c677270632e74657374696e671a257372" .
+            "632f70726f746f2f677270632f74657374696e672f6d657373616765732e" .
+            "70726f746f1a247372632f70726f746f2f677270632f74657374696e672f" .
+            "636f6e74726f6c2e70726f746f32aa010a1042656e63686d61726b536572" .
+            "7669636512460a09556e61727943616c6c121b2e677270632e7465737469" .
+            "6e672e53696d706c65526571756573741a1c2e677270632e74657374696e" .
+            "672e53696d706c65526573706f6e7365124e0a0d53747265616d696e6743" .
+            "616c6c121b2e677270632e74657374696e672e53696d706c655265717565" .
+            "73741a1c2e677270632e74657374696e672e53696d706c65526573706f6e" .
+            "7365280130013297020a0d576f726b65725365727669636512450a095275" .
+            "6e53657276657212182e677270632e74657374696e672e53657276657241" .
+            "7267731a1a2e677270632e74657374696e672e5365727665725374617475" .
+            "732801300112450a0952756e436c69656e7412182e677270632e74657374" .
+            "696e672e436c69656e74417267731a1a2e677270632e74657374696e672e" .
+            "436c69656e745374617475732801300112420a09436f7265436f756e7412" .
+            "192e677270632e74657374696e672e436f7265526571756573741a1a2e67" .
+            "7270632e74657374696e672e436f7265526573706f6e736512340a0a5175" .
+            "6974576f726b657212122e677270632e74657374696e672e566f69641a12" .
+            "2e677270632e74657374696e672e566f6964620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Stats.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Stats.php
new file mode 100644
index 0000000000000000000000000000000000000000..99c0000a52c163d8c4e43a1002a0740bab2b6329
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Stats.php
@@ -0,0 +1,44 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/stats.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class Stats
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0adf040a227372632f70726f746f2f677270632f74657374696e672f7374" .
+            "6174732e70726f746f120c677270632e74657374696e67227a0a0b536572" .
+            "766572537461747312140a0c74696d655f656c6170736564180120012801" .
+            "12110a0974696d655f7573657218022001280112130a0b74696d655f7379" .
+            "7374656d18032001280112160a0e746f74616c5f6370755f74696d651804" .
+            "2001280412150a0d69646c655f6370755f74696d65180520012804223b0a" .
+            "0f486973746f6772616d506172616d7312120a0a7265736f6c7574696f6e" .
+            "18012001280112140a0c6d61785f706f737369626c651802200128012277" .
+            "0a0d486973746f6772616d44617461120e0a066275636b65741801200328" .
+            "0d12100a086d696e5f7365656e18022001280112100a086d61785f736565" .
+            "6e180320012801120b0a0373756d18042001280112160a0e73756d5f6f66" .
+            "5f73717561726573180520012801120d0a05636f756e7418062001280122" .
+            "380a1252657175657374526573756c74436f756e7412130a0b7374617475" .
+            "735f636f6465180120012805120d0a05636f756e7418022001280322b601" .
+            "0a0b436c69656e745374617473122e0a096c6174656e6369657318012001" .
+            "280b321b2e677270632e74657374696e672e486973746f6772616d446174" .
+            "6112140a0c74696d655f656c617073656418022001280112110a0974696d" .
+            "655f7573657218032001280112130a0b74696d655f73797374656d180420" .
+            "01280112390a0f726571756573745f726573756c747318052003280b3220" .
+            "2e677270632e74657374696e672e52657175657374526573756c74436f75" .
+            "6e74620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/BenchmarkServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/BenchmarkServiceClient.php
new file mode 100644
index 0000000000000000000000000000000000000000..daf17800cdcc4277692cbe94fcde4092076ef3af
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/BenchmarkServiceClient.php
@@ -0,0 +1,78 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// 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.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+namespace Grpc\Testing {
+
+  class BenchmarkServiceClient extends \Grpc\BaseStub {
+
+    /**
+     * @param string $hostname hostname
+     * @param array $opts channel options
+     * @param Grpc\Channel $channel (optional) re-use channel object
+     */
+    public function __construct($hostname, $opts, $channel = null) {
+      parent::__construct($hostname, $opts, $channel);
+    }
+
+    /**
+     * One request followed by one response.
+     * The server returns the client payload as-is.
+     * @param \Grpc\Testing\SimpleRequest $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function UnaryCall(\Grpc\Testing\SimpleRequest $argument,
+      $metadata = [], $options = []) {
+      return $this->_simpleRequest('/grpc.testing.BenchmarkService/UnaryCall',
+      $argument,
+      ['\Grpc\Testing\SimpleResponse', 'decode'],
+      $metadata, $options);
+    }
+
+    /**
+     * One request followed by one response.
+     * The server returns the client payload as-is.
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function StreamingCall($metadata = [], $options = []) {
+      return $this->_bidiRequest('/grpc.testing.BenchmarkService/StreamingCall',
+      ['\Grpc\Testing\SimpleResponse','decode'],
+      $metadata, $options);
+    }
+
+  }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/BoolValue.php b/src/php/tests/qps/generated_code/Grpc/Testing/BoolValue.php
new file mode 100644
index 0000000000000000000000000000000000000000..f0497accfb26ff43e2859af9e3e851f34f4b6dd6
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/BoolValue.php
@@ -0,0 +1,62 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * TODO(dgq): Go back to using well-known types once
+ * https://github.com/grpc/grpc/issues/6980 has been fixed.
+ * import "google/protobuf/wrappers.proto";
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.BoolValue</code>
+ */
+class BoolValue extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * The bool value.
+     * </pre>
+     *
+     * <code>bool value = 1;</code>
+     */
+    private $value = false;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * The bool value.
+     * </pre>
+     *
+     * <code>bool value = 1;</code>
+     */
+    public function getValue()
+    {
+        return $this->value;
+    }
+
+    /**
+     * <pre>
+     * The bool value.
+     * </pre>
+     *
+     * <code>bool value = 1;</code>
+     */
+    public function setValue($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->value = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ByteBufferParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/ByteBufferParams.php
new file mode 100644
index 0000000000000000000000000000000000000000..0057d387488440468e7a5ccd32bb23b51c3ac015
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ByteBufferParams.php
@@ -0,0 +1,65 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/payloads.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.ByteBufferParams</code>
+ */
+class ByteBufferParams extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>int32 req_size = 1;</code>
+     */
+    private $req_size = 0;
+    /**
+     * <code>int32 resp_size = 2;</code>
+     */
+    private $resp_size = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Payloads::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>int32 req_size = 1;</code>
+     */
+    public function getReqSize()
+    {
+        return $this->req_size;
+    }
+
+    /**
+     * <code>int32 req_size = 1;</code>
+     */
+    public function setReqSize($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->req_size = $var;
+    }
+
+    /**
+     * <code>int32 resp_size = 2;</code>
+     */
+    public function getRespSize()
+    {
+        return $this->resp_size;
+    }
+
+    /**
+     * <code>int32 resp_size = 2;</code>
+     */
+    public function setRespSize($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->resp_size = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ChannelArg.php b/src/php/tests/qps/generated_code/Grpc/Testing/ChannelArg.php
new file mode 100644
index 0000000000000000000000000000000000000000..d2fe3ae5ffc1083b52606734fed67ea95d917681
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ChannelArg.php
@@ -0,0 +1,84 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.ChannelArg</code>
+ */
+class ChannelArg extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>string name = 1;</code>
+     */
+    private $name = '';
+    protected $value;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>string name = 1;</code>
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * <code>string name = 1;</code>
+     */
+    public function setName($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->name = $var;
+    }
+
+    /**
+     * <code>string str_value = 2;</code>
+     */
+    public function getStrValue()
+    {
+        return $this->readOneof(2);
+    }
+
+    /**
+     * <code>string str_value = 2;</code>
+     */
+    public function setStrValue($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->writeOneof(2, $var);
+    }
+
+    /**
+     * <code>int32 int_value = 3;</code>
+     */
+    public function getIntValue()
+    {
+        return $this->readOneof(3);
+    }
+
+    /**
+     * <code>int32 int_value = 3;</code>
+     */
+    public function setIntValue($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->writeOneof(3, $var);
+    }
+
+    public function getValue()
+    {
+        return $this->whichOneof("value");
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ClientArgs.php b/src/php/tests/qps/generated_code/Grpc/Testing/ClientArgs.php
new file mode 100644
index 0000000000000000000000000000000000000000..c878c5a7bc0bdc0d31ae6d8b5b6cfc05d3097d04
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ClientArgs.php
@@ -0,0 +1,63 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.ClientArgs</code>
+ */
+class ClientArgs extends \Google\Protobuf\Internal\Message
+{
+    protected $argtype;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>.grpc.testing.ClientConfig setup = 1;</code>
+     */
+    public function getSetup()
+    {
+        return $this->readOneof(1);
+    }
+
+    /**
+     * <code>.grpc.testing.ClientConfig setup = 1;</code>
+     */
+    public function setSetup(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ClientConfig::class);
+        $this->writeOneof(1, $var);
+    }
+
+    /**
+     * <code>.grpc.testing.Mark mark = 2;</code>
+     */
+    public function getMark()
+    {
+        return $this->readOneof(2);
+    }
+
+    /**
+     * <code>.grpc.testing.Mark mark = 2;</code>
+     */
+    public function setMark(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\Mark::class);
+        $this->writeOneof(2, $var);
+    }
+
+    public function getArgtype()
+    {
+        return $this->whichOneof("argtype");
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ClientConfig.php b/src/php/tests/qps/generated_code/Grpc/Testing/ClientConfig.php
new file mode 100644
index 0000000000000000000000000000000000000000..52d6a75fb0ecfe9ee8845b0960ed7bc1d17da20e
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ClientConfig.php
@@ -0,0 +1,407 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.ClientConfig</code>
+ */
+class ClientConfig extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * List of targets to connect to. At least one target needs to be specified.
+     * </pre>
+     *
+     * <code>repeated string server_targets = 1;</code>
+     */
+    private $server_targets;
+    /**
+     * <code>.grpc.testing.ClientType client_type = 2;</code>
+     */
+    private $client_type = 0;
+    /**
+     * <code>.grpc.testing.SecurityParams security_params = 3;</code>
+     */
+    private $security_params = null;
+    /**
+     * <pre>
+     * How many concurrent RPCs to start for each channel.
+     * For synchronous client, use a separate thread for each outstanding RPC.
+     * </pre>
+     *
+     * <code>int32 outstanding_rpcs_per_channel = 4;</code>
+     */
+    private $outstanding_rpcs_per_channel = 0;
+    /**
+     * <pre>
+     * Number of independent client channels to create.
+     * i-th channel will connect to server_target[i % server_targets.size()]
+     * </pre>
+     *
+     * <code>int32 client_channels = 5;</code>
+     */
+    private $client_channels = 0;
+    /**
+     * <pre>
+     * Only for async client. Number of threads to use to start/manage RPCs.
+     * </pre>
+     *
+     * <code>int32 async_client_threads = 7;</code>
+     */
+    private $async_client_threads = 0;
+    /**
+     * <code>.grpc.testing.RpcType rpc_type = 8;</code>
+     */
+    private $rpc_type = 0;
+    /**
+     * <pre>
+     * The requested load for the entire client (aggregated over all the threads).
+     * </pre>
+     *
+     * <code>.grpc.testing.LoadParams load_params = 10;</code>
+     */
+    private $load_params = null;
+    /**
+     * <code>.grpc.testing.PayloadConfig payload_config = 11;</code>
+     */
+    private $payload_config = null;
+    /**
+     * <code>.grpc.testing.HistogramParams histogram_params = 12;</code>
+     */
+    private $histogram_params = null;
+    /**
+     * <pre>
+     * Specify the cores we should run the client on, if desired
+     * </pre>
+     *
+     * <code>repeated int32 core_list = 13;</code>
+     */
+    private $core_list;
+    /**
+     * <code>int32 core_limit = 14;</code>
+     */
+    private $core_limit = 0;
+    /**
+     * <pre>
+     * If we use an OTHER_CLIENT client_type, this string gives more detail
+     * </pre>
+     *
+     * <code>string other_client_api = 15;</code>
+     */
+    private $other_client_api = '';
+    /**
+     * <code>repeated .grpc.testing.ChannelArg channel_args = 16;</code>
+     */
+    private $channel_args;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * List of targets to connect to. At least one target needs to be specified.
+     * </pre>
+     *
+     * <code>repeated string server_targets = 1;</code>
+     */
+    public function getServerTargets()
+    {
+        return $this->server_targets;
+    }
+
+    /**
+     * <pre>
+     * List of targets to connect to. At least one target needs to be specified.
+     * </pre>
+     *
+     * <code>repeated string server_targets = 1;</code>
+     */
+    public function setServerTargets(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING);
+        $this->server_targets = $var;
+    }
+
+    /**
+     * <code>.grpc.testing.ClientType client_type = 2;</code>
+     */
+    public function getClientType()
+    {
+        return $this->client_type;
+    }
+
+    /**
+     * <code>.grpc.testing.ClientType client_type = 2;</code>
+     */
+    public function setClientType($var)
+    {
+        GPBUtil::checkEnum($var, \Grpc\Testing\ClientType::class);
+        $this->client_type = $var;
+    }
+
+    /**
+     * <code>.grpc.testing.SecurityParams security_params = 3;</code>
+     */
+    public function getSecurityParams()
+    {
+        return $this->security_params;
+    }
+
+    /**
+     * <code>.grpc.testing.SecurityParams security_params = 3;</code>
+     */
+    public function setSecurityParams(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\SecurityParams::class);
+        $this->security_params = $var;
+    }
+
+    /**
+     * <pre>
+     * How many concurrent RPCs to start for each channel.
+     * For synchronous client, use a separate thread for each outstanding RPC.
+     * </pre>
+     *
+     * <code>int32 outstanding_rpcs_per_channel = 4;</code>
+     */
+    public function getOutstandingRpcsPerChannel()
+    {
+        return $this->outstanding_rpcs_per_channel;
+    }
+
+    /**
+     * <pre>
+     * How many concurrent RPCs to start for each channel.
+     * For synchronous client, use a separate thread for each outstanding RPC.
+     * </pre>
+     *
+     * <code>int32 outstanding_rpcs_per_channel = 4;</code>
+     */
+    public function setOutstandingRpcsPerChannel($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->outstanding_rpcs_per_channel = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of independent client channels to create.
+     * i-th channel will connect to server_target[i % server_targets.size()]
+     * </pre>
+     *
+     * <code>int32 client_channels = 5;</code>
+     */
+    public function getClientChannels()
+    {
+        return $this->client_channels;
+    }
+
+    /**
+     * <pre>
+     * Number of independent client channels to create.
+     * i-th channel will connect to server_target[i % server_targets.size()]
+     * </pre>
+     *
+     * <code>int32 client_channels = 5;</code>
+     */
+    public function setClientChannels($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->client_channels = $var;
+    }
+
+    /**
+     * <pre>
+     * Only for async client. Number of threads to use to start/manage RPCs.
+     * </pre>
+     *
+     * <code>int32 async_client_threads = 7;</code>
+     */
+    public function getAsyncClientThreads()
+    {
+        return $this->async_client_threads;
+    }
+
+    /**
+     * <pre>
+     * Only for async client. Number of threads to use to start/manage RPCs.
+     * </pre>
+     *
+     * <code>int32 async_client_threads = 7;</code>
+     */
+    public function setAsyncClientThreads($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->async_client_threads = $var;
+    }
+
+    /**
+     * <code>.grpc.testing.RpcType rpc_type = 8;</code>
+     */
+    public function getRpcType()
+    {
+        return $this->rpc_type;
+    }
+
+    /**
+     * <code>.grpc.testing.RpcType rpc_type = 8;</code>
+     */
+    public function setRpcType($var)
+    {
+        GPBUtil::checkEnum($var, \Grpc\Testing\RpcType::class);
+        $this->rpc_type = $var;
+    }
+
+    /**
+     * <pre>
+     * The requested load for the entire client (aggregated over all the threads).
+     * </pre>
+     *
+     * <code>.grpc.testing.LoadParams load_params = 10;</code>
+     */
+    public function getLoadParams()
+    {
+        return $this->load_params;
+    }
+
+    /**
+     * <pre>
+     * The requested load for the entire client (aggregated over all the threads).
+     * </pre>
+     *
+     * <code>.grpc.testing.LoadParams load_params = 10;</code>
+     */
+    public function setLoadParams(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\LoadParams::class);
+        $this->load_params = $var;
+    }
+
+    /**
+     * <code>.grpc.testing.PayloadConfig payload_config = 11;</code>
+     */
+    public function getPayloadConfig()
+    {
+        return $this->payload_config;
+    }
+
+    /**
+     * <code>.grpc.testing.PayloadConfig payload_config = 11;</code>
+     */
+    public function setPayloadConfig(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\PayloadConfig::class);
+        $this->payload_config = $var;
+    }
+
+    /**
+     * <code>.grpc.testing.HistogramParams histogram_params = 12;</code>
+     */
+    public function getHistogramParams()
+    {
+        return $this->histogram_params;
+    }
+
+    /**
+     * <code>.grpc.testing.HistogramParams histogram_params = 12;</code>
+     */
+    public function setHistogramParams(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\HistogramParams::class);
+        $this->histogram_params = $var;
+    }
+
+    /**
+     * <pre>
+     * Specify the cores we should run the client on, if desired
+     * </pre>
+     *
+     * <code>repeated int32 core_list = 13;</code>
+     */
+    public function getCoreList()
+    {
+        return $this->core_list;
+    }
+
+    /**
+     * <pre>
+     * Specify the cores we should run the client on, if desired
+     * </pre>
+     *
+     * <code>repeated int32 core_list = 13;</code>
+     */
+    public function setCoreList(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
+        $this->core_list = $var;
+    }
+
+    /**
+     * <code>int32 core_limit = 14;</code>
+     */
+    public function getCoreLimit()
+    {
+        return $this->core_limit;
+    }
+
+    /**
+     * <code>int32 core_limit = 14;</code>
+     */
+    public function setCoreLimit($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->core_limit = $var;
+    }
+
+    /**
+     * <pre>
+     * If we use an OTHER_CLIENT client_type, this string gives more detail
+     * </pre>
+     *
+     * <code>string other_client_api = 15;</code>
+     */
+    public function getOtherClientApi()
+    {
+        return $this->other_client_api;
+    }
+
+    /**
+     * <pre>
+     * If we use an OTHER_CLIENT client_type, this string gives more detail
+     * </pre>
+     *
+     * <code>string other_client_api = 15;</code>
+     */
+    public function setOtherClientApi($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->other_client_api = $var;
+    }
+
+    /**
+     * <code>repeated .grpc.testing.ChannelArg channel_args = 16;</code>
+     */
+    public function getChannelArgs()
+    {
+        return $this->channel_args;
+    }
+
+    /**
+     * <code>repeated .grpc.testing.ChannelArg channel_args = 16;</code>
+     */
+    public function setChannelArgs(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Grpc\Testing\ChannelArg::class);
+        $this->channel_args = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ClientStats.php b/src/php/tests/qps/generated_code/Grpc/Testing/ClientStats.php
new file mode 100644
index 0000000000000000000000000000000000000000..8b9a0c33a463a1dd9488a38e73ac6cf7b36f7f1c
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ClientStats.php
@@ -0,0 +1,164 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/stats.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.ClientStats</code>
+ */
+class ClientStats extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Latency histogram. Data points are in nanoseconds.
+     * </pre>
+     *
+     * <code>.grpc.testing.HistogramData latencies = 1;</code>
+     */
+    private $latencies = null;
+    /**
+     * <pre>
+     * See ServerStats for details.
+     * </pre>
+     *
+     * <code>double time_elapsed = 2;</code>
+     */
+    private $time_elapsed = 0.0;
+    /**
+     * <code>double time_user = 3;</code>
+     */
+    private $time_user = 0.0;
+    /**
+     * <code>double time_system = 4;</code>
+     */
+    private $time_system = 0.0;
+    /**
+     * <pre>
+     * Number of failed requests (one row per status code seen)
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.RequestResultCount request_results = 5;</code>
+     */
+    private $request_results;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Stats::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Latency histogram. Data points are in nanoseconds.
+     * </pre>
+     *
+     * <code>.grpc.testing.HistogramData latencies = 1;</code>
+     */
+    public function getLatencies()
+    {
+        return $this->latencies;
+    }
+
+    /**
+     * <pre>
+     * Latency histogram. Data points are in nanoseconds.
+     * </pre>
+     *
+     * <code>.grpc.testing.HistogramData latencies = 1;</code>
+     */
+    public function setLatencies(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\HistogramData::class);
+        $this->latencies = $var;
+    }
+
+    /**
+     * <pre>
+     * See ServerStats for details.
+     * </pre>
+     *
+     * <code>double time_elapsed = 2;</code>
+     */
+    public function getTimeElapsed()
+    {
+        return $this->time_elapsed;
+    }
+
+    /**
+     * <pre>
+     * See ServerStats for details.
+     * </pre>
+     *
+     * <code>double time_elapsed = 2;</code>
+     */
+    public function setTimeElapsed($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->time_elapsed = $var;
+    }
+
+    /**
+     * <code>double time_user = 3;</code>
+     */
+    public function getTimeUser()
+    {
+        return $this->time_user;
+    }
+
+    /**
+     * <code>double time_user = 3;</code>
+     */
+    public function setTimeUser($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->time_user = $var;
+    }
+
+    /**
+     * <code>double time_system = 4;</code>
+     */
+    public function getTimeSystem()
+    {
+        return $this->time_system;
+    }
+
+    /**
+     * <code>double time_system = 4;</code>
+     */
+    public function setTimeSystem($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->time_system = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of failed requests (one row per status code seen)
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.RequestResultCount request_results = 5;</code>
+     */
+    public function getRequestResults()
+    {
+        return $this->request_results;
+    }
+
+    /**
+     * <pre>
+     * Number of failed requests (one row per status code seen)
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.RequestResultCount request_results = 5;</code>
+     */
+    public function setRequestResults(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Grpc\Testing\RequestResultCount::class);
+        $this->request_results = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ClientStatus.php b/src/php/tests/qps/generated_code/Grpc/Testing/ClientStatus.php
new file mode 100644
index 0000000000000000000000000000000000000000..a59f87a96285dd7113b079c98d4df73460d2ae92
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ClientStatus.php
@@ -0,0 +1,44 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.ClientStatus</code>
+ */
+class ClientStatus extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>.grpc.testing.ClientStats stats = 1;</code>
+     */
+    private $stats = null;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>.grpc.testing.ClientStats stats = 1;</code>
+     */
+    public function getStats()
+    {
+        return $this->stats;
+    }
+
+    /**
+     * <code>.grpc.testing.ClientStats stats = 1;</code>
+     */
+    public function setStats(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ClientStats::class);
+        $this->stats = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ClientType.php b/src/php/tests/qps/generated_code/Grpc/Testing/ClientType.php
new file mode 100644
index 0000000000000000000000000000000000000000..4f59da992f998c9567c94acfb9e8f913d6e07deb
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ClientType.php
@@ -0,0 +1,34 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+/**
+ * Protobuf enum <code>grpc.testing.ClientType</code>
+ */
+class ClientType
+{
+    /**
+     * <pre>
+     * Many languages support a basic distinction between using
+     * sync or async client, and this allows the specification
+     * </pre>
+     *
+     * <code>SYNC_CLIENT = 0;</code>
+     */
+    const SYNC_CLIENT = 0;
+    /**
+     * <code>ASYNC_CLIENT = 1;</code>
+     */
+    const ASYNC_CLIENT = 1;
+    /**
+     * <pre>
+     * used for some language-specific variants
+     * </pre>
+     *
+     * <code>OTHER_CLIENT = 2;</code>
+     */
+    const OTHER_CLIENT = 2;
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ClosedLoopParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/ClosedLoopParams.php
new file mode 100644
index 0000000000000000000000000000000000000000..53f2948af289e80de4d7851dc74a55c562c63c50
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ClosedLoopParams.php
@@ -0,0 +1,28 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Once an RPC finishes, immediately start a new one.
+ * No configuration parameters needed.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.ClosedLoopParams</code>
+ */
+class ClosedLoopParams extends \Google\Protobuf\Internal\Message
+{
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ComplexProtoParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/ComplexProtoParams.php
new file mode 100644
index 0000000000000000000000000000000000000000..6d990f1b064a5abbc2018814f4f3a6987922dd2f
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ComplexProtoParams.php
@@ -0,0 +1,28 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/payloads.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * TODO (vpai): Fill this in once the details of complex, representative
+ *              protos are decided
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.ComplexProtoParams</code>
+ */
+class ComplexProtoParams extends \Google\Protobuf\Internal\Message
+{
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Payloads::initOnce();
+        parent::__construct();
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/CoreRequest.php b/src/php/tests/qps/generated_code/Grpc/Testing/CoreRequest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2e078b3fcdbad02a17b41998c50b81aff7f0f0a2
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/CoreRequest.php
@@ -0,0 +1,23 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.CoreRequest</code>
+ */
+class CoreRequest extends \Google\Protobuf\Internal\Message
+{
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/CoreResponse.php b/src/php/tests/qps/generated_code/Grpc/Testing/CoreResponse.php
new file mode 100644
index 0000000000000000000000000000000000000000..85cb3418ada353426446cdde07326e3adb935c84
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/CoreResponse.php
@@ -0,0 +1,56 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.CoreResponse</code>
+ */
+class CoreResponse extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Number of cores available on the server
+     * </pre>
+     *
+     * <code>int32 cores = 1;</code>
+     */
+    private $cores = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Number of cores available on the server
+     * </pre>
+     *
+     * <code>int32 cores = 1;</code>
+     */
+    public function getCores()
+    {
+        return $this->cores;
+    }
+
+    /**
+     * <pre>
+     * Number of cores available on the server
+     * </pre>
+     *
+     * <code>int32 cores = 1;</code>
+     */
+    public function setCores($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->cores = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/EchoStatus.php b/src/php/tests/qps/generated_code/Grpc/Testing/EchoStatus.php
new file mode 100644
index 0000000000000000000000000000000000000000..27340fb0efe9294b893a4c8854870bfd1590ae14
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/EchoStatus.php
@@ -0,0 +1,70 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * A protobuf representation for grpc status. This is used by test
+ * clients to specify a status that the server should attempt to return.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.EchoStatus</code>
+ */
+class EchoStatus extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>int32 code = 1;</code>
+     */
+    private $code = 0;
+    /**
+     * <code>string message = 2;</code>
+     */
+    private $message = '';
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>int32 code = 1;</code>
+     */
+    public function getCode()
+    {
+        return $this->code;
+    }
+
+    /**
+     * <code>int32 code = 1;</code>
+     */
+    public function setCode($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->code = $var;
+    }
+
+    /**
+     * <code>string message = 2;</code>
+     */
+    public function getMessage()
+    {
+        return $this->message;
+    }
+
+    /**
+     * <code>string message = 2;</code>
+     */
+    public function setMessage($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->message = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/HistogramData.php b/src/php/tests/qps/generated_code/Grpc/Testing/HistogramData.php
new file mode 100644
index 0000000000000000000000000000000000000000..056da6e5de552b9329f77886867cdb7948a16dac
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/HistogramData.php
@@ -0,0 +1,153 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/stats.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Histogram data based on grpc/support/histogram.c
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.HistogramData</code>
+ */
+class HistogramData extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>repeated uint32 bucket = 1;</code>
+     */
+    private $bucket;
+    /**
+     * <code>double min_seen = 2;</code>
+     */
+    private $min_seen = 0.0;
+    /**
+     * <code>double max_seen = 3;</code>
+     */
+    private $max_seen = 0.0;
+    /**
+     * <code>double sum = 4;</code>
+     */
+    private $sum = 0.0;
+    /**
+     * <code>double sum_of_squares = 5;</code>
+     */
+    private $sum_of_squares = 0.0;
+    /**
+     * <code>double count = 6;</code>
+     */
+    private $count = 0.0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Stats::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>repeated uint32 bucket = 1;</code>
+     */
+    public function getBucket()
+    {
+        return $this->bucket;
+    }
+
+    /**
+     * <code>repeated uint32 bucket = 1;</code>
+     */
+    public function setBucket(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::UINT32);
+        $this->bucket = $var;
+    }
+
+    /**
+     * <code>double min_seen = 2;</code>
+     */
+    public function getMinSeen()
+    {
+        return $this->min_seen;
+    }
+
+    /**
+     * <code>double min_seen = 2;</code>
+     */
+    public function setMinSeen($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->min_seen = $var;
+    }
+
+    /**
+     * <code>double max_seen = 3;</code>
+     */
+    public function getMaxSeen()
+    {
+        return $this->max_seen;
+    }
+
+    /**
+     * <code>double max_seen = 3;</code>
+     */
+    public function setMaxSeen($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->max_seen = $var;
+    }
+
+    /**
+     * <code>double sum = 4;</code>
+     */
+    public function getSum()
+    {
+        return $this->sum;
+    }
+
+    /**
+     * <code>double sum = 4;</code>
+     */
+    public function setSum($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->sum = $var;
+    }
+
+    /**
+     * <code>double sum_of_squares = 5;</code>
+     */
+    public function getSumOfSquares()
+    {
+        return $this->sum_of_squares;
+    }
+
+    /**
+     * <code>double sum_of_squares = 5;</code>
+     */
+    public function setSumOfSquares($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->sum_of_squares = $var;
+    }
+
+    /**
+     * <code>double count = 6;</code>
+     */
+    public function getCount()
+    {
+        return $this->count;
+    }
+
+    /**
+     * <code>double count = 6;</code>
+     */
+    public function setCount($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->count = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/HistogramParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/HistogramParams.php
new file mode 100644
index 0000000000000000000000000000000000000000..836c94b01d836818cec011ef419ea1d809ffb067
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/HistogramParams.php
@@ -0,0 +1,93 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/stats.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Histogram params based on grpc/support/histogram.c
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.HistogramParams</code>
+ */
+class HistogramParams extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * first bucket is [0, 1 + resolution)
+     * </pre>
+     *
+     * <code>double resolution = 1;</code>
+     */
+    private $resolution = 0.0;
+    /**
+     * <pre>
+     * use enough buckets to allow this value
+     * </pre>
+     *
+     * <code>double max_possible = 2;</code>
+     */
+    private $max_possible = 0.0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Stats::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * first bucket is [0, 1 + resolution)
+     * </pre>
+     *
+     * <code>double resolution = 1;</code>
+     */
+    public function getResolution()
+    {
+        return $this->resolution;
+    }
+
+    /**
+     * <pre>
+     * first bucket is [0, 1 + resolution)
+     * </pre>
+     *
+     * <code>double resolution = 1;</code>
+     */
+    public function setResolution($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->resolution = $var;
+    }
+
+    /**
+     * <pre>
+     * use enough buckets to allow this value
+     * </pre>
+     *
+     * <code>double max_possible = 2;</code>
+     */
+    public function getMaxPossible()
+    {
+        return $this->max_possible;
+    }
+
+    /**
+     * <pre>
+     * use enough buckets to allow this value
+     * </pre>
+     *
+     * <code>double max_possible = 2;</code>
+     */
+    public function setMaxPossible($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->max_possible = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/LoadParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/LoadParams.php
new file mode 100644
index 0000000000000000000000000000000000000000..1f32e49c8aad6369e587e9e8708b228d016b857a
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/LoadParams.php
@@ -0,0 +1,63 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.LoadParams</code>
+ */
+class LoadParams extends \Google\Protobuf\Internal\Message
+{
+    protected $load;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>.grpc.testing.ClosedLoopParams closed_loop = 1;</code>
+     */
+    public function getClosedLoop()
+    {
+        return $this->readOneof(1);
+    }
+
+    /**
+     * <code>.grpc.testing.ClosedLoopParams closed_loop = 1;</code>
+     */
+    public function setClosedLoop(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ClosedLoopParams::class);
+        $this->writeOneof(1, $var);
+    }
+
+    /**
+     * <code>.grpc.testing.PoissonParams poisson = 2;</code>
+     */
+    public function getPoisson()
+    {
+        return $this->readOneof(2);
+    }
+
+    /**
+     * <code>.grpc.testing.PoissonParams poisson = 2;</code>
+     */
+    public function setPoisson(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\PoissonParams::class);
+        $this->writeOneof(2, $var);
+    }
+
+    public function getLoad()
+    {
+        return $this->whichOneof("load");
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/Mark.php b/src/php/tests/qps/generated_code/Grpc/Testing/Mark.php
new file mode 100644
index 0000000000000000000000000000000000000000..ce006efacd8874873f12f89d8217af659c61001c
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/Mark.php
@@ -0,0 +1,60 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Request current stats
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.Mark</code>
+ */
+class Mark extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * if true, the stats will be reset after taking their snapshot.
+     * </pre>
+     *
+     * <code>bool reset = 1;</code>
+     */
+    private $reset = false;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * if true, the stats will be reset after taking their snapshot.
+     * </pre>
+     *
+     * <code>bool reset = 1;</code>
+     */
+    public function getReset()
+    {
+        return $this->reset;
+    }
+
+    /**
+     * <pre>
+     * if true, the stats will be reset after taking their snapshot.
+     * </pre>
+     *
+     * <code>bool reset = 1;</code>
+     */
+    public function setReset($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->reset = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/Payload.php b/src/php/tests/qps/generated_code/Grpc/Testing/Payload.php
new file mode 100644
index 0000000000000000000000000000000000000000..d17c271af7464ee7798f23cdefb61256a3df9637
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/Payload.php
@@ -0,0 +1,96 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * A block of data, to simply increase gRPC message size.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.Payload</code>
+ */
+class Payload extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * The type of data in body.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType type = 1;</code>
+     */
+    private $type = 0;
+    /**
+     * <pre>
+     * Primary contents of payload.
+     * </pre>
+     *
+     * <code>bytes body = 2;</code>
+     */
+    private $body = '';
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * The type of data in body.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType type = 1;</code>
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * The type of data in body.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType type = 1;</code>
+     */
+    public function setType($var)
+    {
+        GPBUtil::checkEnum($var, \Grpc\Testing\PayloadType::class);
+        $this->type = $var;
+    }
+
+    /**
+     * <pre>
+     * Primary contents of payload.
+     * </pre>
+     *
+     * <code>bytes body = 2;</code>
+     */
+    public function getBody()
+    {
+        return $this->body;
+    }
+
+    /**
+     * <pre>
+     * Primary contents of payload.
+     * </pre>
+     *
+     * <code>bytes body = 2;</code>
+     */
+    public function setBody($var)
+    {
+        GPBUtil::checkString($var, False);
+        $this->body = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/PayloadConfig.php b/src/php/tests/qps/generated_code/Grpc/Testing/PayloadConfig.php
new file mode 100644
index 0000000000000000000000000000000000000000..a2fe7109ba7fc2dd2b08c391ace51e17dba008dd
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/PayloadConfig.php
@@ -0,0 +1,80 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/payloads.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.PayloadConfig</code>
+ */
+class PayloadConfig extends \Google\Protobuf\Internal\Message
+{
+    protected $payload;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Payloads::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>.grpc.testing.ByteBufferParams bytebuf_params = 1;</code>
+     */
+    public function getBytebufParams()
+    {
+        return $this->readOneof(1);
+    }
+
+    /**
+     * <code>.grpc.testing.ByteBufferParams bytebuf_params = 1;</code>
+     */
+    public function setBytebufParams(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ByteBufferParams::class);
+        $this->writeOneof(1, $var);
+    }
+
+    /**
+     * <code>.grpc.testing.SimpleProtoParams simple_params = 2;</code>
+     */
+    public function getSimpleParams()
+    {
+        return $this->readOneof(2);
+    }
+
+    /**
+     * <code>.grpc.testing.SimpleProtoParams simple_params = 2;</code>
+     */
+    public function setSimpleParams(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\SimpleProtoParams::class);
+        $this->writeOneof(2, $var);
+    }
+
+    /**
+     * <code>.grpc.testing.ComplexProtoParams complex_params = 3;</code>
+     */
+    public function getComplexParams()
+    {
+        return $this->readOneof(3);
+    }
+
+    /**
+     * <code>.grpc.testing.ComplexProtoParams complex_params = 3;</code>
+     */
+    public function setComplexParams(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ComplexProtoParams::class);
+        $this->writeOneof(3, $var);
+    }
+
+    public function getPayload()
+    {
+        return $this->whichOneof("payload");
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/PayloadType.php b/src/php/tests/qps/generated_code/Grpc/Testing/PayloadType.php
new file mode 100644
index 0000000000000000000000000000000000000000..189ef034b4724cc7133c20435bd9d1cc93664bf2
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/PayloadType.php
@@ -0,0 +1,26 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+/**
+ * <pre>
+ * DEPRECATED, don't use. To be removed shortly.
+ * The type of payload that should be returned.
+ * </pre>
+ *
+ * Protobuf enum <code>grpc.testing.PayloadType</code>
+ */
+class PayloadType
+{
+    /**
+     * <pre>
+     * Compressable text format.
+     * </pre>
+     *
+     * <code>COMPRESSABLE = 0;</code>
+     */
+    const COMPRESSABLE = 0;
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/PoissonParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/PoissonParams.php
new file mode 100644
index 0000000000000000000000000000000000000000..d64edd45f03baf24a364040489c676c32525b9e1
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/PoissonParams.php
@@ -0,0 +1,61 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Parameters of poisson process distribution, which is a good representation
+ * of activity coming in from independent identical stationary sources.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.PoissonParams</code>
+ */
+class PoissonParams extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * The rate of arrivals (a.k.a. lambda parameter of the exp distribution).
+     * </pre>
+     *
+     * <code>double offered_load = 1;</code>
+     */
+    private $offered_load = 0.0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * The rate of arrivals (a.k.a. lambda parameter of the exp distribution).
+     * </pre>
+     *
+     * <code>double offered_load = 1;</code>
+     */
+    public function getOfferedLoad()
+    {
+        return $this->offered_load;
+    }
+
+    /**
+     * <pre>
+     * The rate of arrivals (a.k.a. lambda parameter of the exp distribution).
+     * </pre>
+     *
+     * <code>double offered_load = 1;</code>
+     */
+    public function setOfferedLoad($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->offered_load = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ProxyClientServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/ProxyClientServiceClient.php
new file mode 100644
index 0000000000000000000000000000000000000000..23c041b47090c882b6567d930d732fc574028d7d
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ProxyClientServiceClient.php
@@ -0,0 +1,72 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2017, 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.
+//
+namespace Grpc\Testing {
+
+  class ProxyClientServiceClient extends \Grpc\BaseStub {
+
+    /**
+     * @param string $hostname hostname
+     * @param array $opts channel options
+     * @param Grpc\Channel $channel (optional) re-use channel object
+     */
+    public function __construct($hostname, $opts, $channel = null) {
+      parent::__construct($hostname, $opts, $channel);
+    }
+
+    /**
+     * @param \Grpc\Testing\Void $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function GetConfig(\Grpc\Testing\Void $argument,
+      $metadata = [], $options = []) {
+      return $this->_simpleRequest('/grpc.testing.ProxyClientService/GetConfig',
+      $argument,
+      ['\Grpc\Testing\ClientConfig', 'decode'],
+      $metadata, $options);
+    }
+
+    /**
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function ReportTime($metadata = [], $options = []) {
+      return $this->_clientStreamRequest('/grpc.testing.ProxyClientService/ReportTime',
+      ['\Grpc\Testing\Void','decode'],
+      $metadata, $options);
+    }
+
+  }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ProxyStat.php b/src/php/tests/qps/generated_code/Grpc/Testing/ProxyStat.php
new file mode 100644
index 0000000000000000000000000000000000000000..ed43be99cef8c928cacf974393eb220e04ab4538
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ProxyStat.php
@@ -0,0 +1,44 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/proxy-service.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.ProxyStat</code>
+ */
+class ProxyStat extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>double latency = 1;</code>
+     */
+    private $latency = 0.0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\ProxyService::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>double latency = 1;</code>
+     */
+    public function getLatency()
+    {
+        return $this->latency;
+    }
+
+    /**
+     * <code>double latency = 1;</code>
+     */
+    public function setLatency($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->latency = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectInfo.php b/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectInfo.php
new file mode 100644
index 0000000000000000000000000000000000000000..dfaaa606c3b6b3af2800e1712838514413450f41
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectInfo.php
@@ -0,0 +1,71 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * For reconnect interop test only.
+ * Server tells client whether its reconnects are following the spec and the
+ * reconnect backoffs it saw.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.ReconnectInfo</code>
+ */
+class ReconnectInfo extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>bool passed = 1;</code>
+     */
+    private $passed = false;
+    /**
+     * <code>repeated int32 backoff_ms = 2;</code>
+     */
+    private $backoff_ms;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>bool passed = 1;</code>
+     */
+    public function getPassed()
+    {
+        return $this->passed;
+    }
+
+    /**
+     * <code>bool passed = 1;</code>
+     */
+    public function setPassed($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->passed = $var;
+    }
+
+    /**
+     * <code>repeated int32 backoff_ms = 2;</code>
+     */
+    public function getBackoffMs()
+    {
+        return $this->backoff_ms;
+    }
+
+    /**
+     * <code>repeated int32 backoff_ms = 2;</code>
+     */
+    public function setBackoffMs(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
+        $this->backoff_ms = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectParams.php
new file mode 100644
index 0000000000000000000000000000000000000000..97158557836966e04263c5f04cf5fd9e3b98f530
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectParams.php
@@ -0,0 +1,49 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * For reconnect interop test only.
+ * Client tells server what reconnection parameters it used.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.ReconnectParams</code>
+ */
+class ReconnectParams extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>int32 max_reconnect_backoff_ms = 1;</code>
+     */
+    private $max_reconnect_backoff_ms = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>int32 max_reconnect_backoff_ms = 1;</code>
+     */
+    public function getMaxReconnectBackoffMs()
+    {
+        return $this->max_reconnect_backoff_ms;
+    }
+
+    /**
+     * <code>int32 max_reconnect_backoff_ms = 1;</code>
+     */
+    public function setMaxReconnectBackoffMs($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->max_reconnect_backoff_ms = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/RequestResultCount.php b/src/php/tests/qps/generated_code/Grpc/Testing/RequestResultCount.php
new file mode 100644
index 0000000000000000000000000000000000000000..1be42b2ac91441251063e6acbca63200adb40645
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/RequestResultCount.php
@@ -0,0 +1,65 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/stats.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.RequestResultCount</code>
+ */
+class RequestResultCount extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>int32 status_code = 1;</code>
+     */
+    private $status_code = 0;
+    /**
+     * <code>int64 count = 2;</code>
+     */
+    private $count = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Stats::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>int32 status_code = 1;</code>
+     */
+    public function getStatusCode()
+    {
+        return $this->status_code;
+    }
+
+    /**
+     * <code>int32 status_code = 1;</code>
+     */
+    public function setStatusCode($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->status_code = $var;
+    }
+
+    /**
+     * <code>int64 count = 2;</code>
+     */
+    public function getCount()
+    {
+        return $this->count;
+    }
+
+    /**
+     * <code>int64 count = 2;</code>
+     */
+    public function setCount($var)
+    {
+        GPBUtil::checkInt64($var);
+        $this->count = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ResponseParameters.php b/src/php/tests/qps/generated_code/Grpc/Testing/ResponseParameters.php
new file mode 100644
index 0000000000000000000000000000000000000000..b7a8e5ece719798c376ee3009d02618f0eb94f63
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ResponseParameters.php
@@ -0,0 +1,138 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Configuration for a particular response.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.ResponseParameters</code>
+ */
+class ResponseParameters extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Desired payload sizes in responses from the server.
+     * </pre>
+     *
+     * <code>int32 size = 1;</code>
+     */
+    private $size = 0;
+    /**
+     * <pre>
+     * Desired interval between consecutive responses in the response stream in
+     * microseconds.
+     * </pre>
+     *
+     * <code>int32 interval_us = 2;</code>
+     */
+    private $interval_us = 0;
+    /**
+     * <pre>
+     * Whether to request the server to compress the response. This field is
+     * "nullable" in order to interoperate seamlessly with clients not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the response's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue compressed = 3;</code>
+     */
+    private $compressed = null;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Desired payload sizes in responses from the server.
+     * </pre>
+     *
+     * <code>int32 size = 1;</code>
+     */
+    public function getSize()
+    {
+        return $this->size;
+    }
+
+    /**
+     * <pre>
+     * Desired payload sizes in responses from the server.
+     * </pre>
+     *
+     * <code>int32 size = 1;</code>
+     */
+    public function setSize($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->size = $var;
+    }
+
+    /**
+     * <pre>
+     * Desired interval between consecutive responses in the response stream in
+     * microseconds.
+     * </pre>
+     *
+     * <code>int32 interval_us = 2;</code>
+     */
+    public function getIntervalUs()
+    {
+        return $this->interval_us;
+    }
+
+    /**
+     * <pre>
+     * Desired interval between consecutive responses in the response stream in
+     * microseconds.
+     * </pre>
+     *
+     * <code>int32 interval_us = 2;</code>
+     */
+    public function setIntervalUs($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->interval_us = $var;
+    }
+
+    /**
+     * <pre>
+     * Whether to request the server to compress the response. This field is
+     * "nullable" in order to interoperate seamlessly with clients not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the response's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue compressed = 3;</code>
+     */
+    public function getCompressed()
+    {
+        return $this->compressed;
+    }
+
+    /**
+     * <pre>
+     * Whether to request the server to compress the response. This field is
+     * "nullable" in order to interoperate seamlessly with clients not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the response's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue compressed = 3;</code>
+     */
+    public function setCompressed(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\BoolValue::class);
+        $this->compressed = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/RpcType.php b/src/php/tests/qps/generated_code/Grpc/Testing/RpcType.php
new file mode 100644
index 0000000000000000000000000000000000000000..2e664fff47716c5ba0f7704c522ac7d0f35d4fa0
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/RpcType.php
@@ -0,0 +1,21 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+/**
+ * Protobuf enum <code>grpc.testing.RpcType</code>
+ */
+class RpcType
+{
+    /**
+     * <code>UNARY = 0;</code>
+     */
+    const UNARY = 0;
+    /**
+     * <code>STREAMING = 1;</code>
+     */
+    const STREAMING = 1;
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/Scenario.php b/src/php/tests/qps/generated_code/Grpc/Testing/Scenario.php
new file mode 100644
index 0000000000000000000000000000000000000000..136ed299ea8ad6385f8c6698b0e4cd53a5d2dd06
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/Scenario.php
@@ -0,0 +1,291 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * A single performance scenario: input to qps_json_driver
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.Scenario</code>
+ */
+class Scenario extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Human readable name for this scenario
+     * </pre>
+     *
+     * <code>string name = 1;</code>
+     */
+    private $name = '';
+    /**
+     * <pre>
+     * Client configuration
+     * </pre>
+     *
+     * <code>.grpc.testing.ClientConfig client_config = 2;</code>
+     */
+    private $client_config = null;
+    /**
+     * <pre>
+     * Number of clients to start for the test
+     * </pre>
+     *
+     * <code>int32 num_clients = 3;</code>
+     */
+    private $num_clients = 0;
+    /**
+     * <pre>
+     * Server configuration
+     * </pre>
+     *
+     * <code>.grpc.testing.ServerConfig server_config = 4;</code>
+     */
+    private $server_config = null;
+    /**
+     * <pre>
+     * Number of servers to start for the test
+     * </pre>
+     *
+     * <code>int32 num_servers = 5;</code>
+     */
+    private $num_servers = 0;
+    /**
+     * <pre>
+     * Warmup period, in seconds
+     * </pre>
+     *
+     * <code>int32 warmup_seconds = 6;</code>
+     */
+    private $warmup_seconds = 0;
+    /**
+     * <pre>
+     * Benchmark time, in seconds
+     * </pre>
+     *
+     * <code>int32 benchmark_seconds = 7;</code>
+     */
+    private $benchmark_seconds = 0;
+    /**
+     * <pre>
+     * Number of workers to spawn locally (usually zero)
+     * </pre>
+     *
+     * <code>int32 spawn_local_worker_count = 8;</code>
+     */
+    private $spawn_local_worker_count = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Human readable name for this scenario
+     * </pre>
+     *
+     * <code>string name = 1;</code>
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * <pre>
+     * Human readable name for this scenario
+     * </pre>
+     *
+     * <code>string name = 1;</code>
+     */
+    public function setName($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->name = $var;
+    }
+
+    /**
+     * <pre>
+     * Client configuration
+     * </pre>
+     *
+     * <code>.grpc.testing.ClientConfig client_config = 2;</code>
+     */
+    public function getClientConfig()
+    {
+        return $this->client_config;
+    }
+
+    /**
+     * <pre>
+     * Client configuration
+     * </pre>
+     *
+     * <code>.grpc.testing.ClientConfig client_config = 2;</code>
+     */
+    public function setClientConfig(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ClientConfig::class);
+        $this->client_config = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of clients to start for the test
+     * </pre>
+     *
+     * <code>int32 num_clients = 3;</code>
+     */
+    public function getNumClients()
+    {
+        return $this->num_clients;
+    }
+
+    /**
+     * <pre>
+     * Number of clients to start for the test
+     * </pre>
+     *
+     * <code>int32 num_clients = 3;</code>
+     */
+    public function setNumClients($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->num_clients = $var;
+    }
+
+    /**
+     * <pre>
+     * Server configuration
+     * </pre>
+     *
+     * <code>.grpc.testing.ServerConfig server_config = 4;</code>
+     */
+    public function getServerConfig()
+    {
+        return $this->server_config;
+    }
+
+    /**
+     * <pre>
+     * Server configuration
+     * </pre>
+     *
+     * <code>.grpc.testing.ServerConfig server_config = 4;</code>
+     */
+    public function setServerConfig(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ServerConfig::class);
+        $this->server_config = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of servers to start for the test
+     * </pre>
+     *
+     * <code>int32 num_servers = 5;</code>
+     */
+    public function getNumServers()
+    {
+        return $this->num_servers;
+    }
+
+    /**
+     * <pre>
+     * Number of servers to start for the test
+     * </pre>
+     *
+     * <code>int32 num_servers = 5;</code>
+     */
+    public function setNumServers($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->num_servers = $var;
+    }
+
+    /**
+     * <pre>
+     * Warmup period, in seconds
+     * </pre>
+     *
+     * <code>int32 warmup_seconds = 6;</code>
+     */
+    public function getWarmupSeconds()
+    {
+        return $this->warmup_seconds;
+    }
+
+    /**
+     * <pre>
+     * Warmup period, in seconds
+     * </pre>
+     *
+     * <code>int32 warmup_seconds = 6;</code>
+     */
+    public function setWarmupSeconds($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->warmup_seconds = $var;
+    }
+
+    /**
+     * <pre>
+     * Benchmark time, in seconds
+     * </pre>
+     *
+     * <code>int32 benchmark_seconds = 7;</code>
+     */
+    public function getBenchmarkSeconds()
+    {
+        return $this->benchmark_seconds;
+    }
+
+    /**
+     * <pre>
+     * Benchmark time, in seconds
+     * </pre>
+     *
+     * <code>int32 benchmark_seconds = 7;</code>
+     */
+    public function setBenchmarkSeconds($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->benchmark_seconds = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of workers to spawn locally (usually zero)
+     * </pre>
+     *
+     * <code>int32 spawn_local_worker_count = 8;</code>
+     */
+    public function getSpawnLocalWorkerCount()
+    {
+        return $this->spawn_local_worker_count;
+    }
+
+    /**
+     * <pre>
+     * Number of workers to spawn locally (usually zero)
+     * </pre>
+     *
+     * <code>int32 spawn_local_worker_count = 8;</code>
+     */
+    public function setSpawnLocalWorkerCount($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->spawn_local_worker_count = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ScenarioResult.php b/src/php/tests/qps/generated_code/Grpc/Testing/ScenarioResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..809cd96244df250b37100aa40e007e4091e78dca
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ScenarioResult.php
@@ -0,0 +1,312 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Results of a single benchmark scenario.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.ScenarioResult</code>
+ */
+class ScenarioResult extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Inputs used to run the scenario.
+     * </pre>
+     *
+     * <code>.grpc.testing.Scenario scenario = 1;</code>
+     */
+    private $scenario = null;
+    /**
+     * <pre>
+     * Histograms from all clients merged into one histogram.
+     * </pre>
+     *
+     * <code>.grpc.testing.HistogramData latencies = 2;</code>
+     */
+    private $latencies = null;
+    /**
+     * <pre>
+     * Client stats for each client
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ClientStats client_stats = 3;</code>
+     */
+    private $client_stats;
+    /**
+     * <pre>
+     * Server stats for each server
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ServerStats server_stats = 4;</code>
+     */
+    private $server_stats;
+    /**
+     * <pre>
+     * Number of cores available to each server
+     * </pre>
+     *
+     * <code>repeated int32 server_cores = 5;</code>
+     */
+    private $server_cores;
+    /**
+     * <pre>
+     * An after-the-fact computed summary
+     * </pre>
+     *
+     * <code>.grpc.testing.ScenarioResultSummary summary = 6;</code>
+     */
+    private $summary = null;
+    /**
+     * <pre>
+     * Information on success or failure of each worker
+     * </pre>
+     *
+     * <code>repeated bool client_success = 7;</code>
+     */
+    private $client_success;
+    /**
+     * <code>repeated bool server_success = 8;</code>
+     */
+    private $server_success;
+    /**
+     * <pre>
+     * Number of failed requests (one row per status code seen)
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.RequestResultCount request_results = 9;</code>
+     */
+    private $request_results;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Inputs used to run the scenario.
+     * </pre>
+     *
+     * <code>.grpc.testing.Scenario scenario = 1;</code>
+     */
+    public function getScenario()
+    {
+        return $this->scenario;
+    }
+
+    /**
+     * <pre>
+     * Inputs used to run the scenario.
+     * </pre>
+     *
+     * <code>.grpc.testing.Scenario scenario = 1;</code>
+     */
+    public function setScenario(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\Scenario::class);
+        $this->scenario = $var;
+    }
+
+    /**
+     * <pre>
+     * Histograms from all clients merged into one histogram.
+     * </pre>
+     *
+     * <code>.grpc.testing.HistogramData latencies = 2;</code>
+     */
+    public function getLatencies()
+    {
+        return $this->latencies;
+    }
+
+    /**
+     * <pre>
+     * Histograms from all clients merged into one histogram.
+     * </pre>
+     *
+     * <code>.grpc.testing.HistogramData latencies = 2;</code>
+     */
+    public function setLatencies(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\HistogramData::class);
+        $this->latencies = $var;
+    }
+
+    /**
+     * <pre>
+     * Client stats for each client
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ClientStats client_stats = 3;</code>
+     */
+    public function getClientStats()
+    {
+        return $this->client_stats;
+    }
+
+    /**
+     * <pre>
+     * Client stats for each client
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ClientStats client_stats = 3;</code>
+     */
+    public function setClientStats(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Grpc\Testing\ClientStats::class);
+        $this->client_stats = $var;
+    }
+
+    /**
+     * <pre>
+     * Server stats for each server
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ServerStats server_stats = 4;</code>
+     */
+    public function getServerStats()
+    {
+        return $this->server_stats;
+    }
+
+    /**
+     * <pre>
+     * Server stats for each server
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ServerStats server_stats = 4;</code>
+     */
+    public function setServerStats(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Grpc\Testing\ServerStats::class);
+        $this->server_stats = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of cores available to each server
+     * </pre>
+     *
+     * <code>repeated int32 server_cores = 5;</code>
+     */
+    public function getServerCores()
+    {
+        return $this->server_cores;
+    }
+
+    /**
+     * <pre>
+     * Number of cores available to each server
+     * </pre>
+     *
+     * <code>repeated int32 server_cores = 5;</code>
+     */
+    public function setServerCores(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
+        $this->server_cores = $var;
+    }
+
+    /**
+     * <pre>
+     * An after-the-fact computed summary
+     * </pre>
+     *
+     * <code>.grpc.testing.ScenarioResultSummary summary = 6;</code>
+     */
+    public function getSummary()
+    {
+        return $this->summary;
+    }
+
+    /**
+     * <pre>
+     * An after-the-fact computed summary
+     * </pre>
+     *
+     * <code>.grpc.testing.ScenarioResultSummary summary = 6;</code>
+     */
+    public function setSummary(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ScenarioResultSummary::class);
+        $this->summary = $var;
+    }
+
+    /**
+     * <pre>
+     * Information on success or failure of each worker
+     * </pre>
+     *
+     * <code>repeated bool client_success = 7;</code>
+     */
+    public function getClientSuccess()
+    {
+        return $this->client_success;
+    }
+
+    /**
+     * <pre>
+     * Information on success or failure of each worker
+     * </pre>
+     *
+     * <code>repeated bool client_success = 7;</code>
+     */
+    public function setClientSuccess(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::BOOL);
+        $this->client_success = $var;
+    }
+
+    /**
+     * <code>repeated bool server_success = 8;</code>
+     */
+    public function getServerSuccess()
+    {
+        return $this->server_success;
+    }
+
+    /**
+     * <code>repeated bool server_success = 8;</code>
+     */
+    public function setServerSuccess(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::BOOL);
+        $this->server_success = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of failed requests (one row per status code seen)
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.RequestResultCount request_results = 9;</code>
+     */
+    public function getRequestResults()
+    {
+        return $this->request_results;
+    }
+
+    /**
+     * <pre>
+     * Number of failed requests (one row per status code seen)
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.RequestResultCount request_results = 9;</code>
+     */
+    public function setRequestResults(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Grpc\Testing\RequestResultCount::class);
+        $this->request_results = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ScenarioResultSummary.php b/src/php/tests/qps/generated_code/Grpc/Testing/ScenarioResultSummary.php
new file mode 100644
index 0000000000000000000000000000000000000000..7520cff78e8300e650dab257e9addae66e349755
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ScenarioResultSummary.php
@@ -0,0 +1,430 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Basic summary that can be computed from ClientStats and ServerStats
+ * once the scenario has finished.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.ScenarioResultSummary</code>
+ */
+class ScenarioResultSummary extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Total number of operations per second over all clients.
+     * </pre>
+     *
+     * <code>double qps = 1;</code>
+     */
+    private $qps = 0.0;
+    /**
+     * <pre>
+     * QPS per one server core.
+     * </pre>
+     *
+     * <code>double qps_per_server_core = 2;</code>
+     */
+    private $qps_per_server_core = 0.0;
+    /**
+     * <pre>
+     * server load based on system_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double server_system_time = 3;</code>
+     */
+    private $server_system_time = 0.0;
+    /**
+     * <pre>
+     * server load based on user_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double server_user_time = 4;</code>
+     */
+    private $server_user_time = 0.0;
+    /**
+     * <pre>
+     * client load based on system_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double client_system_time = 5;</code>
+     */
+    private $client_system_time = 0.0;
+    /**
+     * <pre>
+     * client load based on user_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double client_user_time = 6;</code>
+     */
+    private $client_user_time = 0.0;
+    /**
+     * <pre>
+     * X% latency percentiles (in nanoseconds)
+     * </pre>
+     *
+     * <code>double latency_50 = 7;</code>
+     */
+    private $latency_50 = 0.0;
+    /**
+     * <code>double latency_90 = 8;</code>
+     */
+    private $latency_90 = 0.0;
+    /**
+     * <code>double latency_95 = 9;</code>
+     */
+    private $latency_95 = 0.0;
+    /**
+     * <code>double latency_99 = 10;</code>
+     */
+    private $latency_99 = 0.0;
+    /**
+     * <code>double latency_999 = 11;</code>
+     */
+    private $latency_999 = 0.0;
+    /**
+     * <pre>
+     * server cpu usage percentage
+     * </pre>
+     *
+     * <code>double server_cpu_usage = 12;</code>
+     */
+    private $server_cpu_usage = 0.0;
+    /**
+     * <pre>
+     * Number of requests that succeeded/failed
+     * </pre>
+     *
+     * <code>double successful_requests_per_second = 13;</code>
+     */
+    private $successful_requests_per_second = 0.0;
+    /**
+     * <code>double failed_requests_per_second = 14;</code>
+     */
+    private $failed_requests_per_second = 0.0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Total number of operations per second over all clients.
+     * </pre>
+     *
+     * <code>double qps = 1;</code>
+     */
+    public function getQps()
+    {
+        return $this->qps;
+    }
+
+    /**
+     * <pre>
+     * Total number of operations per second over all clients.
+     * </pre>
+     *
+     * <code>double qps = 1;</code>
+     */
+    public function setQps($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->qps = $var;
+    }
+
+    /**
+     * <pre>
+     * QPS per one server core.
+     * </pre>
+     *
+     * <code>double qps_per_server_core = 2;</code>
+     */
+    public function getQpsPerServerCore()
+    {
+        return $this->qps_per_server_core;
+    }
+
+    /**
+     * <pre>
+     * QPS per one server core.
+     * </pre>
+     *
+     * <code>double qps_per_server_core = 2;</code>
+     */
+    public function setQpsPerServerCore($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->qps_per_server_core = $var;
+    }
+
+    /**
+     * <pre>
+     * server load based on system_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double server_system_time = 3;</code>
+     */
+    public function getServerSystemTime()
+    {
+        return $this->server_system_time;
+    }
+
+    /**
+     * <pre>
+     * server load based on system_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double server_system_time = 3;</code>
+     */
+    public function setServerSystemTime($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->server_system_time = $var;
+    }
+
+    /**
+     * <pre>
+     * server load based on user_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double server_user_time = 4;</code>
+     */
+    public function getServerUserTime()
+    {
+        return $this->server_user_time;
+    }
+
+    /**
+     * <pre>
+     * server load based on user_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double server_user_time = 4;</code>
+     */
+    public function setServerUserTime($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->server_user_time = $var;
+    }
+
+    /**
+     * <pre>
+     * client load based on system_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double client_system_time = 5;</code>
+     */
+    public function getClientSystemTime()
+    {
+        return $this->client_system_time;
+    }
+
+    /**
+     * <pre>
+     * client load based on system_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double client_system_time = 5;</code>
+     */
+    public function setClientSystemTime($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->client_system_time = $var;
+    }
+
+    /**
+     * <pre>
+     * client load based on user_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double client_user_time = 6;</code>
+     */
+    public function getClientUserTime()
+    {
+        return $this->client_user_time;
+    }
+
+    /**
+     * <pre>
+     * client load based on user_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double client_user_time = 6;</code>
+     */
+    public function setClientUserTime($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->client_user_time = $var;
+    }
+
+    /**
+     * <pre>
+     * X% latency percentiles (in nanoseconds)
+     * </pre>
+     *
+     * <code>double latency_50 = 7;</code>
+     */
+    public function getLatency50()
+    {
+        return $this->latency_50;
+    }
+
+    /**
+     * <pre>
+     * X% latency percentiles (in nanoseconds)
+     * </pre>
+     *
+     * <code>double latency_50 = 7;</code>
+     */
+    public function setLatency50($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->latency_50 = $var;
+    }
+
+    /**
+     * <code>double latency_90 = 8;</code>
+     */
+    public function getLatency90()
+    {
+        return $this->latency_90;
+    }
+
+    /**
+     * <code>double latency_90 = 8;</code>
+     */
+    public function setLatency90($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->latency_90 = $var;
+    }
+
+    /**
+     * <code>double latency_95 = 9;</code>
+     */
+    public function getLatency95()
+    {
+        return $this->latency_95;
+    }
+
+    /**
+     * <code>double latency_95 = 9;</code>
+     */
+    public function setLatency95($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->latency_95 = $var;
+    }
+
+    /**
+     * <code>double latency_99 = 10;</code>
+     */
+    public function getLatency99()
+    {
+        return $this->latency_99;
+    }
+
+    /**
+     * <code>double latency_99 = 10;</code>
+     */
+    public function setLatency99($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->latency_99 = $var;
+    }
+
+    /**
+     * <code>double latency_999 = 11;</code>
+     */
+    public function getLatency999()
+    {
+        return $this->latency_999;
+    }
+
+    /**
+     * <code>double latency_999 = 11;</code>
+     */
+    public function setLatency999($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->latency_999 = $var;
+    }
+
+    /**
+     * <pre>
+     * server cpu usage percentage
+     * </pre>
+     *
+     * <code>double server_cpu_usage = 12;</code>
+     */
+    public function getServerCpuUsage()
+    {
+        return $this->server_cpu_usage;
+    }
+
+    /**
+     * <pre>
+     * server cpu usage percentage
+     * </pre>
+     *
+     * <code>double server_cpu_usage = 12;</code>
+     */
+    public function setServerCpuUsage($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->server_cpu_usage = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of requests that succeeded/failed
+     * </pre>
+     *
+     * <code>double successful_requests_per_second = 13;</code>
+     */
+    public function getSuccessfulRequestsPerSecond()
+    {
+        return $this->successful_requests_per_second;
+    }
+
+    /**
+     * <pre>
+     * Number of requests that succeeded/failed
+     * </pre>
+     *
+     * <code>double successful_requests_per_second = 13;</code>
+     */
+    public function setSuccessfulRequestsPerSecond($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->successful_requests_per_second = $var;
+    }
+
+    /**
+     * <code>double failed_requests_per_second = 14;</code>
+     */
+    public function getFailedRequestsPerSecond()
+    {
+        return $this->failed_requests_per_second;
+    }
+
+    /**
+     * <code>double failed_requests_per_second = 14;</code>
+     */
+    public function setFailedRequestsPerSecond($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->failed_requests_per_second = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/Scenarios.php b/src/php/tests/qps/generated_code/Grpc/Testing/Scenarios.php
new file mode 100644
index 0000000000000000000000000000000000000000..278f555b7606338f767c20c0ef610e22719a2cb6
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/Scenarios.php
@@ -0,0 +1,48 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * A set of scenarios to be run with qps_json_driver
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.Scenarios</code>
+ */
+class Scenarios extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>repeated .grpc.testing.Scenario scenarios = 1;</code>
+     */
+    private $scenarios;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>repeated .grpc.testing.Scenario scenarios = 1;</code>
+     */
+    public function getScenarios()
+    {
+        return $this->scenarios;
+    }
+
+    /**
+     * <code>repeated .grpc.testing.Scenario scenarios = 1;</code>
+     */
+    public function setScenarios(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Grpc\Testing\Scenario::class);
+        $this->scenarios = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/SecurityParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/SecurityParams.php
new file mode 100644
index 0000000000000000000000000000000000000000..27a5b95cc94db5a4605e141d2c3272b8bf1e6657
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/SecurityParams.php
@@ -0,0 +1,69 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * presence of SecurityParams implies use of TLS
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.SecurityParams</code>
+ */
+class SecurityParams extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>bool use_test_ca = 1;</code>
+     */
+    private $use_test_ca = false;
+    /**
+     * <code>string server_host_override = 2;</code>
+     */
+    private $server_host_override = '';
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>bool use_test_ca = 1;</code>
+     */
+    public function getUseTestCa()
+    {
+        return $this->use_test_ca;
+    }
+
+    /**
+     * <code>bool use_test_ca = 1;</code>
+     */
+    public function setUseTestCa($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->use_test_ca = $var;
+    }
+
+    /**
+     * <code>string server_host_override = 2;</code>
+     */
+    public function getServerHostOverride()
+    {
+        return $this->server_host_override;
+    }
+
+    /**
+     * <code>string server_host_override = 2;</code>
+     */
+    public function setServerHostOverride($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->server_host_override = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ServerArgs.php b/src/php/tests/qps/generated_code/Grpc/Testing/ServerArgs.php
new file mode 100644
index 0000000000000000000000000000000000000000..0d84b80124ae2b2927358b2639f0a712afb50749
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ServerArgs.php
@@ -0,0 +1,63 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.ServerArgs</code>
+ */
+class ServerArgs extends \Google\Protobuf\Internal\Message
+{
+    protected $argtype;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>.grpc.testing.ServerConfig setup = 1;</code>
+     */
+    public function getSetup()
+    {
+        return $this->readOneof(1);
+    }
+
+    /**
+     * <code>.grpc.testing.ServerConfig setup = 1;</code>
+     */
+    public function setSetup(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ServerConfig::class);
+        $this->writeOneof(1, $var);
+    }
+
+    /**
+     * <code>.grpc.testing.Mark mark = 2;</code>
+     */
+    public function getMark()
+    {
+        return $this->readOneof(2);
+    }
+
+    /**
+     * <code>.grpc.testing.Mark mark = 2;</code>
+     */
+    public function setMark(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\Mark::class);
+        $this->writeOneof(2, $var);
+    }
+
+    public function getArgtype()
+    {
+        return $this->whichOneof("argtype");
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ServerConfig.php b/src/php/tests/qps/generated_code/Grpc/Testing/ServerConfig.php
new file mode 100644
index 0000000000000000000000000000000000000000..e2bcede48cbd908422ea799da04793d3af5ac41b
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ServerConfig.php
@@ -0,0 +1,305 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.ServerConfig</code>
+ */
+class ServerConfig extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>.grpc.testing.ServerType server_type = 1;</code>
+     */
+    private $server_type = 0;
+    /**
+     * <code>.grpc.testing.SecurityParams security_params = 2;</code>
+     */
+    private $security_params = null;
+    /**
+     * <pre>
+     * Port on which to listen. Zero means pick unused port.
+     * </pre>
+     *
+     * <code>int32 port = 4;</code>
+     */
+    private $port = 0;
+    /**
+     * <pre>
+     * Only for async server. Number of threads used to serve the requests.
+     * </pre>
+     *
+     * <code>int32 async_server_threads = 7;</code>
+     */
+    private $async_server_threads = 0;
+    /**
+     * <pre>
+     * Specify the number of cores to limit server to, if desired
+     * </pre>
+     *
+     * <code>int32 core_limit = 8;</code>
+     */
+    private $core_limit = 0;
+    /**
+     * <pre>
+     * payload config, used in generic server.
+     * Note this must NOT be used in proto (non-generic) servers. For proto servers,
+     * 'response sizes' must be configured from the 'response_size' field of the
+     * 'SimpleRequest' objects in RPC requests.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadConfig payload_config = 9;</code>
+     */
+    private $payload_config = null;
+    /**
+     * <pre>
+     * Specify the cores we should run the server on, if desired
+     * </pre>
+     *
+     * <code>repeated int32 core_list = 10;</code>
+     */
+    private $core_list;
+    /**
+     * <pre>
+     * If we use an OTHER_SERVER client_type, this string gives more detail
+     * </pre>
+     *
+     * <code>string other_server_api = 11;</code>
+     */
+    private $other_server_api = '';
+    /**
+     * <pre>
+     * Buffer pool size (no buffer pool specified if unset)
+     * </pre>
+     *
+     * <code>int32 resource_quota_size = 1001;</code>
+     */
+    private $resource_quota_size = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>.grpc.testing.ServerType server_type = 1;</code>
+     */
+    public function getServerType()
+    {
+        return $this->server_type;
+    }
+
+    /**
+     * <code>.grpc.testing.ServerType server_type = 1;</code>
+     */
+    public function setServerType($var)
+    {
+        GPBUtil::checkEnum($var, \Grpc\Testing\ServerType::class);
+        $this->server_type = $var;
+    }
+
+    /**
+     * <code>.grpc.testing.SecurityParams security_params = 2;</code>
+     */
+    public function getSecurityParams()
+    {
+        return $this->security_params;
+    }
+
+    /**
+     * <code>.grpc.testing.SecurityParams security_params = 2;</code>
+     */
+    public function setSecurityParams(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\SecurityParams::class);
+        $this->security_params = $var;
+    }
+
+    /**
+     * <pre>
+     * Port on which to listen. Zero means pick unused port.
+     * </pre>
+     *
+     * <code>int32 port = 4;</code>
+     */
+    public function getPort()
+    {
+        return $this->port;
+    }
+
+    /**
+     * <pre>
+     * Port on which to listen. Zero means pick unused port.
+     * </pre>
+     *
+     * <code>int32 port = 4;</code>
+     */
+    public function setPort($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->port = $var;
+    }
+
+    /**
+     * <pre>
+     * Only for async server. Number of threads used to serve the requests.
+     * </pre>
+     *
+     * <code>int32 async_server_threads = 7;</code>
+     */
+    public function getAsyncServerThreads()
+    {
+        return $this->async_server_threads;
+    }
+
+    /**
+     * <pre>
+     * Only for async server. Number of threads used to serve the requests.
+     * </pre>
+     *
+     * <code>int32 async_server_threads = 7;</code>
+     */
+    public function setAsyncServerThreads($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->async_server_threads = $var;
+    }
+
+    /**
+     * <pre>
+     * Specify the number of cores to limit server to, if desired
+     * </pre>
+     *
+     * <code>int32 core_limit = 8;</code>
+     */
+    public function getCoreLimit()
+    {
+        return $this->core_limit;
+    }
+
+    /**
+     * <pre>
+     * Specify the number of cores to limit server to, if desired
+     * </pre>
+     *
+     * <code>int32 core_limit = 8;</code>
+     */
+    public function setCoreLimit($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->core_limit = $var;
+    }
+
+    /**
+     * <pre>
+     * payload config, used in generic server.
+     * Note this must NOT be used in proto (non-generic) servers. For proto servers,
+     * 'response sizes' must be configured from the 'response_size' field of the
+     * 'SimpleRequest' objects in RPC requests.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadConfig payload_config = 9;</code>
+     */
+    public function getPayloadConfig()
+    {
+        return $this->payload_config;
+    }
+
+    /**
+     * <pre>
+     * payload config, used in generic server.
+     * Note this must NOT be used in proto (non-generic) servers. For proto servers,
+     * 'response sizes' must be configured from the 'response_size' field of the
+     * 'SimpleRequest' objects in RPC requests.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadConfig payload_config = 9;</code>
+     */
+    public function setPayloadConfig(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\PayloadConfig::class);
+        $this->payload_config = $var;
+    }
+
+    /**
+     * <pre>
+     * Specify the cores we should run the server on, if desired
+     * </pre>
+     *
+     * <code>repeated int32 core_list = 10;</code>
+     */
+    public function getCoreList()
+    {
+        return $this->core_list;
+    }
+
+    /**
+     * <pre>
+     * Specify the cores we should run the server on, if desired
+     * </pre>
+     *
+     * <code>repeated int32 core_list = 10;</code>
+     */
+    public function setCoreList(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
+        $this->core_list = $var;
+    }
+
+    /**
+     * <pre>
+     * If we use an OTHER_SERVER client_type, this string gives more detail
+     * </pre>
+     *
+     * <code>string other_server_api = 11;</code>
+     */
+    public function getOtherServerApi()
+    {
+        return $this->other_server_api;
+    }
+
+    /**
+     * <pre>
+     * If we use an OTHER_SERVER client_type, this string gives more detail
+     * </pre>
+     *
+     * <code>string other_server_api = 11;</code>
+     */
+    public function setOtherServerApi($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->other_server_api = $var;
+    }
+
+    /**
+     * <pre>
+     * Buffer pool size (no buffer pool specified if unset)
+     * </pre>
+     *
+     * <code>int32 resource_quota_size = 1001;</code>
+     */
+    public function getResourceQuotaSize()
+    {
+        return $this->resource_quota_size;
+    }
+
+    /**
+     * <pre>
+     * Buffer pool size (no buffer pool specified if unset)
+     * </pre>
+     *
+     * <code>int32 resource_quota_size = 1001;</code>
+     */
+    public function setResourceQuotaSize($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->resource_quota_size = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ServerStats.php b/src/php/tests/qps/generated_code/Grpc/Testing/ServerStats.php
new file mode 100644
index 0000000000000000000000000000000000000000..98b2af764c94fd1db6945d9b1afbdb98ac4d37e5
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ServerStats.php
@@ -0,0 +1,191 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/stats.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.ServerStats</code>
+ */
+class ServerStats extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * wall clock time change in seconds since last reset
+     * </pre>
+     *
+     * <code>double time_elapsed = 1;</code>
+     */
+    private $time_elapsed = 0.0;
+    /**
+     * <pre>
+     * change in user time (in seconds) used by the server since last reset
+     * </pre>
+     *
+     * <code>double time_user = 2;</code>
+     */
+    private $time_user = 0.0;
+    /**
+     * <pre>
+     * change in server time (in seconds) used by the server process and all
+     * threads since last reset
+     * </pre>
+     *
+     * <code>double time_system = 3;</code>
+     */
+    private $time_system = 0.0;
+    /**
+     * <pre>
+     * change in total cpu time of the server (data from proc/stat)
+     * </pre>
+     *
+     * <code>uint64 total_cpu_time = 4;</code>
+     */
+    private $total_cpu_time = 0;
+    /**
+     * <pre>
+     * change in idle time of the server (data from proc/stat)
+     * </pre>
+     *
+     * <code>uint64 idle_cpu_time = 5;</code>
+     */
+    private $idle_cpu_time = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Stats::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * wall clock time change in seconds since last reset
+     * </pre>
+     *
+     * <code>double time_elapsed = 1;</code>
+     */
+    public function getTimeElapsed()
+    {
+        return $this->time_elapsed;
+    }
+
+    /**
+     * <pre>
+     * wall clock time change in seconds since last reset
+     * </pre>
+     *
+     * <code>double time_elapsed = 1;</code>
+     */
+    public function setTimeElapsed($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->time_elapsed = $var;
+    }
+
+    /**
+     * <pre>
+     * change in user time (in seconds) used by the server since last reset
+     * </pre>
+     *
+     * <code>double time_user = 2;</code>
+     */
+    public function getTimeUser()
+    {
+        return $this->time_user;
+    }
+
+    /**
+     * <pre>
+     * change in user time (in seconds) used by the server since last reset
+     * </pre>
+     *
+     * <code>double time_user = 2;</code>
+     */
+    public function setTimeUser($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->time_user = $var;
+    }
+
+    /**
+     * <pre>
+     * change in server time (in seconds) used by the server process and all
+     * threads since last reset
+     * </pre>
+     *
+     * <code>double time_system = 3;</code>
+     */
+    public function getTimeSystem()
+    {
+        return $this->time_system;
+    }
+
+    /**
+     * <pre>
+     * change in server time (in seconds) used by the server process and all
+     * threads since last reset
+     * </pre>
+     *
+     * <code>double time_system = 3;</code>
+     */
+    public function setTimeSystem($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->time_system = $var;
+    }
+
+    /**
+     * <pre>
+     * change in total cpu time of the server (data from proc/stat)
+     * </pre>
+     *
+     * <code>uint64 total_cpu_time = 4;</code>
+     */
+    public function getTotalCpuTime()
+    {
+        return $this->total_cpu_time;
+    }
+
+    /**
+     * <pre>
+     * change in total cpu time of the server (data from proc/stat)
+     * </pre>
+     *
+     * <code>uint64 total_cpu_time = 4;</code>
+     */
+    public function setTotalCpuTime($var)
+    {
+        GPBUtil::checkUint64($var);
+        $this->total_cpu_time = $var;
+    }
+
+    /**
+     * <pre>
+     * change in idle time of the server (data from proc/stat)
+     * </pre>
+     *
+     * <code>uint64 idle_cpu_time = 5;</code>
+     */
+    public function getIdleCpuTime()
+    {
+        return $this->idle_cpu_time;
+    }
+
+    /**
+     * <pre>
+     * change in idle time of the server (data from proc/stat)
+     * </pre>
+     *
+     * <code>uint64 idle_cpu_time = 5;</code>
+     */
+    public function setIdleCpuTime($var)
+    {
+        GPBUtil::checkUint64($var);
+        $this->idle_cpu_time = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ServerStatus.php b/src/php/tests/qps/generated_code/Grpc/Testing/ServerStatus.php
new file mode 100644
index 0000000000000000000000000000000000000000..d293f03fbdfe3557e2954dbce1940b67800ef110
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ServerStatus.php
@@ -0,0 +1,110 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.ServerStatus</code>
+ */
+class ServerStatus extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>.grpc.testing.ServerStats stats = 1;</code>
+     */
+    private $stats = null;
+    /**
+     * <pre>
+     * the port bound by the server
+     * </pre>
+     *
+     * <code>int32 port = 2;</code>
+     */
+    private $port = 0;
+    /**
+     * <pre>
+     * Number of cores available to the server
+     * </pre>
+     *
+     * <code>int32 cores = 3;</code>
+     */
+    private $cores = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>.grpc.testing.ServerStats stats = 1;</code>
+     */
+    public function getStats()
+    {
+        return $this->stats;
+    }
+
+    /**
+     * <code>.grpc.testing.ServerStats stats = 1;</code>
+     */
+    public function setStats(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ServerStats::class);
+        $this->stats = $var;
+    }
+
+    /**
+     * <pre>
+     * the port bound by the server
+     * </pre>
+     *
+     * <code>int32 port = 2;</code>
+     */
+    public function getPort()
+    {
+        return $this->port;
+    }
+
+    /**
+     * <pre>
+     * the port bound by the server
+     * </pre>
+     *
+     * <code>int32 port = 2;</code>
+     */
+    public function setPort($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->port = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of cores available to the server
+     * </pre>
+     *
+     * <code>int32 cores = 3;</code>
+     */
+    public function getCores()
+    {
+        return $this->cores;
+    }
+
+    /**
+     * <pre>
+     * Number of cores available to the server
+     * </pre>
+     *
+     * <code>int32 cores = 3;</code>
+     */
+    public function setCores($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->cores = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ServerType.php b/src/php/tests/qps/generated_code/Grpc/Testing/ServerType.php
new file mode 100644
index 0000000000000000000000000000000000000000..605c83c3f76d85310356f02c71ee252f04264721
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ServerType.php
@@ -0,0 +1,33 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+/**
+ * Protobuf enum <code>grpc.testing.ServerType</code>
+ */
+class ServerType
+{
+    /**
+     * <code>SYNC_SERVER = 0;</code>
+     */
+    const SYNC_SERVER = 0;
+    /**
+     * <code>ASYNC_SERVER = 1;</code>
+     */
+    const ASYNC_SERVER = 1;
+    /**
+     * <code>ASYNC_GENERIC_SERVER = 2;</code>
+     */
+    const ASYNC_GENERIC_SERVER = 2;
+    /**
+     * <pre>
+     * used for some language-specific variants
+     * </pre>
+     *
+     * <code>OTHER_SERVER = 3;</code>
+     */
+    const OTHER_SERVER = 3;
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/SimpleProtoParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/SimpleProtoParams.php
new file mode 100644
index 0000000000000000000000000000000000000000..29834a3be71a7ae28d3f772b967001d12c663203
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/SimpleProtoParams.php
@@ -0,0 +1,65 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/payloads.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.SimpleProtoParams</code>
+ */
+class SimpleProtoParams extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>int32 req_size = 1;</code>
+     */
+    private $req_size = 0;
+    /**
+     * <code>int32 resp_size = 2;</code>
+     */
+    private $resp_size = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Payloads::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>int32 req_size = 1;</code>
+     */
+    public function getReqSize()
+    {
+        return $this->req_size;
+    }
+
+    /**
+     * <code>int32 req_size = 1;</code>
+     */
+    public function setReqSize($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->req_size = $var;
+    }
+
+    /**
+     * <code>int32 resp_size = 2;</code>
+     */
+    public function getRespSize()
+    {
+        return $this->resp_size;
+    }
+
+    /**
+     * <code>int32 resp_size = 2;</code>
+     */
+    public function setRespSize($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->resp_size = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/SimpleRequest.php b/src/php/tests/qps/generated_code/Grpc/Testing/SimpleRequest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f84c95319f4efc746bd7adab9dc6faf8c3f660d7
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/SimpleRequest.php
@@ -0,0 +1,306 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Unary request.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.SimpleRequest</code>
+ */
+class SimpleRequest extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * Desired payload type in the response from the server.
+     * If response_type is RANDOM, server randomly chooses one from other formats.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType response_type = 1;</code>
+     */
+    private $response_type = 0;
+    /**
+     * <pre>
+     * Desired payload size in the response from the server.
+     * </pre>
+     *
+     * <code>int32 response_size = 2;</code>
+     */
+    private $response_size = 0;
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 3;</code>
+     */
+    private $payload = null;
+    /**
+     * <pre>
+     * Whether SimpleResponse should include username.
+     * </pre>
+     *
+     * <code>bool fill_username = 4;</code>
+     */
+    private $fill_username = false;
+    /**
+     * <pre>
+     * Whether SimpleResponse should include OAuth scope.
+     * </pre>
+     *
+     * <code>bool fill_oauth_scope = 5;</code>
+     */
+    private $fill_oauth_scope = false;
+    /**
+     * <pre>
+     * Whether to request the server to compress the response. This field is
+     * "nullable" in order to interoperate seamlessly with clients not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the response's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue response_compressed = 6;</code>
+     */
+    private $response_compressed = null;
+    /**
+     * <pre>
+     * Whether server should return a given status
+     * </pre>
+     *
+     * <code>.grpc.testing.EchoStatus response_status = 7;</code>
+     */
+    private $response_status = null;
+    /**
+     * <pre>
+     * Whether the server should expect this request to be compressed.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue expect_compressed = 8;</code>
+     */
+    private $expect_compressed = null;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * Desired payload type in the response from the server.
+     * If response_type is RANDOM, server randomly chooses one from other formats.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType response_type = 1;</code>
+     */
+    public function getResponseType()
+    {
+        return $this->response_type;
+    }
+
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * Desired payload type in the response from the server.
+     * If response_type is RANDOM, server randomly chooses one from other formats.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType response_type = 1;</code>
+     */
+    public function setResponseType($var)
+    {
+        GPBUtil::checkEnum($var, \Grpc\Testing\PayloadType::class);
+        $this->response_type = $var;
+    }
+
+    /**
+     * <pre>
+     * Desired payload size in the response from the server.
+     * </pre>
+     *
+     * <code>int32 response_size = 2;</code>
+     */
+    public function getResponseSize()
+    {
+        return $this->response_size;
+    }
+
+    /**
+     * <pre>
+     * Desired payload size in the response from the server.
+     * </pre>
+     *
+     * <code>int32 response_size = 2;</code>
+     */
+    public function setResponseSize($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->response_size = $var;
+    }
+
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 3;</code>
+     */
+    public function getPayload()
+    {
+        return $this->payload;
+    }
+
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 3;</code>
+     */
+    public function setPayload(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\Payload::class);
+        $this->payload = $var;
+    }
+
+    /**
+     * <pre>
+     * Whether SimpleResponse should include username.
+     * </pre>
+     *
+     * <code>bool fill_username = 4;</code>
+     */
+    public function getFillUsername()
+    {
+        return $this->fill_username;
+    }
+
+    /**
+     * <pre>
+     * Whether SimpleResponse should include username.
+     * </pre>
+     *
+     * <code>bool fill_username = 4;</code>
+     */
+    public function setFillUsername($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->fill_username = $var;
+    }
+
+    /**
+     * <pre>
+     * Whether SimpleResponse should include OAuth scope.
+     * </pre>
+     *
+     * <code>bool fill_oauth_scope = 5;</code>
+     */
+    public function getFillOauthScope()
+    {
+        return $this->fill_oauth_scope;
+    }
+
+    /**
+     * <pre>
+     * Whether SimpleResponse should include OAuth scope.
+     * </pre>
+     *
+     * <code>bool fill_oauth_scope = 5;</code>
+     */
+    public function setFillOauthScope($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->fill_oauth_scope = $var;
+    }
+
+    /**
+     * <pre>
+     * Whether to request the server to compress the response. This field is
+     * "nullable" in order to interoperate seamlessly with clients not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the response's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue response_compressed = 6;</code>
+     */
+    public function getResponseCompressed()
+    {
+        return $this->response_compressed;
+    }
+
+    /**
+     * <pre>
+     * Whether to request the server to compress the response. This field is
+     * "nullable" in order to interoperate seamlessly with clients not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the response's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue response_compressed = 6;</code>
+     */
+    public function setResponseCompressed(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\BoolValue::class);
+        $this->response_compressed = $var;
+    }
+
+    /**
+     * <pre>
+     * Whether server should return a given status
+     * </pre>
+     *
+     * <code>.grpc.testing.EchoStatus response_status = 7;</code>
+     */
+    public function getResponseStatus()
+    {
+        return $this->response_status;
+    }
+
+    /**
+     * <pre>
+     * Whether server should return a given status
+     * </pre>
+     *
+     * <code>.grpc.testing.EchoStatus response_status = 7;</code>
+     */
+    public function setResponseStatus(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\EchoStatus::class);
+        $this->response_status = $var;
+    }
+
+    /**
+     * <pre>
+     * Whether the server should expect this request to be compressed.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue expect_compressed = 8;</code>
+     */
+    public function getExpectCompressed()
+    {
+        return $this->expect_compressed;
+    }
+
+    /**
+     * <pre>
+     * Whether the server should expect this request to be compressed.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue expect_compressed = 8;</code>
+     */
+    public function setExpectCompressed(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\BoolValue::class);
+        $this->expect_compressed = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/SimpleResponse.php b/src/php/tests/qps/generated_code/Grpc/Testing/SimpleResponse.php
new file mode 100644
index 0000000000000000000000000000000000000000..ccc628ec4c0feb8ed1aa68c293f71b997cf556c0
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/SimpleResponse.php
@@ -0,0 +1,129 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Unary response, as configured by the request.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.SimpleResponse</code>
+ */
+class SimpleResponse extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Payload to increase message size.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    private $payload = null;
+    /**
+     * <pre>
+     * The user the request came from, for verifying authentication was
+     * successful when the client expected it.
+     * </pre>
+     *
+     * <code>string username = 2;</code>
+     */
+    private $username = '';
+    /**
+     * <pre>
+     * OAuth scope.
+     * </pre>
+     *
+     * <code>string oauth_scope = 3;</code>
+     */
+    private $oauth_scope = '';
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Payload to increase message size.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    public function getPayload()
+    {
+        return $this->payload;
+    }
+
+    /**
+     * <pre>
+     * Payload to increase message size.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    public function setPayload(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\Payload::class);
+        $this->payload = $var;
+    }
+
+    /**
+     * <pre>
+     * The user the request came from, for verifying authentication was
+     * successful when the client expected it.
+     * </pre>
+     *
+     * <code>string username = 2;</code>
+     */
+    public function getUsername()
+    {
+        return $this->username;
+    }
+
+    /**
+     * <pre>
+     * The user the request came from, for verifying authentication was
+     * successful when the client expected it.
+     * </pre>
+     *
+     * <code>string username = 2;</code>
+     */
+    public function setUsername($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->username = $var;
+    }
+
+    /**
+     * <pre>
+     * OAuth scope.
+     * </pre>
+     *
+     * <code>string oauth_scope = 3;</code>
+     */
+    public function getOauthScope()
+    {
+        return $this->oauth_scope;
+    }
+
+    /**
+     * <pre>
+     * OAuth scope.
+     * </pre>
+     *
+     * <code>string oauth_scope = 3;</code>
+     */
+    public function setOauthScope($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->oauth_scope = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/StreamingInputCallRequest.php b/src/php/tests/qps/generated_code/Grpc/Testing/StreamingInputCallRequest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d7bbc707799688e2fb4895b631bf95245dc6de93
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/StreamingInputCallRequest.php
@@ -0,0 +1,102 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Client-streaming request.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.StreamingInputCallRequest</code>
+ */
+class StreamingInputCallRequest extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    private $payload = null;
+    /**
+     * <pre>
+     * Whether the server should expect this request to be compressed. This field
+     * is "nullable" in order to interoperate seamlessly with servers not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the request's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue expect_compressed = 2;</code>
+     */
+    private $expect_compressed = null;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    public function getPayload()
+    {
+        return $this->payload;
+    }
+
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    public function setPayload(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\Payload::class);
+        $this->payload = $var;
+    }
+
+    /**
+     * <pre>
+     * Whether the server should expect this request to be compressed. This field
+     * is "nullable" in order to interoperate seamlessly with servers not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the request's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue expect_compressed = 2;</code>
+     */
+    public function getExpectCompressed()
+    {
+        return $this->expect_compressed;
+    }
+
+    /**
+     * <pre>
+     * Whether the server should expect this request to be compressed. This field
+     * is "nullable" in order to interoperate seamlessly with servers not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the request's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue expect_compressed = 2;</code>
+     */
+    public function setExpectCompressed(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\BoolValue::class);
+        $this->expect_compressed = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/StreamingInputCallResponse.php b/src/php/tests/qps/generated_code/Grpc/Testing/StreamingInputCallResponse.php
new file mode 100644
index 0000000000000000000000000000000000000000..fdd1d0dbf8a96953ee7d36c319f31def76266e32
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/StreamingInputCallResponse.php
@@ -0,0 +1,60 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Client-streaming response.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.StreamingInputCallResponse</code>
+ */
+class StreamingInputCallResponse extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Aggregated size of payloads received from the client.
+     * </pre>
+     *
+     * <code>int32 aggregated_payload_size = 1;</code>
+     */
+    private $aggregated_payload_size = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Aggregated size of payloads received from the client.
+     * </pre>
+     *
+     * <code>int32 aggregated_payload_size = 1;</code>
+     */
+    public function getAggregatedPayloadSize()
+    {
+        return $this->aggregated_payload_size;
+    }
+
+    /**
+     * <pre>
+     * Aggregated size of payloads received from the client.
+     * </pre>
+     *
+     * <code>int32 aggregated_payload_size = 1;</code>
+     */
+    public function setAggregatedPayloadSize($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->aggregated_payload_size = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/StreamingOutputCallRequest.php b/src/php/tests/qps/generated_code/Grpc/Testing/StreamingOutputCallRequest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2aab5fadad77ced2c3a3ef24d8af965978e8f430
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/StreamingOutputCallRequest.php
@@ -0,0 +1,171 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Server-streaming request.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.StreamingOutputCallRequest</code>
+ */
+class StreamingOutputCallRequest extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * Desired payload type in the response from the server.
+     * If response_type is RANDOM, the payload from each response in the stream
+     * might be of different types. This is to simulate a mixed type of payload
+     * stream.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType response_type = 1;</code>
+     */
+    private $response_type = 0;
+    /**
+     * <pre>
+     * Configuration for each expected response message.
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ResponseParameters response_parameters = 2;</code>
+     */
+    private $response_parameters;
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 3;</code>
+     */
+    private $payload = null;
+    /**
+     * <pre>
+     * Whether server should return a given status
+     * </pre>
+     *
+     * <code>.grpc.testing.EchoStatus response_status = 7;</code>
+     */
+    private $response_status = null;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * Desired payload type in the response from the server.
+     * If response_type is RANDOM, the payload from each response in the stream
+     * might be of different types. This is to simulate a mixed type of payload
+     * stream.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType response_type = 1;</code>
+     */
+    public function getResponseType()
+    {
+        return $this->response_type;
+    }
+
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * Desired payload type in the response from the server.
+     * If response_type is RANDOM, the payload from each response in the stream
+     * might be of different types. This is to simulate a mixed type of payload
+     * stream.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType response_type = 1;</code>
+     */
+    public function setResponseType($var)
+    {
+        GPBUtil::checkEnum($var, \Grpc\Testing\PayloadType::class);
+        $this->response_type = $var;
+    }
+
+    /**
+     * <pre>
+     * Configuration for each expected response message.
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ResponseParameters response_parameters = 2;</code>
+     */
+    public function getResponseParameters()
+    {
+        return $this->response_parameters;
+    }
+
+    /**
+     * <pre>
+     * Configuration for each expected response message.
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ResponseParameters response_parameters = 2;</code>
+     */
+    public function setResponseParameters(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Grpc\Testing\ResponseParameters::class);
+        $this->response_parameters = $var;
+    }
+
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 3;</code>
+     */
+    public function getPayload()
+    {
+        return $this->payload;
+    }
+
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 3;</code>
+     */
+    public function setPayload(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\Payload::class);
+        $this->payload = $var;
+    }
+
+    /**
+     * <pre>
+     * Whether server should return a given status
+     * </pre>
+     *
+     * <code>.grpc.testing.EchoStatus response_status = 7;</code>
+     */
+    public function getResponseStatus()
+    {
+        return $this->response_status;
+    }
+
+    /**
+     * <pre>
+     * Whether server should return a given status
+     * </pre>
+     *
+     * <code>.grpc.testing.EchoStatus response_status = 7;</code>
+     */
+    public function setResponseStatus(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\EchoStatus::class);
+        $this->response_status = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/StreamingOutputCallResponse.php b/src/php/tests/qps/generated_code/Grpc/Testing/StreamingOutputCallResponse.php
new file mode 100644
index 0000000000000000000000000000000000000000..c06c78c9d8ffb2b251339fd900e4644bf2c7e3f0
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/StreamingOutputCallResponse.php
@@ -0,0 +1,60 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Server-streaming response, as configured by the request and parameters.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.StreamingOutputCallResponse</code>
+ */
+class StreamingOutputCallResponse extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Payload to increase response size.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    private $payload = null;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Payload to increase response size.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    public function getPayload()
+    {
+        return $this->payload;
+    }
+
+    /**
+     * <pre>
+     * Payload to increase response size.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    public function setPayload(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\Payload::class);
+        $this->payload = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/Void.php b/src/php/tests/qps/generated_code/Grpc/Testing/Void.php
new file mode 100644
index 0000000000000000000000000000000000000000..38c100845a02b039048f7e9096d556f5e1b2b974
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/Void.php
@@ -0,0 +1,23 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.Void</code>
+ */
+class Void extends \Google\Protobuf\Internal\Message
+{
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/WorkerServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/WorkerServiceClient.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a68e41269e895eff4d105480785ec2e69a8177c
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/WorkerServiceClient.php
@@ -0,0 +1,111 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// 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.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+namespace Grpc\Testing {
+
+  class WorkerServiceClient extends \Grpc\BaseStub {
+
+    /**
+     * @param string $hostname hostname
+     * @param array $opts channel options
+     * @param Grpc\Channel $channel (optional) re-use channel object
+     */
+    public function __construct($hostname, $opts, $channel = null) {
+      parent::__construct($hostname, $opts, $channel);
+    }
+
+    /**
+     * Start server with specified workload.
+     * First request sent specifies the ServerConfig followed by ServerStatus
+     * response. After that, a "Mark" can be sent anytime to request the latest
+     * stats. Closing the stream will initiate shutdown of the test server
+     * and once the shutdown has finished, the OK status is sent to terminate
+     * this RPC.
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function RunServer($metadata = [], $options = []) {
+      return $this->_bidiRequest('/grpc.testing.WorkerService/RunServer',
+      ['\Grpc\Testing\ServerStatus','decode'],
+      $metadata, $options);
+    }
+
+    /**
+     * Start client with specified workload.
+     * First request sent specifies the ClientConfig followed by ClientStatus
+     * response. After that, a "Mark" can be sent anytime to request the latest
+     * stats. Closing the stream will initiate shutdown of the test client
+     * and once the shutdown has finished, the OK status is sent to terminate
+     * this RPC.
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function RunClient($metadata = [], $options = []) {
+      return $this->_bidiRequest('/grpc.testing.WorkerService/RunClient',
+      ['\Grpc\Testing\ClientStatus','decode'],
+      $metadata, $options);
+    }
+
+    /**
+     * Just return the core count - unary call
+     * @param \Grpc\Testing\CoreRequest $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function CoreCount(\Grpc\Testing\CoreRequest $argument,
+      $metadata = [], $options = []) {
+      return $this->_simpleRequest('/grpc.testing.WorkerService/CoreCount',
+      $argument,
+      ['\Grpc\Testing\CoreResponse', 'decode'],
+      $metadata, $options);
+    }
+
+    /**
+     * Quit this worker
+     * @param \Grpc\Testing\Void $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function QuitWorker(\Grpc\Testing\Void $argument,
+      $metadata = [], $options = []) {
+      return $this->_simpleRequest('/grpc.testing.WorkerService/QuitWorker',
+      $argument,
+      ['\Grpc\Testing\Void', 'decode'],
+      $metadata, $options);
+    }
+
+  }
+
+}
diff --git a/src/php/tests/unit_tests/ServerTest.php b/src/php/tests/unit_tests/ServerTest.php
index 5f40202f182d52f8f39291f5210e899e2d70bafc..3e7c01f20e2bd35440ba791692cfbcab8d866f1a 100644
--- a/src/php/tests/unit_tests/ServerTest.php
+++ b/src/php/tests/unit_tests/ServerTest.php
@@ -69,7 +69,7 @@ class ServerTest extends PHPUnit_Framework_TestCase
         $this->server = new Grpc\Server();
         $port = $this->server->addHttp2Port('0.0.0.0:0');
         $this->server->start();
-        $channel = new Grpc\Channel('localhost:' . $port,
+        $channel = new Grpc\Channel('localhost:'.$port,
              ['credentials' => Grpc\ChannelCredentials::createInsecure()]);
 
         $deadline = Grpc\Timeval::infFuture();
diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD
new file mode 100644
index 0000000000000000000000000000000000000000..dbb91d913926c60018abf01165c0e361d38ed296
--- /dev/null
+++ b/src/proto/grpc/health/v1/BUILD
@@ -0,0 +1,39 @@
+# Copyright 2017, 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.
+
+licenses(["notice"])  # 3-clause BSD
+
+package(default_visibility = ["//visibility:public"])
+
+load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
+
+grpc_proto_library(
+    name = "health_proto",
+    srcs = ["health.proto"],
+)
diff --git a/src/proto/grpc/lb/v1/BUILD b/src/proto/grpc/lb/v1/BUILD
new file mode 100644
index 0000000000000000000000000000000000000000..46d4f2d62c716074419183d92dccbfa12c151305
--- /dev/null
+++ b/src/proto/grpc/lb/v1/BUILD
@@ -0,0 +1,39 @@
+# Copyright 2017, 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.
+
+licenses(["notice"])  # 3-clause BSD
+
+package(default_visibility = ["//visibility:public"])
+
+load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
+
+grpc_proto_library(
+    name = "load_balancer_proto",
+    srcs = ["load_balancer.proto"],
+)
diff --git a/src/proto/grpc/lb/v1/load_balancer.proto b/src/proto/grpc/lb/v1/load_balancer.proto
index 44a5150a7e068d10adddf65149fda5bd3a6b14c7..a2502fb284a34070e9397a8e4e110d8505bb77a9 100644
--- a/src/proto/grpc/lb/v1/load_balancer.proto
+++ b/src/proto/grpc/lb/v1/load_balancer.proto
@@ -45,6 +45,20 @@ message Duration {
   int32 nanos = 2;
 }
 
+message Timestamp {
+
+  // Represents seconds of UTC time since Unix epoch
+  // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
+  // 9999-12-31T23:59:59Z inclusive.
+  int64 seconds = 1;
+
+  // Non-negative fractions of a second at nanosecond resolution. Negative
+  // second values with fractions must still have non-negative nanos values
+  // that count forward in time. Must be from 0 to 999,999,999
+  // inclusive.
+  int32 nanos = 2;
+}
+
 service LoadBalancer {
   // Bidirectional rpc to get a list of servers.
   rpc BalanceLoad(stream LoadBalanceRequest)
@@ -63,22 +77,37 @@ message LoadBalanceRequest {
 }
 
 message InitialLoadBalanceRequest {
-  // Name of load balanced service (IE, service.grpc.gslb.google.com). Its
+  // Name of load balanced service (IE, balancer.service.com)
   // length should be less than 256 bytes.
   string name = 1;
 }
 
 // Contains client level statistics that are useful to load balancing. Each
-// count should be reset to zero after reporting the stats.
+// count except the timestamp 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 timestamp of generating the report.
+  Timestamp timestamp = 1;
 
-  // The number of client rpc errors since the last report.
-  int64 client_rpc_errors = 2;
+  // The total number of RPCs that started.
+  int64 num_calls_started = 2;
 
-  // The number of dropped requests since the last report.
-  int64 dropped_requests = 3;
+  // The total number of RPCs that finished.
+  int64 num_calls_finished = 3;
+
+  // The total number of RPCs that were dropped by the client because of rate
+  // limiting.
+  int64 num_calls_finished_with_drop_for_rate_limiting = 4;
+
+  // The total number of RPCs that were dropped by the client because of load
+  // balancing.
+  int64 num_calls_finished_with_drop_for_load_balancing = 5;
+
+  // The total number of RPCs that failed to reach a server except dropped RPCs.
+  int64 num_calls_finished_with_client_failed_to_send = 6;
+
+  // The total number of RPCs that finished and are known to have been received
+  // by a server.
+  int64 num_calls_finished_known_received = 7;
 }
 
 message LoadBalanceResponse {
@@ -120,6 +149,10 @@ message ServerList {
   Duration expiration_interval = 3;
 }
 
+// Contains server information. When none of the [drop_for_*] fields are true,
+// use the other fields. When drop_for_rate_limiting is true, ignore all other
+// fields. Use drop_for_load_balancing only when it is true and
+// drop_for_rate_limiting is false.
 message Server {
   // A resolved address for the server, serialized in network-byte-order. It may
   // either be an IPv4 or IPv6 address.
@@ -137,6 +170,10 @@ message Server {
   string 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;
+  // for rate limiting.
+  bool drop_for_rate_limiting = 4;
+
+  // Indicates whether this particular request should be dropped by the client
+  // for load balancing.
+  bool drop_for_load_balancing = 5;
 }
diff --git a/examples/protos/BUILD b/src/proto/grpc/status/BUILD
similarity index 83%
rename from examples/protos/BUILD
rename to src/proto/grpc/status/BUILD
index 2ffdf64f9af540d48fbebd64581e11226af18421..71363bd1b639971ca50915e0d3d44351cb3fbd5f 100644
--- a/examples/protos/BUILD
+++ b/src/proto/grpc/status/BUILD
@@ -27,26 +27,15 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+licenses(["notice"])  # 3-clause BSD
+
 package(default_visibility = ["//visibility:public"])
 
 load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
 
 grpc_proto_library(
-    name = "auth_sample",
-    srcs = ["auth_sample.proto"],
-)
-
-grpc_proto_library(
-    name = "hellostreamingworld",
-    srcs = ["hellostreamingworld.proto"],
-)
-
-grpc_proto_library(
-    name = "helloworld",
-    srcs = ["helloworld.proto"],
-)
-
-grpc_proto_library(
-    name = "route_guide",
-    srcs = ["route_guide.proto"],
+    name = "status_proto",
+    srcs = ["status.proto"],
+    has_services = False,
+    well_known_protos = "@com_google_protobuf//:well_known_protos",
 )
diff --git a/src/proto/grpc/status/README b/src/proto/grpc/status/README
new file mode 100644
index 0000000000000000000000000000000000000000..34e588efac967046366a7886f6f87f8d29cb9179
--- /dev/null
+++ b/src/proto/grpc/status/README
@@ -0,0 +1,2 @@
+The status.proto file is copied from
+https://github.com/googleapis/googleapis/blob/master/google/rpc/status.proto.
diff --git a/src/proto/grpc/status/status.proto b/src/proto/grpc/status/status.proto
new file mode 100644
index 0000000000000000000000000000000000000000..bc6097b29fbdf1653d48d2861ac651b256bf628e
--- /dev/null
+++ b/src/proto/grpc/status/status.proto
@@ -0,0 +1,92 @@
+// Copyright 2016 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package google.rpc;
+
+import "google/protobuf/any.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/rpc/status;status";
+option java_multiple_files = true;
+option java_outer_classname = "StatusProto";
+option java_package = "com.google.rpc";
+option objc_class_prefix = "RPC";
+
+
+// The `Status` type defines a logical error model that is suitable for different
+// programming environments, including REST APIs and RPC APIs. It is used by
+// [gRPC](https://github.com/grpc). The error model is designed to be:
+//
+// - Simple to use and understand for most users
+// - Flexible enough to meet unexpected needs
+//
+// # Overview
+//
+// The `Status` message contains three pieces of data: error code, error message,
+// and error details. The error code should be an enum value of
+// [google.rpc.Code][google.rpc.Code], but it may accept additional error codes if needed.  The
+// error message should be a developer-facing English message that helps
+// developers *understand* and *resolve* the error. If a localized user-facing
+// error message is needed, put the localized message in the error details or
+// localize it in the client. The optional error details may contain arbitrary
+// information about the error. There is a predefined set of error detail types
+// in the package `google.rpc` which can be used for common error conditions.
+//
+// # Language mapping
+//
+// The `Status` message is the logical representation of the error model, but it
+// is not necessarily the actual wire format. When the `Status` message is
+// exposed in different client libraries and different wire protocols, it can be
+// mapped differently. For example, it will likely be mapped to some exceptions
+// in Java, but more likely mapped to some error codes in C.
+//
+// # Other uses
+//
+// The error model and the `Status` message can be used in a variety of
+// environments, either with or without APIs, to provide a
+// consistent developer experience across different environments.
+//
+// Example uses of this error model include:
+//
+// - Partial errors. If a service needs to return partial errors to the client,
+//     it may embed the `Status` in the normal response to indicate the partial
+//     errors.
+//
+// - Workflow errors. A typical workflow has multiple steps. Each step may
+//     have a `Status` message for error reporting purpose.
+//
+// - Batch operations. If a client uses batch request and batch response, the
+//     `Status` message should be used directly inside batch response, one for
+//     each error sub-response.
+//
+// - Asynchronous operations. If an API call embeds asynchronous operation
+//     results in its response, the status of those operations should be
+//     represented directly using the `Status` message.
+//
+// - Logging. If some API errors are stored in logs, the message `Status` could
+//     be used directly after any stripping needed for security/privacy reasons.
+message Status {
+  // The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].
+  int32 code = 1;
+
+  // A developer-facing error message, which should be in English. Any
+  // user-facing error message should be localized and sent in the
+  // [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.
+  string message = 2;
+
+  // A list of messages that carry the error details.  There will be a
+  // common set of message types for APIs to use.
+  repeated google.protobuf.Any details = 3;
+}
diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD
index 23a16a7cfc3ac35d2ef1f3f24bae2a8c9b5bd52a..805988c3372efe113333df9fdc326fdf106754b6 100644
--- a/src/proto/grpc/testing/BUILD
+++ b/src/proto/grpc/testing/BUILD
@@ -36,6 +36,7 @@ load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
 grpc_proto_library(
     name = "compiler_test_proto",
     srcs = ["compiler_test.proto"],
+    generate_mock = True,
 )
 
 grpc_proto_library(
@@ -55,6 +56,7 @@ grpc_proto_library(
     name = "echo_proto",
     srcs = ["echo.proto"],
     deps = ["echo_messages_proto"],
+    generate_mock = True,
 )
 
 grpc_proto_library(
@@ -83,7 +85,11 @@ grpc_proto_library(
 grpc_proto_library(
     name = "services_proto",
     srcs = ["services.proto"],
-    deps = ["control_proto", "messages_proto"],
+    deps = [
+        "control_proto",
+        "messages_proto",
+        "stats_proto",
+    ],
 )
 
 grpc_proto_library(
diff --git a/src/proto/grpc/testing/compiler_test.proto b/src/proto/grpc/testing/compiler_test.proto
index 085e8ae59f7933903f271686dc4c55cc51a8ce30..24735522e03c97c4211216495a96c46365f28e45 100644
--- a/src/proto/grpc/testing/compiler_test.proto
+++ b/src/proto/grpc/testing/compiler_test.proto
@@ -59,6 +59,14 @@ service ServiceA {
   // Method A2 leading comment 2
   rpc MethodA2(stream Request) returns (Response);
   // MethodA2 trailing comment 1
+
+  // Method A3 leading comment 1
+  rpc MethodA3(Request) returns (stream Response);
+  // Method A3 trailing comment 1
+
+  // Method A4 leading comment 1
+  rpc MethodA4(stream Request) returns (stream Response);
+  // Method A4 trailing comment 1
 }
 // Ignored ServiceA trailing comment 1
 
diff --git a/src/proto/grpc/testing/control.proto b/src/proto/grpc/testing/control.proto
index 8f0d25c2c96007360d5783973a63aab9e76c16ba..acee86678db2e34ac3612105b9da22ba5f30988c 100644
--- a/src/proto/grpc/testing/control.proto
+++ b/src/proto/grpc/testing/control.proto
@@ -113,6 +113,9 @@ message ClientConfig {
   string other_client_api = 15;
 
   repeated ChannelArg channel_args = 16;
+
+  // Number of messages on a stream before it gets finished/restarted
+  int32 messages_per_stream = 18;
 }
 
 message ClientStatus { ClientStats stats = 1; }
diff --git a/src/proto/grpc/testing/echo_messages.proto b/src/proto/grpc/testing/echo_messages.proto
index efb6f4d49350cf279614f6cb5b3a768df1a0f280..b82e80d8e34baebeae9a8d704272ca8f39032f8e 100644
--- a/src/proto/grpc/testing/echo_messages.proto
+++ b/src/proto/grpc/testing/echo_messages.proto
@@ -38,6 +38,13 @@ message DebugInfo {
   string detail = 2;
 }
 
+// Error status client expects to see.
+message ErrorStatus {
+  int32 code = 1;
+  string error_message = 2;
+  string binary_error_details = 3;
+}
+
 message RequestParams {
   bool echo_deadline = 1;
   int32 client_cancel_after_us = 2;
@@ -51,6 +58,8 @@ message RequestParams {
   string expected_transport_security_type = 10;
   DebugInfo debug_info = 11;
   bool server_die = 12; // Server should not see a request with this set.
+  string binary_error_details = 13;
+  ErrorStatus expected_error = 14;
 }
 
 message EchoRequest {
diff --git a/src/proto/grpc/testing/proxy-service.proto b/src/proto/grpc/testing/proxy-service.proto
new file mode 100644
index 0000000000000000000000000000000000000000..7b7de8d5494059969a054f168a260a30006ea3d6
--- /dev/null
+++ b/src/proto/grpc/testing/proxy-service.proto
@@ -0,0 +1,44 @@
+// Copyright 2017, 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";
+
+import "src/proto/grpc/testing/control.proto";
+
+package grpc.testing;
+
+message ProxyStat {
+  double latency = 1;
+}
+
+service ProxyClientService {
+  rpc GetConfig(Void) returns (ClientConfig);
+  rpc ReportTime(stream ProxyStat) returns (Void);
+}
+
diff --git a/src/proto/grpc/testing/services.proto b/src/proto/grpc/testing/services.proto
index f71dae34eedfbab7fc153bd0897948cc6e1fa1e5..969782d6561d773271c4a97d0fa40662d868ce84 100644
--- a/src/proto/grpc/testing/services.proto
+++ b/src/proto/grpc/testing/services.proto
@@ -33,6 +33,7 @@ syntax = "proto3";
 
 import "src/proto/grpc/testing/messages.proto";
 import "src/proto/grpc/testing/control.proto";
+import "src/proto/grpc/testing/stats.proto";
 
 package grpc.testing;
 
@@ -69,3 +70,8 @@ service WorkerService {
   // Quit this worker
   rpc QuitWorker(Void) returns (Void);
 }
+
+service ReportQpsScenarioService {
+  // Report results of a QPS test benchmark scenario.
+  rpc ReportScenario(ScenarioResult) returns (Void);
+}
diff --git a/src/python/grpcio/.gitignore b/src/python/grpcio/.gitignore
index 3309795948cd9027a72a80de7e27ca028e118e78..d0ee1e10fdd5ed33d66f297281a3a67686fdd3f4 100644
--- a/src/python/grpcio/.gitignore
+++ b/src/python/grpcio/.gitignore
@@ -11,7 +11,6 @@ dist/
 .cache/
 nosetests.xml
 doc/
-_grpcio_metadata.py
 htmlcov/
 grpc/_cython/_credentials
 poison.c
diff --git a/src/python/grpcio/README.rst b/src/python/grpcio/README.rst
index 3fc318539ea5d2000b8add8ebcd5ce8ad6cfb902..28a27145682e5f1df4d6311b376bcb003c6a86c2 100644
--- a/src/python/grpcio/README.rst
+++ b/src/python/grpcio/README.rst
@@ -6,7 +6,7 @@ Package for gRPC Python.
 Installation
 ------------
 
-gRPC Python is available for Linux, Mac OS X, and Windows running Python 2.7.
+gRPC Python is available for Linux, macOS, and Windows.
 
 From PyPI
 ~~~~~~~~~
diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py
index e50ccbe23e74a6633536067cee87eca35f9a229b..4f072809c4741a35599f12d90a069f2866f26ad9 100644
--- a/src/python/grpcio/commands.py
+++ b/src/python/grpcio/commands.py
@@ -260,12 +260,36 @@ class BuildExt(build_ext.build_ext):
     """Custom build_ext command to enable compiler-specific flags."""
 
     C_OPTIONS = {
-        'unix': ('-pthread', '-std=gnu99'),
+        'unix': ('-pthread',),
         'msvc': (),
     }
     LINK_OPTIONS = {}
 
     def build_extensions(self):
+        if "darwin" in sys.platform:
+            config = os.environ.get('CONFIG', 'opt')
+            target_path = os.path.abspath(
+                os.path.join(
+                    os.path.dirname(os.path.realpath(__file__)), '..', '..',
+                    '..', 'libs', config))
+            targets = [
+                os.path.join(target_path, 'libboringssl.a'),
+                os.path.join(target_path, 'libares.a'),
+                os.path.join(target_path, 'libgpr.a'),
+                os.path.join(target_path, 'libgrpc.a')
+            ]
+            make_process = subprocess.Popen(
+                ['make'] + targets,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.PIPE)
+            make_out, make_err = make_process.communicate()
+            if make_out and make_process.returncode != 0:
+                sys.stdout.write(make_out + '\n')
+            if make_err:
+                sys.stderr.write(make_err + '\n')
+            if make_process.returncode != 0:
+                raise Exception("make command failed!")
+
         compiler = self.compiler.compiler_type
         if compiler in BuildExt.C_OPTIONS:
             for extension in self.extensions:
diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py
index b64a708cc783777f8c833e764207e6a78eb288f0..4960df3be9fe48bac2fcbf4eebe8963429d88412 100644
--- a/src/python/grpcio/grpc/__init__.py
+++ b/src/python/grpcio/grpc/__init__.py
@@ -1004,7 +1004,7 @@ def unary_unary_rpc_method_handler(behavior,
     An RpcMethodHandler for a unary-unary RPC method constructed from the given
       parameters.
   """
-    from grpc import _utilities
+    from grpc import _utilities  # pylint: disable=cyclic-import
     return _utilities.RpcMethodHandler(False, False, request_deserializer,
                                        response_serializer, behavior, None,
                                        None, None)
@@ -1025,7 +1025,7 @@ def unary_stream_rpc_method_handler(behavior,
     An RpcMethodHandler for a unary-stream RPC method constructed from the
       given parameters.
   """
-    from grpc import _utilities
+    from grpc import _utilities  # pylint: disable=cyclic-import
     return _utilities.RpcMethodHandler(False, True, request_deserializer,
                                        response_serializer, None, behavior,
                                        None, None)
@@ -1046,7 +1046,7 @@ def stream_unary_rpc_method_handler(behavior,
     An RpcMethodHandler for a stream-unary RPC method constructed from the
       given parameters.
   """
-    from grpc import _utilities
+    from grpc import _utilities  # pylint: disable=cyclic-import
     return _utilities.RpcMethodHandler(True, False, request_deserializer,
                                        response_serializer, None, None,
                                        behavior, None)
@@ -1068,7 +1068,7 @@ def stream_stream_rpc_method_handler(behavior,
     An RpcMethodHandler for a stream-stream RPC method constructed from the
       given parameters.
   """
-    from grpc import _utilities
+    from grpc import _utilities  # pylint: disable=cyclic-import
     return _utilities.RpcMethodHandler(True, True, request_deserializer,
                                        response_serializer, None, None, None,
                                        behavior)
@@ -1085,7 +1085,7 @@ def method_handlers_generic_handler(service, method_handlers):
   Returns:
     A GenericRpcHandler constructed from the given parameters.
   """
-    from grpc import _utilities
+    from grpc import _utilities  # pylint: disable=cyclic-import
     return _utilities.DictionaryGenericHandler(service, method_handlers)
 
 
@@ -1124,7 +1124,7 @@ def metadata_call_credentials(metadata_plugin, name=None):
   Returns:
     A CallCredentials.
   """
-    from grpc import _plugin_wrapping
+    from grpc import _plugin_wrapping  # pylint: disable=cyclic-import
     if name is None:
         try:
             effective_name = metadata_plugin.__name__
@@ -1147,7 +1147,7 @@ def access_token_call_credentials(access_token):
   Returns:
     A CallCredentials.
   """
-    from grpc import _auth
+    from grpc import _auth  # pylint: disable=cyclic-import
     return metadata_call_credentials(
         _auth.AccessTokenCallCredentials(access_token))
 
@@ -1161,7 +1161,7 @@ def composite_call_credentials(*call_credentials):
   Returns:
     A CallCredentials object composed of the given CallCredentials objects.
   """
-    from grpc import _credential_composition
+    from grpc import _credential_composition  # pylint: disable=cyclic-import
     cygrpc_call_credentials = tuple(
         single_call_credentials._credentials
         for single_call_credentials in call_credentials)
@@ -1180,7 +1180,7 @@ def composite_channel_credentials(channel_credentials, *call_credentials):
     A ChannelCredentials composed of the given ChannelCredentials and
       CallCredentials objects.
   """
-    from grpc import _credential_composition
+    from grpc import _credential_composition  # pylint: disable=cyclic-import
     cygrpc_call_credentials = tuple(
         single_call_credentials._credentials
         for single_call_credentials in call_credentials)
@@ -1237,7 +1237,7 @@ def channel_ready_future(channel):
     A Future that matures when the given Channel has connectivity
       ChannelConnectivity.READY.
   """
-    from grpc import _utilities
+    from grpc import _utilities  # pylint: disable=cyclic-import
     return _utilities.channel_ready_future(channel)
 
 
@@ -1252,7 +1252,7 @@ def insecure_channel(target, options=None):
   Returns:
     A Channel to the target through which RPCs may be conducted.
   """
-    from grpc import _channel
+    from grpc import _channel  # pylint: disable=cyclic-import
     return _channel.Channel(target, () if options is None else options, None)
 
 
@@ -1268,12 +1268,15 @@ def secure_channel(target, credentials, options=None):
   Returns:
     A Channel to the target through which RPCs may be conducted.
   """
-    from grpc import _channel
+    from grpc import _channel  # pylint: disable=cyclic-import
     return _channel.Channel(target, () if options is None else options,
                             credentials._credentials)
 
 
-def server(thread_pool, handlers=None, options=None):
+def server(thread_pool,
+           handlers=None,
+           options=None,
+           maximum_concurrent_rpcs=None):
     """Creates a Server with which RPCs can be serviced.
 
   Args:
@@ -1286,13 +1289,17 @@ def server(thread_pool, handlers=None, options=None):
       returned Server is started.
     options: A sequence of string-value pairs according to which to configure
       the created server.
+    maximum_concurrent_rpcs: The maximum number of concurrent RPCs this server
+      will service before returning status RESOURCE_EXHAUSTED, or None to
+      indicate no limit.
 
   Returns:
     A Server with which RPCs can be serviced.
   """
-    from grpc import _server
+    from grpc import _server  # pylint: disable=cyclic-import
     return _server.Server(thread_pool, () if handlers is None else handlers, ()
-                          if options is None else options)
+                          if options is None else options,
+                          maximum_concurrent_rpcs)
 
 
 ###################################  __all__  #################################
diff --git a/src/python/grpcio/grpc/_auth.py b/src/python/grpcio/grpc/_auth.py
index 3e7250e85e456fe52164de25f25c5c1af6dad438..cb7c6fe4fda7d9a21238c6340496811beac5adb7 100644
--- a/src/python/grpcio/grpc/_auth.py
+++ b/src/python/grpcio/grpc/_auth.py
@@ -44,7 +44,7 @@ def _create_get_token_callback(callback):
     def get_token_callback(future):
         try:
             access_token = future.result().access_token
-        except Exception as exception:
+        except Exception as exception:  # pylint: disable=broad-except
             _sign_request(callback, None, exception)
         else:
             _sign_request(callback, access_token, None)
diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index 2480f9b174e293d2e03dfe754a6103c8652083d8..4316449ac65d4d701a070183bd061eaba4274ec4 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -200,7 +200,7 @@ def _consume_request_iterator(request_iterator, state, call,
                 request = next(request_iterator)
             except StopIteration:
                 break
-            except Exception:
+            except Exception:  # pylint: disable=broad-except
                 logging.exception("Exception iterating requests!")
                 call.cancel()
                 _abort(state, grpc.StatusCode.UNKNOWN,
@@ -237,7 +237,7 @@ def _consume_request_iterator(request_iterator, state, call,
                     cygrpc.Operations(operations), event_handler)
                 state.due.add(cygrpc.OperationType.send_close_from_client)
 
-    def stop_consumption_thread(timeout):
+    def stop_consumption_thread(timeout):  # pylint: disable=unused-argument
         with state.condition:
             if state.code is None:
                 call.cancel()
@@ -387,13 +387,14 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call):
         with self._state.condition:
             while self._state.initial_metadata is None:
                 self._state.condition.wait()
-            return _common.application_metadata(self._state.initial_metadata)
+            return _common.to_application_metadata(self._state.initial_metadata)
 
     def trailing_metadata(self):
         with self._state.condition:
             while self._state.trailing_metadata is None:
                 self._state.condition.wait()
-            return _common.application_metadata(self._state.trailing_metadata)
+            return _common.to_application_metadata(
+                self._state.trailing_metadata)
 
     def code(self):
         with self._state.condition:
@@ -473,7 +474,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
             state = _RPCState(_UNARY_UNARY_INITIAL_DUE, None, None, None, None)
             operations = (
                 cygrpc.operation_send_initial_metadata(
-                    _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
+                    _common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS),
                 cygrpc.operation_send_message(serialized_request, _EMPTY_FLAGS),
                 cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
                 cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
@@ -563,7 +564,7 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
                     )), event_handler)
                 operations = (
                     cygrpc.operation_send_initial_metadata(
-                        _common.cygrpc_metadata(metadata),
+                        _common.to_cygrpc_metadata(metadata),
                         _EMPTY_FLAGS), cygrpc.operation_send_message(
                             serialized_request, _EMPTY_FLAGS),
                     cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
@@ -603,7 +604,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
                 None)
             operations = (
                 cygrpc.operation_send_initial_metadata(
-                    _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
+                    _common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS),
                 cygrpc.operation_receive_message(_EMPTY_FLAGS),
                 cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
             call_error = call.start_client_batch(
@@ -657,7 +658,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
                 event_handler)
             operations = (
                 cygrpc.operation_send_initial_metadata(
-                    _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
+                    _common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS),
                 cygrpc.operation_receive_message(_EMPTY_FLAGS),
                 cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
             call_error = call.start_client_batch(
@@ -700,7 +701,7 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
                 event_handler)
             operations = (
                 cygrpc.operation_send_initial_metadata(
-                    _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
+                    _common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS),
                 cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
             call_error = call.start_client_batch(
                 cygrpc.Operations(operations), event_handler)
@@ -735,7 +736,7 @@ def _run_channel_spin_thread(state):
                         state.managed_calls = None
                         return
 
-    def stop_channel_spin(timeout):
+    def stop_channel_spin(timeout):  # pylint: disable=unused-argument
         with state.lock:
             if state.managed_calls is not None:
                 for call in state.managed_calls:
@@ -876,12 +877,8 @@ def _moot(state):
 def _subscribe(state, callback, try_to_connect):
     with state.lock:
         if not state.callbacks_and_connectivities and not state.polling:
-
-            def cancel_all_subscriptions(timeout):
-                _moot(state)
-
             polling_thread = _common.CleanupThread(
-                cancel_all_subscriptions,
+                lambda timeout: _moot(state),
                 target=_poll_connectivity,
                 args=(state, state.channel, bool(try_to_connect)))
             polling_thread.start()
diff --git a/src/python/grpcio/grpc/_common.py b/src/python/grpcio/grpc/_common.py
index 6879e1780baabfbe778a5d71973024c6c9bc2831..2e369013f5f8a65e6f9187462c4395e51dfc4614 100644
--- a/src/python/grpcio/grpc/_common.py
+++ b/src/python/grpcio/grpc/_common.py
@@ -97,22 +97,22 @@ def decode(b):
 
 
 def channel_args(options):
-    channel_args = []
+    cygrpc_args = []
     for key, value in options:
         if isinstance(value, six.string_types):
-            channel_args.append(cygrpc.ChannelArg(encode(key), encode(value)))
+            cygrpc_args.append(cygrpc.ChannelArg(encode(key), encode(value)))
         else:
-            channel_args.append(cygrpc.ChannelArg(encode(key), value))
-    return cygrpc.ChannelArgs(channel_args)
+            cygrpc_args.append(cygrpc.ChannelArg(encode(key), value))
+    return cygrpc.ChannelArgs(cygrpc_args)
 
 
-def cygrpc_metadata(application_metadata):
+def to_cygrpc_metadata(application_metadata):
     return EMPTY_METADATA if application_metadata is None else cygrpc.Metadata(
         cygrpc.Metadatum(encode(key), encode(value))
         for key, value in application_metadata)
 
 
-def application_metadata(cygrpc_metadata):
+def to_application_metadata(cygrpc_metadata):
     if cygrpc_metadata is None:
         return ()
     else:
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
index cc3bd7a067297a5fb26c94ce8fdb42e3305c7485..aa3558b8436bbf182bbe02f0885d98e93376f0ef 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
@@ -106,7 +106,7 @@ cdef class Call:
 
   def __dealloc__(self):
     if self.c_call != NULL:
-      grpc_call_destroy(self.c_call)
+      grpc_call_unref(self.c_call)
     grpc_shutdown()
 
   # The object *should* always be valid from Python. Used for debugging.
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 d8df6c2ef40a0ac94f13d60461c221c9e7ac67a4..502b6556b4ea3b063090b1c182f098e2c36ae02e 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
@@ -37,10 +37,17 @@ cdef int _INTERRUPT_CHECK_PERIOD_MS = 200
 
 cdef class CompletionQueue:
 
-  def __cinit__(self):
+  def __cinit__(self, shutdown_cq=False):
+    cdef grpc_completion_queue_attributes c_attrs
     grpc_init()
-    with nogil:
-      self.c_completion_queue = grpc_completion_queue_create(NULL)
+    if shutdown_cq:
+      c_attrs.version = 1
+      c_attrs.cq_completion_type = GRPC_CQ_NEXT
+      c_attrs.cq_polling_type = GRPC_CQ_NON_LISTENING
+      self.c_completion_queue = grpc_completion_queue_create(
+          grpc_completion_queue_factory_lookup(&c_attrs), &c_attrs, NULL);
+    else:
+      self.c_completion_queue = grpc_completion_queue_create_for_next(NULL)
     self.is_shutting_down = False
     self.is_shutdown = False
 
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
index bbd72424b9b43fc9f4912359d14af795e401c0aa..1db2056d476a70394eb5cb49f46307dc5d526158 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
@@ -217,6 +217,20 @@ cdef extern from "grpc/grpc.h":
     GRPC_CALL_ERROR_INVALID_FLAGS
     GRPC_CALL_ERROR_INVALID_METADATA
 
+  ctypedef enum grpc_cq_completion_type:
+    GRPC_CQ_NEXT
+    GRPC_CQ_PLUCK
+
+  ctypedef enum grpc_cq_polling_type:
+    GRPC_CQ_DEFAULT_POLLING
+    GRPC_CQ_NON_LISTENING
+    GRPC_CQ_NON_POLLING
+
+  ctypedef struct grpc_completion_queue_attributes:
+    int version
+    grpc_cq_completion_type cq_completion_type
+    grpc_cq_polling_type cq_polling_type
+
   ctypedef enum grpc_connectivity_state:
     GRPC_CHANNEL_IDLE
     GRPC_CHANNEL_CONNECTING
@@ -309,7 +323,16 @@ cdef extern from "grpc/grpc.h":
   void grpc_init() nogil
   void grpc_shutdown() nogil
 
-  grpc_completion_queue *grpc_completion_queue_create(void *reserved) nogil
+  ctypedef struct grpc_completion_queue_factory:
+    pass
+
+  grpc_completion_queue_factory *grpc_completion_queue_factory_lookup(
+      const grpc_completion_queue_attributes* attributes) nogil
+  grpc_completion_queue *grpc_completion_queue_create(
+    const grpc_completion_queue_factory* factory,
+    const grpc_completion_queue_attributes* attr, void* reserved) nogil
+  grpc_completion_queue *grpc_completion_queue_create_for_next(void *reserved) nogil
+
   grpc_event grpc_completion_queue_next(grpc_completion_queue *cq,
                                         gpr_timespec deadline,
                                         void *reserved) nogil
@@ -328,7 +351,7 @@ cdef extern from "grpc/grpc.h":
                                                const char *description,
                                                void *reserved) nogil
   char *grpc_call_get_peer(grpc_call *call) nogil
-  void grpc_call_destroy(grpc_call *call) nogil
+  void grpc_call_unref(grpc_call *call) nogil
 
   grpc_channel *grpc_insecure_channel_create(const char *target,
                                              const grpc_channel_args *args,
@@ -355,8 +378,6 @@ cdef extern from "grpc/grpc.h":
   void grpc_server_register_completion_queue(grpc_server *server,
                                              grpc_completion_queue *cq,
                                              void *reserved) nogil
-  void grpc_server_register_non_listening_completion_queue(
-      grpc_server *server, grpc_completion_queue *cq, void *reserved) nogil
   int grpc_server_add_insecure_http2_port(
       grpc_server *server, const char *addr) nogil
   void grpc_server_start(grpc_server *server) nogil
@@ -501,4 +522,3 @@ cdef extern from "grpc/compression.h":
   int grpc_compression_options_is_algorithm_enabled(
       const grpc_compression_options *opts,
       grpc_compression_algorithm algorithm) nogil
-
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/security.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/security.pxd.pxi
index 3a952ca309aa9c40ed3d089b97b9ad9226d4b50a..9915b0ed1abbad943f580203a829ae776b4a0f7f 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/security.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/security.pxd.pxi
@@ -29,4 +29,4 @@
 
 
 cdef grpc_ssl_roots_override_result ssl_roots_override_callback(
-    char **pem_root_certs) with gil
+    char **pem_root_certs) nogil
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/security.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/security.pyx.pxi
index 20fc1c5fce78560ee055a8eef7cadcb481304279..357b0330d5ce7c9295f74d298dbed33c8de79c4d 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/security.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/security.pyx.pxi
@@ -33,12 +33,14 @@ import pkg_resources
 
 
 cdef grpc_ssl_roots_override_result ssl_roots_override_callback(
-    char **pem_root_certs) with gil:
-  temporary_pem_root_certs = pkg_resources.resource_string(
-      __name__.rstrip('.cygrpc'), '_credentials/roots.pem')
-  pem_root_certs[0] = <char *>gpr_malloc(len(temporary_pem_root_certs) + 1)
-  memcpy(
-      pem_root_certs[0], <char *>temporary_pem_root_certs,
-      len(temporary_pem_root_certs))
-  pem_root_certs[0][len(temporary_pem_root_certs)] = '\0'
+    char **pem_root_certs) nogil:
+  with gil:
+    temporary_pem_root_certs = pkg_resources.resource_string(
+        __name__.rstrip('.cygrpc'), '_credentials/roots.pem')
+    pem_root_certs[0] = <char *>gpr_malloc(len(temporary_pem_root_certs) + 1)
+    memcpy(
+        pem_root_certs[0], <char *>temporary_pem_root_certs,
+        len(temporary_pem_root_certs))
+    pem_root_certs[0][len(temporary_pem_root_certs)] = '\0'
+
   return GRPC_SSL_ROOTS_OVERRIDE_OK
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
index 18db38b68610c096e4c08326082770bc7b8f35d3..5233edc7895cb134e9400fe30c07a4d3aa520a50 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
@@ -82,20 +82,11 @@ cdef class Server:
           self.c_server, queue.c_completion_queue, NULL)
     self.registered_completion_queues.append(queue)
 
-  def register_non_listening_completion_queue(
-      self, CompletionQueue queue not None):
-    if self.is_started:
-      raise ValueError("cannot register completion queues after start")
-    with nogil:
-      grpc_server_register_non_listening_completion_queue(
-          self.c_server, queue.c_completion_queue, NULL)
-    self.registered_completion_queues.append(queue)
-
   def start(self):
     if self.is_started:
       raise ValueError("the server has already started")
-    self.backup_shutdown_queue = CompletionQueue()
-    self.register_non_listening_completion_queue(self.backup_shutdown_queue)
+    self.backup_shutdown_queue = CompletionQueue(shutdown_cq=True)
+    self.register_completion_queue(self.backup_shutdown_queue)
     self.is_started = True
     with nogil:
       grpc_server_start(self.c_server)
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx
index e1bd046a1a5e72035b5c5efc05defc583bfd6bf1..274b5f1b8ac2cd26ad3a2553689b3a957050ef3c 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pyx
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx
@@ -47,14 +47,14 @@ include "_cygrpc/server.pyx.pxi"
 #
 # initialize gRPC
 #
-
-
 cdef extern from "Python.h":
 
-  int Py_AtExit(void(*func)())
-
+  int PyEval_InitThreads()
 
-def _initialize():
+cdef _initialize():
+  # We have Python callbacks called by c-core threads, this ensures the GIL
+  # is initialized.
+  PyEval_InitThreads()
   grpc_set_ssl_roots_override_callback(
           <grpc_ssl_roots_override_callback>ssl_roots_override_callback)
 
diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py
new file mode 100644
index 0000000000000000000000000000000000000000..a0cb0dd067f1eb68790e1908a17cf257fae609c3
--- /dev/null
+++ b/src/python/grpcio/grpc/_grpcio_metadata.py
@@ -0,0 +1,32 @@
+# Copyright 2017, 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.
+
+# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!!
+
+__version__ = """1.4.0.dev0"""
diff --git a/src/python/grpcio/grpc/_plugin_wrapping.py b/src/python/grpcio/grpc/_plugin_wrapping.py
index 69c46aa546cfe0715e4ab6358ba888f81dcc6e82..1e44561c97b4b5297baa43803a69fc144f20e8a9 100644
--- a/src/python/grpcio/grpc/_plugin_wrapping.py
+++ b/src/python/grpcio/grpc/_plugin_wrapping.py
@@ -66,9 +66,9 @@ class _WrappedCygrpcCallback(object):
 
     def _invoke_success(self, metadata):
         try:
-            cygrpc_metadata = _common.cygrpc_metadata(metadata)
-        except Exception as error:
-            self._invoke_failure(error)
+            cygrpc_metadata = _common.to_cygrpc_metadata(metadata)
+        except Exception as exception:  # pylint: disable=broad-except
+            self._invoke_failure(exception)
             return
         self.cygrpc_callback(cygrpc_metadata, cygrpc.StatusCode.ok, b'')
 
diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py
index 8dc956a374951e96ee6cc05347f1df0e9c89c1e5..f29c44a4cfd3e35b9dfbc01b08f2cfe882423172 100644
--- a/src/python/grpcio/grpc/_server.py
+++ b/src/python/grpcio/grpc/_server.py
@@ -142,14 +142,14 @@ def _abort(state, call, code, details):
         effective_details = details if state.details is None else state.details
         if state.initial_metadata_allowed:
             operations = (cygrpc.operation_send_initial_metadata(
-                _common.EMPTY_METADATA, _EMPTY_FLAGS),
-                          cygrpc.operation_send_status_from_server(
-                              _common.cygrpc_metadata(state.trailing_metadata),
-                              effective_code, effective_details, _EMPTY_FLAGS),)
+                _common.EMPTY_METADATA,
+                _EMPTY_FLAGS), cygrpc.operation_send_status_from_server(
+                    _common.to_cygrpc_metadata(state.trailing_metadata),
+                    effective_code, effective_details, _EMPTY_FLAGS),)
             token = _SEND_INITIAL_METADATA_AND_SEND_STATUS_FROM_SERVER_TOKEN
         else:
             operations = (cygrpc.operation_send_status_from_server(
-                _common.cygrpc_metadata(state.trailing_metadata),
+                _common.to_cygrpc_metadata(state.trailing_metadata),
                 effective_code, effective_details, _EMPTY_FLAGS),)
             token = _SEND_STATUS_FROM_SERVER_TOKEN
         call.start_server_batch(
@@ -250,7 +250,7 @@ class _Context(grpc.ServicerContext):
             self._state.disable_next_compression = True
 
     def invocation_metadata(self):
-        return _common.application_metadata(self._rpc_event.request_metadata)
+        return _common.to_application_metadata(self._rpc_event.request_metadata)
 
     def peer(self):
         return _common.decode(self._rpc_event.operation_call.peer())
@@ -262,7 +262,8 @@ class _Context(grpc.ServicerContext):
             else:
                 if self._state.initial_metadata_allowed:
                     operation = cygrpc.operation_send_initial_metadata(
-                        _common.cygrpc_metadata(initial_metadata), _EMPTY_FLAGS)
+                        _common.to_cygrpc_metadata(initial_metadata),
+                        _EMPTY_FLAGS)
                     self._rpc_event.operation_call.start_server_batch(
                         cygrpc.Operations((operation,)),
                         _send_initial_metadata(self._state))
@@ -273,7 +274,7 @@ class _Context(grpc.ServicerContext):
 
     def set_trailing_metadata(self, trailing_metadata):
         with self._state.condition:
-            self._state.trailing_metadata = _common.cygrpc_metadata(
+            self._state.trailing_metadata = _common.to_cygrpc_metadata(
                 trailing_metadata)
 
     def set_code(self, code):
@@ -436,7 +437,8 @@ def _send_response(rpc_event, state, serialized_response):
 def _status(rpc_event, state, serialized_response):
     with state.condition:
         if state.client is not _CANCELLED:
-            trailing_metadata = _common.cygrpc_metadata(state.trailing_metadata)
+            trailing_metadata = _common.to_cygrpc_metadata(
+                state.trailing_metadata)
             code = _completion_code(state)
             details = _details(state)
             operations = [
@@ -502,37 +504,37 @@ def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk,
 def _handle_unary_unary(rpc_event, state, method_handler, thread_pool):
     unary_request = _unary_request(rpc_event, state,
                                    method_handler.request_deserializer)
-    thread_pool.submit(_unary_response_in_pool, rpc_event, state,
-                       method_handler.unary_unary, unary_request,
-                       method_handler.request_deserializer,
-                       method_handler.response_serializer)
+    return thread_pool.submit(_unary_response_in_pool, rpc_event, state,
+                              method_handler.unary_unary, unary_request,
+                              method_handler.request_deserializer,
+                              method_handler.response_serializer)
 
 
 def _handle_unary_stream(rpc_event, state, method_handler, thread_pool):
     unary_request = _unary_request(rpc_event, state,
                                    method_handler.request_deserializer)
-    thread_pool.submit(_stream_response_in_pool, rpc_event, state,
-                       method_handler.unary_stream, unary_request,
-                       method_handler.request_deserializer,
-                       method_handler.response_serializer)
+    return thread_pool.submit(_stream_response_in_pool, rpc_event, state,
+                              method_handler.unary_stream, unary_request,
+                              method_handler.request_deserializer,
+                              method_handler.response_serializer)
 
 
 def _handle_stream_unary(rpc_event, state, method_handler, thread_pool):
     request_iterator = _RequestIterator(state, rpc_event.operation_call,
                                         method_handler.request_deserializer)
-    thread_pool.submit(_unary_response_in_pool, rpc_event, state,
-                       method_handler.stream_unary, lambda: request_iterator,
-                       method_handler.request_deserializer,
-                       method_handler.response_serializer)
+    return thread_pool.submit(
+        _unary_response_in_pool, rpc_event, state, method_handler.stream_unary,
+        lambda: request_iterator, method_handler.request_deserializer,
+        method_handler.response_serializer)
 
 
 def _handle_stream_stream(rpc_event, state, method_handler, thread_pool):
     request_iterator = _RequestIterator(state, rpc_event.operation_call,
                                         method_handler.request_deserializer)
-    thread_pool.submit(_stream_response_in_pool, rpc_event, state,
-                       method_handler.stream_stream, lambda: request_iterator,
-                       method_handler.request_deserializer,
-                       method_handler.response_serializer)
+    return thread_pool.submit(
+        _stream_response_in_pool, rpc_event, state,
+        method_handler.stream_stream, lambda: request_iterator,
+        method_handler.request_deserializer, method_handler.response_serializer)
 
 
 def _find_method_handler(rpc_event, generic_handlers):
@@ -547,13 +549,12 @@ def _find_method_handler(rpc_event, generic_handlers):
         return None
 
 
-def _handle_unrecognized_method(rpc_event):
+def _reject_rpc(rpc_event, status, details):
     operations = (cygrpc.operation_send_initial_metadata(_common.EMPTY_METADATA,
                                                          _EMPTY_FLAGS),
                   cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
                   cygrpc.operation_send_status_from_server(
-                      _common.EMPTY_METADATA, cygrpc.StatusCode.unimplemented,
-                      b'Method not found!', _EMPTY_FLAGS),)
+                      _common.EMPTY_METADATA, status, details, _EMPTY_FLAGS),)
     rpc_state = _RPCState()
     rpc_event.operation_call.start_server_batch(
         operations, lambda ignored_event: (rpc_state, (),))
@@ -570,33 +571,37 @@ def _handle_with_method_handler(rpc_event, method_handler, thread_pool):
         state.due.add(_RECEIVE_CLOSE_ON_SERVER_TOKEN)
         if method_handler.request_streaming:
             if method_handler.response_streaming:
-                _handle_stream_stream(rpc_event, state, method_handler,
-                                      thread_pool)
+                return state, _handle_stream_stream(rpc_event, state,
+                                                    method_handler, thread_pool)
             else:
-                _handle_stream_unary(rpc_event, state, method_handler,
-                                     thread_pool)
+                return state, _handle_stream_unary(rpc_event, state,
+                                                   method_handler, thread_pool)
         else:
             if method_handler.response_streaming:
-                _handle_unary_stream(rpc_event, state, method_handler,
-                                     thread_pool)
+                return state, _handle_unary_stream(rpc_event, state,
+                                                   method_handler, thread_pool)
             else:
-                _handle_unary_unary(rpc_event, state, method_handler,
-                                    thread_pool)
-        return state
+                return state, _handle_unary_unary(rpc_event, state,
+                                                  method_handler, thread_pool)
 
 
-def _handle_call(rpc_event, generic_handlers, thread_pool):
+def _handle_call(rpc_event, generic_handlers, thread_pool,
+                 concurrency_exceeded):
     if not rpc_event.success:
-        return None
+        return None, None
     if rpc_event.request_call_details.method is not None:
         method_handler = _find_method_handler(rpc_event, generic_handlers)
         if method_handler is None:
-            return _handle_unrecognized_method(rpc_event)
+            return _reject_rpc(rpc_event, cygrpc.StatusCode.unimplemented,
+                               b'Method not found!'), None
+        elif concurrency_exceeded:
+            return _reject_rpc(rpc_event, cygrpc.StatusCode.resource_exhausted,
+                               b'Concurrent RPC limit exceeded!'), None
         else:
             return _handle_with_method_handler(rpc_event, method_handler,
                                                thread_pool)
     else:
-        return None
+        return None, None
 
 
 @enum.unique
@@ -608,7 +613,8 @@ class _ServerStage(enum.Enum):
 
 class _ServerState(object):
 
-    def __init__(self, completion_queue, server, generic_handlers, thread_pool):
+    def __init__(self, completion_queue, server, generic_handlers, thread_pool,
+                 maximum_concurrent_rpcs):
         self.lock = threading.Lock()
         self.completion_queue = completion_queue
         self.server = server
@@ -616,6 +622,8 @@ class _ServerState(object):
         self.thread_pool = thread_pool
         self.stage = _ServerStage.STOPPED
         self.shutdown_events = None
+        self.maximum_concurrent_rpcs = maximum_concurrent_rpcs
+        self.active_rpc_count = 0
 
         # TODO(https://github.com/grpc/grpc/issues/6597): eliminate these fields.
         self.rpc_states = set()
@@ -655,6 +663,11 @@ def _stop_serving(state):
         return False
 
 
+def _on_call_completed(state):
+    with state.lock:
+        state.active_rpc_count -= 1
+
+
 def _serve(state):
     while True:
         event = state.completion_queue.poll()
@@ -666,10 +679,18 @@ def _serve(state):
         elif event.tag is _REQUEST_CALL_TAG:
             with state.lock:
                 state.due.remove(_REQUEST_CALL_TAG)
-                rpc_state = _handle_call(event, state.generic_handlers,
-                                         state.thread_pool)
+                concurrency_exceeded = (
+                    state.maximum_concurrent_rpcs is not None and
+                    state.active_rpc_count >= state.maximum_concurrent_rpcs)
+                rpc_state, rpc_future = _handle_call(
+                    event, state.generic_handlers, state.thread_pool,
+                    concurrency_exceeded)
                 if rpc_state is not None:
                     state.rpc_states.add(rpc_state)
+                if rpc_future is not None:
+                    state.active_rpc_count += 1
+                    rpc_future.add_done_callback(
+                        lambda unused_future: _on_call_completed(state))
                 if state.stage is _ServerStage.STARTED:
                     _request_call(state)
                 elif _stop_serving(state):
@@ -684,6 +705,10 @@ def _serve(state):
                     state.rpc_states.remove(rpc_state)
                     if _stop_serving(state):
                         return
+        # We want to force the deletion of the previous event
+        # ~before~ we poll again; if the event has a reference
+        # to a shutdown Call object, this can induce spinlock.
+        event = None
 
 
 def _stop(state, grace):
@@ -747,12 +772,13 @@ def _start(state):
 
 class Server(grpc.Server):
 
-    def __init__(self, thread_pool, generic_handlers, options):
+    def __init__(self, thread_pool, generic_handlers, options,
+                 maximum_concurrent_rpcs):
         completion_queue = cygrpc.CompletionQueue()
         server = cygrpc.Server(_common.channel_args(options))
         server.register_completion_queue(completion_queue)
         self._state = _ServerState(completion_queue, server, generic_handlers,
-                                   thread_pool)
+                                   thread_pool, maximum_concurrent_rpcs)
 
     def add_generic_rpc_handlers(self, generic_rpc_handlers):
         _add_generic_handlers(self._state, generic_rpc_handlers)
diff --git a/src/python/grpcio/grpc/beta/_client_adaptations.py b/src/python/grpcio/grpc/beta/_client_adaptations.py
index a8f2bf7642af93ea594cdb660a6da4cf9b28e6c0..3c69acc019527857c64aba97c8c6f64290eac59c 100644
--- a/src/python/grpcio/grpc/beta/_client_adaptations.py
+++ b/src/python/grpcio/grpc/beta/_client_adaptations.py
@@ -35,6 +35,8 @@ from grpc.framework.common import cardinality
 from grpc.framework.foundation import future
 from grpc.framework.interfaces.face import face
 
+# pylint: disable=too-many-arguments,too-many-locals,unused-argument
+
 _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS = {
     grpc.StatusCode.CANCELLED: (face.Abortion.Kind.CANCELLED,
                                 face.CancellationError),
@@ -620,8 +622,8 @@ class _GenericStub(face.GenericStub):
 
 class _DynamicStub(face.DynamicStub):
 
-    def __init__(self, generic_stub, group, cardinalities):
-        self._generic_stub = generic_stub
+    def __init__(self, backing_generic_stub, group, cardinalities):
+        self._generic_stub = backing_generic_stub
         self._group = group
         self._cardinalities = cardinalities
 
diff --git a/src/python/grpcio/grpc/beta/_server_adaptations.py b/src/python/grpcio/grpc/beta/_server_adaptations.py
index 174af2d642275ca5668f8ae542d715fbc001e94e..cf10c26d2fe0aa906e02f50ce0d360606c388d4b 100644
--- a/src/python/grpcio/grpc/beta/_server_adaptations.py
+++ b/src/python/grpcio/grpc/beta/_server_adaptations.py
@@ -41,6 +41,8 @@ from grpc.framework.foundation import logging_pool
 from grpc.framework.foundation import stream
 from grpc.framework.interfaces.face import face
 
+# pylint: disable=too-many-return-statements
+
 _DEFAULT_POOL_SIZE = 8
 
 
@@ -78,7 +80,7 @@ class _FaceServicerContext(face.ServicerContext):
         return _ServerProtocolContext(self._servicer_context)
 
     def invocation_metadata(self):
-        return _common.cygrpc_metadata(
+        return _common.to_cygrpc_metadata(
             self._servicer_context.invocation_metadata())
 
     def initial_metadata(self, initial_metadata):
@@ -179,7 +181,7 @@ def _run_request_pipe_thread(request_iterator, request_consumer,
                 return
         request_consumer.terminate()
 
-    def stop_request_pipe(timeout):
+    def stop_request_pipe(timeout):  # pylint: disable=unused-argument
         thread_joined.set()
 
     request_pipe_thread = _common.CleanupThread(
@@ -351,27 +353,27 @@ class _GenericRpcHandler(grpc.GenericRpcHandler):
 
 class _Server(interfaces.Server):
 
-    def __init__(self, server):
-        self._server = server
+    def __init__(self, grpc_server):
+        self._grpc_server = grpc_server
 
     def add_insecure_port(self, address):
-        return self._server.add_insecure_port(address)
+        return self._grpc_server.add_insecure_port(address)
 
     def add_secure_port(self, address, server_credentials):
-        return self._server.add_secure_port(address, server_credentials)
+        return self._grpc_server.add_secure_port(address, server_credentials)
 
     def start(self):
-        self._server.start()
+        self._grpc_server.start()
 
     def stop(self, grace):
-        return self._server.stop(grace)
+        return self._grpc_server.stop(grace)
 
     def __enter__(self):
-        self._server.start()
+        self._grpc_server.start()
         return self
 
     def __exit__(self, exc_type, exc_val, exc_tb):
-        self._server.stop(None)
+        self._grpc_server.stop(None)
         return False
 
 
diff --git a/src/python/grpcio/grpc/beta/implementations.py b/src/python/grpcio/grpc/beta/implementations.py
index af31e38a5453c2f0548f8f31530f4c013b1e64e0..113fd38f8a6e4fae9bf138ae2bcf48e1fd82a488 100644
--- a/src/python/grpcio/grpc/beta/implementations.py
+++ b/src/python/grpcio/grpc/beta/implementations.py
@@ -41,6 +41,8 @@ from grpc.beta import interfaces  # pylint: disable=unused-import
 from grpc.framework.common import cardinality  # pylint: disable=unused-import
 from grpc.framework.interfaces.face import face  # pylint: disable=unused-import
 
+# pylint: disable=too-many-arguments
+
 ChannelCredentials = grpc.ChannelCredentials
 ssl_channel_credentials = grpc.ssl_channel_credentials
 CallCredentials = grpc.CallCredentials
@@ -217,7 +219,7 @@ def dynamic_stub(channel, service, cardinalities, options=None):
   Returns:
     A face.DynamicStub with which RPCs can be invoked.
   """
-    effective_options = StubOptions() if options is None else options
+    effective_options = _EMPTY_STUB_OPTIONS if options is None else options
     return _client_adaptations.dynamic_stub(
         channel._channel,  # pylint: disable=protected-access
         service,
diff --git a/src/python/grpcio/grpc/framework/interfaces/base/base.py b/src/python/grpcio/grpc/framework/interfaces/base/base.py
index cb3328296c5b57ce002b2d347e0d39b20de358af..aa80e65f57ade5b1c66367508a0b99beb655e591 100644
--- a/src/python/grpcio/grpc/framework/interfaces/base/base.py
+++ b/src/python/grpcio/grpc/framework/interfaces/base/base.py
@@ -46,26 +46,29 @@ import six
 # abandonment is referenced from specification in this module.
 from grpc.framework.foundation import abandonment  # pylint: disable=unused-import
 
+# pylint: disable=too-many-arguments
+
 
 class NoSuchMethodError(Exception):
     """Indicates that an unrecognized operation has been called.
 
-  Attributes:
-    code: A code value to communicate to the other side of the operation along
-      with indication of operation termination. May be None.
-    details: A details value to communicate to the other side of the operation
-      along with indication of operation termination. May be None.
-  """
-
-    def __init__(self, code, details):
-        """Constructor.
-
-    Args:
+    Attributes:
       code: A code value to communicate to the other side of the operation
         along with indication of operation termination. May be None.
       details: A details value to communicate to the other side of the
         operation along with indication of operation termination. May be None.
     """
+
+    def __init__(self, code, details):
+        """Constructor.
+
+        Args:
+          code: A code value to communicate to the other side of the operation
+            along with indication of operation termination. May be None.
+          details: A details value to communicate to the other side of the
+            operation along with indication of operation termination. May be None.
+        """
+        super(NoSuchMethodError, self).__init__()
         self.code = code
         self.details = details
 
diff --git a/src/python/grpcio/grpc/framework/interfaces/face/face.py b/src/python/grpcio/grpc/framework/interfaces/face/face.py
index 6c7e2a3af6a1e6c2ed33e539e9e1b950f2ee14bb..c6c44fe4e4ccb83981015cf63acc96e38e0a1975 100644
--- a/src/python/grpcio/grpc/framework/interfaces/face/face.py
+++ b/src/python/grpcio/grpc/framework/interfaces/face/face.py
@@ -42,6 +42,8 @@ from grpc.framework.foundation import abandonment  # pylint: disable=unused-impo
 from grpc.framework.foundation import future  # pylint: disable=unused-import
 from grpc.framework.foundation import stream  # pylint: disable=unused-import
 
+# pylint: disable=too-many-arguments
+
 
 class NoSuchMethodError(Exception):
     """Raised by customer code to indicate an unrecognized method.
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index a9f20e6d2a88654e327d2a8903f8de81c2c53b0f..42c13b2cb63664cf7731cc1bd56d119055d279b9 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -33,6 +33,8 @@ CORE_SOURCE_FILES = [
   'src/core/lib/profiling/basic_timers.c',
   'src/core/lib/profiling/stap_timers.c',
   'src/core/lib/support/alloc.c',
+  'src/core/lib/support/arena.c',
+  'src/core/lib/support/atm.c',
   'src/core/lib/support/avl.c',
   'src/core/lib/support/backoff.c',
   'src/core/lib/support/cmdline.c',
@@ -78,15 +80,10 @@ CORE_SOURCE_FILES = [
   'src/core/lib/channel/channel_args.c',
   'src/core/lib/channel/channel_stack.c',
   'src/core/lib/channel/channel_stack_builder.c',
-  'src/core/lib/channel/compress_filter.c',
   'src/core/lib/channel/connected_channel.c',
-  'src/core/lib/channel/deadline_filter.c',
   'src/core/lib/channel/handshaker.c',
   'src/core/lib/channel/handshaker_factory.c',
   'src/core/lib/channel/handshaker_registry.c',
-  'src/core/lib/channel/http_client_filter.c',
-  'src/core/lib/channel/http_server_filter.c',
-  'src/core/lib/channel/message_size_filter.c',
   'src/core/lib/compression/compression.c',
   'src/core/lib/compression/message_compress.c',
   'src/core/lib/debug/trace.c',
@@ -111,6 +108,7 @@ CORE_SOURCE_FILES = [
   'src/core/lib/iomgr/iomgr_uv.c',
   'src/core/lib/iomgr/iomgr_windows.c',
   'src/core/lib/iomgr/load_file.c',
+  'src/core/lib/iomgr/lockfree_event.c',
   'src/core/lib/iomgr/network_status_tracker.c',
   'src/core/lib/iomgr/polling_entity.c',
   'src/core/lib/iomgr/pollset_set_uv.c',
@@ -122,6 +120,7 @@ CORE_SOURCE_FILES = [
   'src/core/lib/iomgr/resolve_address_windows.c',
   'src/core/lib/iomgr/resource_quota.c',
   'src/core/lib/iomgr/sockaddr_utils.c',
+  'src/core/lib/iomgr/socket_factory_posix.c',
   'src/core/lib/iomgr/socket_mutator.c',
   'src/core/lib/iomgr/socket_utils_common_posix.c',
   'src/core/lib/iomgr/socket_utils_linux.c',
@@ -134,6 +133,9 @@ CORE_SOURCE_FILES = [
   'src/core/lib/iomgr/tcp_client_windows.c',
   'src/core/lib/iomgr/tcp_posix.c',
   'src/core/lib/iomgr/tcp_server_posix.c',
+  'src/core/lib/iomgr/tcp_server_utils_posix_common.c',
+  'src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c',
+  'src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c',
   'src/core/lib/iomgr/tcp_server_uv.c',
   'src/core/lib/iomgr/tcp_server_windows.c',
   'src/core/lib/iomgr/tcp_uv.c',
@@ -156,6 +158,7 @@ CORE_SOURCE_FILES = [
   'src/core/lib/json/json_reader.c',
   'src/core/lib/json/json_string.c',
   'src/core/lib/json/json_writer.c',
+  'src/core/lib/slice/b64.c',
   'src/core/lib/slice/percent_encoding.c',
   'src/core/lib/slice/slice.c',
   'src/core/lib/slice/slice_buffer.c',
@@ -174,8 +177,9 @@ CORE_SOURCE_FILES = [
   'src/core/lib/surface/channel_ping.c',
   'src/core/lib/surface/channel_stack_type.c',
   'src/core/lib/surface/completion_queue.c',
+  'src/core/lib/surface/completion_queue_factory.c',
   'src/core/lib/surface/event_string.c',
-  'src/core/lib/surface/lame_client.c',
+  'src/core/lib/surface/lame_client.cc',
   'src/core/lib/surface/metadata_array.c',
   'src/core/lib/surface/server.c',
   'src/core/lib/surface/validate_metadata.c',
@@ -207,6 +211,7 @@ CORE_SOURCE_FILES = [
   'src/core/ext/transport/chttp2/transport/hpack_encoder.c',
   'src/core/ext/transport/chttp2/transport/hpack_parser.c',
   'src/core/ext/transport/chttp2/transport/hpack_table.c',
+  'src/core/ext/transport/chttp2/transport/http2_settings.c',
   'src/core/ext/transport/chttp2/transport/huffsyms.c',
   'src/core/ext/transport/chttp2/transport/incoming_metadata.c',
   'src/core/ext/transport/chttp2/transport/parsing.c',
@@ -215,6 +220,10 @@ CORE_SOURCE_FILES = [
   'src/core/ext/transport/chttp2/transport/varint.c',
   'src/core/ext/transport/chttp2/transport/writing.c',
   'src/core/ext/transport/chttp2/alpn/alpn.c',
+  'src/core/ext/filters/http/client/http_client_filter.c',
+  'src/core/ext/filters/http/http_filters_plugin.c',
+  'src/core/ext/filters/http/message_compress/message_compress_filter.c',
+  'src/core/ext/filters/http/server/http_server_filter.c',
   'src/core/lib/http/httpcli_security_connector.c',
   'src/core/lib/security/context/security_context.c',
   'src/core/lib/security/credentials/composite/composite_credentials.c',
@@ -237,53 +246,58 @@ CORE_SOURCE_FILES = [
   'src/core/lib/security/transport/security_handshaker.c',
   'src/core/lib/security/transport/server_auth_filter.c',
   'src/core/lib/security/transport/tsi_error.c',
-  'src/core/lib/security/util/b64.c',
   'src/core/lib/security/util/json_util.c',
   'src/core/lib/surface/init_secure.c',
-  'src/core/lib/tsi/fake_transport_security.c',
-  'src/core/lib/tsi/ssl_transport_security.c',
-  'src/core/lib/tsi/transport_security.c',
+  'src/core/tsi/fake_transport_security.c',
+  'src/core/tsi/ssl_transport_security.c',
+  'src/core/tsi/transport_security.c',
+  'src/core/tsi/transport_security_adapter.c',
   'src/core/ext/transport/chttp2/server/chttp2_server.c',
   'src/core/ext/transport/chttp2/client/secure/secure_channel_create.c',
-  'src/core/ext/client_channel/channel_connectivity.c',
-  'src/core/ext/client_channel/client_channel.c',
-  'src/core/ext/client_channel/client_channel_factory.c',
-  'src/core/ext/client_channel/client_channel_plugin.c',
-  'src/core/ext/client_channel/connector.c',
-  'src/core/ext/client_channel/default_initial_connect_string.c',
-  'src/core/ext/client_channel/http_connect_handshaker.c',
-  'src/core/ext/client_channel/http_proxy.c',
-  'src/core/ext/client_channel/initial_connect_string.c',
-  'src/core/ext/client_channel/lb_policy.c',
-  'src/core/ext/client_channel/lb_policy_factory.c',
-  'src/core/ext/client_channel/lb_policy_registry.c',
-  'src/core/ext/client_channel/parse_address.c',
-  'src/core/ext/client_channel/proxy_mapper.c',
-  'src/core/ext/client_channel/proxy_mapper_registry.c',
-  'src/core/ext/client_channel/resolver.c',
-  'src/core/ext/client_channel/resolver_factory.c',
-  'src/core/ext/client_channel/resolver_registry.c',
-  'src/core/ext/client_channel/subchannel.c',
-  'src/core/ext/client_channel/subchannel_index.c',
-  'src/core/ext/client_channel/uri_parser.c',
+  'src/core/ext/filters/client_channel/channel_connectivity.c',
+  'src/core/ext/filters/client_channel/client_channel.c',
+  'src/core/ext/filters/client_channel/client_channel_factory.c',
+  'src/core/ext/filters/client_channel/client_channel_plugin.c',
+  'src/core/ext/filters/client_channel/connector.c',
+  'src/core/ext/filters/client_channel/http_connect_handshaker.c',
+  'src/core/ext/filters/client_channel/http_proxy.c',
+  'src/core/ext/filters/client_channel/lb_policy.c',
+  'src/core/ext/filters/client_channel/lb_policy_factory.c',
+  'src/core/ext/filters/client_channel/lb_policy_registry.c',
+  'src/core/ext/filters/client_channel/parse_address.c',
+  'src/core/ext/filters/client_channel/proxy_mapper.c',
+  'src/core/ext/filters/client_channel/proxy_mapper_registry.c',
+  'src/core/ext/filters/client_channel/resolver.c',
+  'src/core/ext/filters/client_channel/resolver_factory.c',
+  'src/core/ext/filters/client_channel/resolver_registry.c',
+  'src/core/ext/filters/client_channel/retry_throttle.c',
+  'src/core/ext/filters/client_channel/subchannel.c',
+  'src/core/ext/filters/client_channel/subchannel_index.c',
+  'src/core/ext/filters/client_channel/uri_parser.c',
+  'src/core/ext/filters/deadline/deadline_filter.c',
   'src/core/ext/transport/chttp2/client/chttp2_connector.c',
   'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
   'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c',
   'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
   'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c',
-  'src/core/ext/lb_policy/grpclb/grpclb.c',
-  'src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c',
-  'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
-  'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
+  'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c',
+  'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c',
+  'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c',
+  'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c',
+  'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c',
+  'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
   'third_party/nanopb/pb_common.c',
   'third_party/nanopb/pb_decode.c',
   'third_party/nanopb/pb_encode.c',
-  'src/core/ext/lb_policy/pick_first/pick_first.c',
-  'src/core/ext/lb_policy/round_robin/round_robin.c',
-  'src/core/ext/resolver/dns/native/dns_resolver.c',
-  'src/core/ext/resolver/sockaddr/sockaddr_resolver.c',
-  'src/core/ext/load_reporting/load_reporting.c',
-  'src/core/ext/load_reporting/load_reporting_filter.c',
+  'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c',
+  'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c',
+  'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c',
+  'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c',
+  'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c',
+  'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c',
+  'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c',
+  'src/core/ext/filters/load_reporting/load_reporting.c',
+  'src/core/ext/filters/load_reporting/load_reporting_filter.c',
   'src/core/ext/census/base_resources.c',
   'src/core/ext/census/context.c',
   'src/core/ext/census/gen/census.pb.c',
@@ -298,6 +312,8 @@ CORE_SOURCE_FILES = [
   'src/core/ext/census/resource.c',
   'src/core/ext/census/trace_context.c',
   'src/core/ext/census/tracing.c',
+  'src/core/ext/filters/max_age/max_age_filter.c',
+  'src/core/ext/filters/message_size/message_size_filter.c',
   'src/core/plugin_registry/grpc_plugin_registry.c',
   'src/boringssl/err_data.c',
   'third_party/boringssl/crypto/aes/aes.c',
@@ -618,4 +634,53 @@ CORE_SOURCE_FILES = [
   'third_party/zlib/trees.c',
   'third_party/zlib/uncompr.c',
   'third_party/zlib/zutil.c',
+  'third_party/cares/cares/ares__close_sockets.c',
+  'third_party/cares/cares/ares__get_hostent.c',
+  'third_party/cares/cares/ares__read_line.c',
+  'third_party/cares/cares/ares__timeval.c',
+  'third_party/cares/cares/ares_cancel.c',
+  'third_party/cares/cares/ares_create_query.c',
+  'third_party/cares/cares/ares_data.c',
+  'third_party/cares/cares/ares_destroy.c',
+  'third_party/cares/cares/ares_expand_name.c',
+  'third_party/cares/cares/ares_expand_string.c',
+  'third_party/cares/cares/ares_fds.c',
+  'third_party/cares/cares/ares_free_hostent.c',
+  'third_party/cares/cares/ares_free_string.c',
+  'third_party/cares/cares/ares_getenv.c',
+  'third_party/cares/cares/ares_gethostbyaddr.c',
+  'third_party/cares/cares/ares_gethostbyname.c',
+  'third_party/cares/cares/ares_getnameinfo.c',
+  'third_party/cares/cares/ares_getopt.c',
+  'third_party/cares/cares/ares_getsock.c',
+  'third_party/cares/cares/ares_init.c',
+  'third_party/cares/cares/ares_library_init.c',
+  'third_party/cares/cares/ares_llist.c',
+  'third_party/cares/cares/ares_mkquery.c',
+  'third_party/cares/cares/ares_nowarn.c',
+  'third_party/cares/cares/ares_options.c',
+  'third_party/cares/cares/ares_parse_a_reply.c',
+  'third_party/cares/cares/ares_parse_aaaa_reply.c',
+  'third_party/cares/cares/ares_parse_mx_reply.c',
+  'third_party/cares/cares/ares_parse_naptr_reply.c',
+  'third_party/cares/cares/ares_parse_ns_reply.c',
+  'third_party/cares/cares/ares_parse_ptr_reply.c',
+  'third_party/cares/cares/ares_parse_soa_reply.c',
+  'third_party/cares/cares/ares_parse_srv_reply.c',
+  'third_party/cares/cares/ares_parse_txt_reply.c',
+  'third_party/cares/cares/ares_platform.c',
+  'third_party/cares/cares/ares_process.c',
+  'third_party/cares/cares/ares_query.c',
+  'third_party/cares/cares/ares_search.c',
+  'third_party/cares/cares/ares_send.c',
+  'third_party/cares/cares/ares_strcasecmp.c',
+  'third_party/cares/cares/ares_strdup.c',
+  'third_party/cares/cares/ares_strerror.c',
+  'third_party/cares/cares/ares_timeout.c',
+  'third_party/cares/cares/ares_version.c',
+  'third_party/cares/cares/ares_writev.c',
+  'third_party/cares/cares/bitncmp.c',
+  'third_party/cares/cares/inet_net_pton.c',
+  'third_party/cares/cares/inet_ntop.c',
+  'third_party/cares/cares/windows_port.c',
 ]
diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py
index c197e92ca58174a5b54921a9b7e7592f44f1234e..ea4bc7ba207d856818fc418a43d8488245d5f1f4 100644
--- a/src/python/grpcio/grpc_version.py
+++ b/src/python/grpcio/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!!
 
-VERSION='1.2.0.dev0'
+VERSION='1.4.0.dev0'
diff --git a/src/python/grpcio_health_checking/grpc_health/v1/health.py b/src/python/grpcio_health_checking/grpc_health/v1/health.py
index f0f11cf84b01194afad61d8b88b036d4d90ba878..e92c2659b7e4a5af51b127f6c0437f4e5f36e895 100644
--- a/src/python/grpcio_health_checking/grpc_health/v1/health.py
+++ b/src/python/grpcio_health_checking/grpc_health/v1/health.py
@@ -33,9 +33,10 @@ import threading
 import grpc
 
 from grpc_health.v1 import health_pb2
+from grpc_health.v1 import health_pb2_grpc
 
 
-class HealthServicer(health_pb2.HealthServicer):
+class HealthServicer(health_pb2_grpc.HealthServicer):
     """Servicer handling RPCs for service statuses."""
 
     def __init__(self):
diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py
index c1807e9f1c2820c1273c07105da1c1ec6a801992..26aa555e14cf9b2257214624a9f3bcb83c77a668 100644
--- a/src/python/grpcio_health_checking/grpc_version.py
+++ b/src/python/grpcio_health_checking/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
 
-VERSION='1.2.0.dev0'
+VERSION='1.4.0.dev0'
diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py
index 072c3263c6e9b0cd74a0b148ed852c47c24c1cc7..1806d311b47658b9a6a3496f78741b00e7c08d6b 100644
--- a/src/python/grpcio_health_checking/setup.py
+++ b/src/python/grpcio_health_checking/setup.py
@@ -29,7 +29,6 @@
 """Setup module for the GRPC Python package's optional health checking."""
 
 import os
-import sys
 
 import setuptools
 
@@ -47,7 +46,7 @@ PACKAGE_DIRECTORIES = {
 SETUP_REQUIRES = (
     'grpcio-tools>={version}'.format(version=grpc_version.VERSION),)
 
-INSTALL_REQUIRES = ('protobuf>=3.0.0',
+INSTALL_REQUIRES = ('protobuf>=3.2.0',
                     'grpcio>={version}'.format(version=grpc_version.VERSION),)
 
 COMMAND_CLASS = {
@@ -59,6 +58,10 @@ COMMAND_CLASS = {
 setuptools.setup(
     name='grpcio-health-checking',
     version=grpc_version.VERSION,
+    description='Standard Health Checking Service for gRPC',
+    author='The gRPC Authors',
+    author_email='grpc-io@googlegroups.com',
+    url='http://www.grpc.io',
     license='3-clause BSD',
     package_dir=PACKAGE_DIRECTORIES,
     packages=setuptools.find_packages('.'),
diff --git a/src/python/grpcio_reflection/MANIFEST.in b/src/python/grpcio_reflection/MANIFEST.in
new file mode 100644
index 0000000000000000000000000000000000000000..0f2130c0b58f1b8b932f52e2983dbdf0f6d279ff
--- /dev/null
+++ b/src/python/grpcio_reflection/MANIFEST.in
@@ -0,0 +1,4 @@
+include grpc_version.py
+include reflection_commands.py
+graft grpc_reflection
+global-exclude *.pyc
diff --git a/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py b/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py
index 87f28396ce222e680ae110de59c4b2e4d9ff7fb0..cd896f32c3cdece9bba26882cce5229728c7c3b5 100644
--- a/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py
+++ b/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py
@@ -35,6 +35,7 @@ from google.protobuf import descriptor_pb2
 from google.protobuf import descriptor_pool
 
 from grpc_reflection.v1alpha import reflection_pb2
+from grpc_reflection.v1alpha import reflection_pb2_grpc
 
 _POOL = descriptor_pool.Default()
 
@@ -55,7 +56,7 @@ def _file_descriptor_response(descriptor):
             file_descriptor_proto=(serialized_proto,)),)
 
 
-class ReflectionServicer(reflection_pb2.ServerReflectionServicer):
+class ReflectionServicer(reflection_pb2_grpc.ServerReflectionServicer):
     """Servicer handling RPCs for service statuses."""
 
     def __init__(self, service_names, pool=None):
@@ -64,7 +65,7 @@ class ReflectionServicer(reflection_pb2.ServerReflectionServicer):
     Args:
       service_names: Iterable of fully-qualified service names available.
     """
-        self._service_names = list(service_names)
+        self._service_names = tuple(sorted(service_names))
         self._pool = _POOL if pool is None else pool
 
     def _file_by_filename(self, filename):
@@ -84,23 +85,32 @@ class ReflectionServicer(reflection_pb2.ServerReflectionServicer):
         else:
             return _file_descriptor_response(descriptor)
 
-    def _file_containing_extension(containing_type, extension_number):
-        # TODO(atash) Python protobuf currently doesn't support querying extensions.
-        # https://github.com/google/protobuf/issues/2248
-        return reflection_pb2.ServerReflectionResponse(
-            error_response=reflection_pb2.ErrorResponse(
-                error_code=grpc.StatusCode.UNIMPLEMENTED.value[0],
-                error_message=grpc.StatusCode.UNIMPLMENTED.value[1].encode(),))
-
-    def _extension_numbers_of_type(fully_qualified_name):
-        # TODO(atash) We're allowed to leave this unsupported according to the
-        # protocol, but we should still eventually implement it. Hits the same issue
-        # as `_file_containing_extension`, however.
-        # https://github.com/google/protobuf/issues/2248
-        return reflection_pb2.ServerReflectionResponse(
-            error_response=reflection_pb2.ErrorResponse(
-                error_code=grpc.StatusCode.UNIMPLEMENTED.value[0],
-                error_message=grpc.StatusCode.UNIMPLMENTED.value[1].encode(),))
+    def _file_containing_extension(self, containing_type, extension_number):
+        try:
+            message_descriptor = self._pool.FindMessageTypeByName(containing_type)
+            extension_descriptor = self._pool.FindExtensionByNumber(
+                message_descriptor, extension_number)
+            descriptor = self._pool.FindFileContainingSymbol(
+                extension_descriptor.full_name)
+        except KeyError:
+            return _not_found_error()
+        else:
+            return _file_descriptor_response(descriptor)
+
+    def _all_extension_numbers_of_type(self, containing_type):
+        try:
+            message_descriptor = self._pool.FindMessageTypeByName(containing_type)
+            extension_numbers = tuple(sorted(
+                extension.number
+                for extension in self._pool.FindAllExtensions(message_descriptor)))
+        except KeyError:
+            return _not_found_error()
+        else:
+            return reflection_pb2.ServerReflectionResponse(
+                all_extension_numbers_response=reflection_pb2.
+                ExtensionNumberResponse(
+                    base_type_name=message_descriptor.full_name,
+                    extension_number=extension_numbers))
 
     def _list_services(self):
         return reflection_pb2.ServerReflectionResponse(
@@ -121,7 +131,7 @@ class ReflectionServicer(reflection_pb2.ServerReflectionServicer):
                     request.file_containing_extension.containing_type,
                     request.file_containing_extension.extension_number)
             elif request.HasField('all_extension_numbers_of_type'):
-                yield _all_extension_numbers_of_type(
+                yield self._all_extension_numbers_of_type(
                     request.all_extension_numbers_of_type)
             elif request.HasField('list_services'):
                 yield self._list_services()
@@ -131,3 +141,15 @@ class ReflectionServicer(reflection_pb2.ServerReflectionServicer):
                         error_code=grpc.StatusCode.INVALID_ARGUMENT.value[0],
                         error_message=grpc.StatusCode.INVALID_ARGUMENT.value[1]
                         .encode(),))
+
+
+def enable_server_reflection(service_names, server, pool=None):
+    """Enables server reflection on a server.
+
+    Args:
+      service_names: Iterable of fully-qualified service names available.
+      server: grpc.Server to which reflection service will be added.
+      pool: DescriptorPool object to use (descriptor_pool.Default() if None).
+    """
+    reflection_pb2_grpc.add_ServerReflectionServicer_to_server(
+        ReflectionServicer(service_names), server, pool)
diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py
index 3778dcd3e0b26bc64cdae7d6d3484eb1307de299..978d6b4011f76ac41a5d3f17bb88c6680acb30dc 100644
--- a/src/python/grpcio_reflection/grpc_version.py
+++ b/src/python/grpcio_reflection/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!!
 
-VERSION='1.2.0.dev0'
+VERSION='1.4.0.dev0'
diff --git a/src/python/grpcio_reflection/setup.py b/src/python/grpcio_reflection/setup.py
index 19aafe443a9a8202697341bea8b81718f00279e7..e6cf54745e2d945f492bad31c25f55e215577029 100644
--- a/src/python/grpcio_reflection/setup.py
+++ b/src/python/grpcio_reflection/setup.py
@@ -47,7 +47,7 @@ PACKAGE_DIRECTORIES = {
 SETUP_REQUIRES = (
     'grpcio-tools>={version}'.format(version=grpc_version.VERSION),)
 
-INSTALL_REQUIRES = ('protobuf>=3.0.0',
+INSTALL_REQUIRES = ('protobuf>=3.2.0',
                     'grpcio>={version}'.format(version=grpc_version.VERSION),)
 
 COMMAND_CLASS = {
@@ -60,6 +60,10 @@ setuptools.setup(
     name='grpcio-reflection',
     version=grpc_version.VERSION,
     license='3-clause BSD',
+    description='Standard Protobuf Reflection Service for gRPC',
+    author='The gRPC Authors',
+    author_email='grpc-io@googlegroups.com',
+    url='http://www.grpc.io',
     package_dir=PACKAGE_DIRECTORIES,
     packages=setuptools.find_packages('.'),
     install_requires=INSTALL_REQUIRES,
diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py
index 33824b6b8fcb0d7dfead9787936b2435940d3cd8..5f0b084884649fea2bd4d0fee6d92d6bdda4e9c5 100644
--- a/src/python/grpcio_tests/grpc_version.py
+++ b/src/python/grpcio_tests/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!!
 
-VERSION='1.2.0.dev0'
+VERSION='1.4.0.dev0'
diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py
index b0c73fc575b4dc426561116a6021258e96e0e63e..b9f0264dae3a29eb025a6bc4ba301b0156e3ef8c 100644
--- a/src/python/grpcio_tests/setup.py
+++ b/src/python/grpcio_tests/setup.py
@@ -56,7 +56,7 @@ INSTALL_REQUIRES = (
     'grpcio>={version}'.format(version=grpc_version.VERSION),
     'grpcio-tools>={version}'.format(version=grpc_version.VERSION),
     'grpcio-health-checking>={version}'.format(version=grpc_version.VERSION),
-    'oauth2client>=1.4.7', 'protobuf>=3.0.0', 'six>=1.10',)
+    'oauth2client>=1.4.7', 'protobuf>=3.2.0', 'six>=1.10',)
 
 COMMAND_CLASS = {
     # Run `preprocess` *before* doing any packaging!
diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py
index 363b4c5f994799a66afe9f27917299e36eb1ca1b..1bc8669dad99ec9788678be815850be091d4673b 100644
--- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py
+++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py
@@ -34,6 +34,7 @@ import grpc
 from grpc.framework.foundation import logging_pool
 from grpc_health.v1 import health
 from grpc_health.v1 import health_pb2
+from grpc_health.v1 import health_pb2_grpc
 
 from tests.unit.framework.common import test_constants
 
@@ -52,11 +53,11 @@ class HealthServicerTest(unittest.TestCase):
         server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
         self._server = grpc.server(server_pool)
         port = self._server.add_insecure_port('[::]:0')
-        health_pb2.add_HealthServicer_to_server(servicer, self._server)
+        health_pb2_grpc.add_HealthServicer_to_server(servicer, self._server)
         self._server.start()
 
         channel = grpc.insecure_channel('localhost:%d' % port)
-        self._stub = health_pb2.HealthStub(channel)
+        self._stub = health_pb2_grpc.HealthStub(channel)
 
     def test_empty_service(self):
         request = health_pb2.HealthCheckRequest()
diff --git a/src/python/grpcio_tests/tests/http2/negative_http2_client.py b/src/python/grpcio_tests/tests/http2/negative_http2_client.py
index b184e62cfd4cfb2c95500108a8a34f6f920809f3..90f54e80bbf3571d32179d982bc98bfad1a6c813 100644
--- a/src/python/grpcio_tests/tests/http2/negative_http2_client.py
+++ b/src/python/grpcio_tests/tests/http2/negative_http2_client.py
@@ -96,8 +96,6 @@ def _rst_during_data(stub):
 
 def _rst_after_data(stub):
     resp_future = stub.UnaryCall.future(_SIMPLE_REQUEST)
-    _validate_payload_type_and_length(
-        next(resp_future), messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
     _validate_status_code_and_details(resp_future, grpc.StatusCode.INTERNAL,
                                       "Received RST_STREAM with error code 0")
 
diff --git a/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py b/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py
index 58f3b364bad336b05d449416b8510041fcf9e308..3325d54375a3a0635ad2fd74e8d4f5b381a4eb2f 100644
--- a/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py
+++ b/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py
@@ -32,7 +32,7 @@ from concurrent import futures
 import unittest
 
 import grpc
-from src.proto.grpc.testing import test_pb2
+from src.proto.grpc.testing import test_pb2_grpc
 
 from tests.interop import _intraop_test_case
 from tests.interop import methods
@@ -44,11 +44,11 @@ class InsecureIntraopTest(_intraop_test_case.IntraopTestCase,
 
     def setUp(self):
         self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
-        test_pb2.add_TestServiceServicer_to_server(methods.TestService(),
-                                                   self.server)
+        test_pb2_grpc.add_TestServiceServicer_to_server(methods.TestService(),
+                                                        self.server)
         port = self.server.add_insecure_port('[::]:0')
         self.server.start()
-        self.stub = test_pb2.TestServiceStub(
+        self.stub = test_pb2_grpc.TestServiceStub(
             grpc.insecure_channel('localhost:{}'.format(port)))
 
 
diff --git a/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py b/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py
index 5fe929b99edf6b859dd530a090851c18c82a50cb..857e00efb3a052bd569dcc68b008ffd8e260e7bc 100644
--- a/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py
+++ b/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py
@@ -32,7 +32,7 @@ from concurrent import futures
 import unittest
 
 import grpc
-from src.proto.grpc.testing import test_pb2
+from src.proto.grpc.testing import test_pb2_grpc
 
 from tests.interop import _intraop_test_case
 from tests.interop import methods
@@ -45,14 +45,14 @@ class SecureIntraopTest(_intraop_test_case.IntraopTestCase, unittest.TestCase):
 
     def setUp(self):
         self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
-        test_pb2.add_TestServiceServicer_to_server(methods.TestService(),
-                                                   self.server)
+        test_pb2_grpc.add_TestServiceServicer_to_server(methods.TestService(),
+                                                        self.server)
         port = self.server.add_secure_port(
             '[::]:0',
             grpc.ssl_server_credentials(
                 [(resources.private_key(), resources.certificate_chain())]))
         self.server.start()
-        self.stub = test_pb2.TestServiceStub(
+        self.stub = test_pb2_grpc.TestServiceStub(
             grpc.secure_channel('localhost:{}'.format(port),
                                 grpc.ssl_channel_credentials(
                                     resources.test_root_certificates()), (
diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py
index 662ea9ce570078b39a9c2760cda298f2711d78b4..e1016f7c0d5b803717b297023210a462de2b8fec 100644
--- a/src/python/grpcio_tests/tests/interop/methods.py
+++ b/src/python/grpcio_tests/tests/interop/methods.py
@@ -40,7 +40,7 @@ from grpc.beta import implementations
 
 from src.proto.grpc.testing import empty_pb2
 from src.proto.grpc.testing import messages_pb2
-from src.proto.grpc.testing import test_pb2
+from src.proto.grpc.testing import test_pb2_grpc
 
 _INITIAL_METADATA_KEY = "x-grpc-test-echo-initial"
 _TRAILING_METADATA_KEY = "x-grpc-test-echo-trailing-bin"
@@ -66,7 +66,7 @@ def _maybe_echo_status_and_message(request, servicer_context):
         servicer_context.set_details(request.response_status.message)
 
 
-class TestService(test_pb2.TestServiceServicer):
+class TestService(test_pb2_grpc.TestServiceServicer):
 
     def EmptyCall(self, request, context):
         _maybe_echo_metadata(context)
diff --git a/src/python/grpcio_tests/tests/interop/server.py b/src/python/grpcio_tests/tests/interop/server.py
index 65f1604eb8239c47642d08a3c3044064a816e250..0ae2c97b4278502eb96f16f89a4ad376cdedd85d 100644
--- a/src/python/grpcio_tests/tests/interop/server.py
+++ b/src/python/grpcio_tests/tests/interop/server.py
@@ -34,7 +34,7 @@ import logging
 import time
 
 import grpc
-from src.proto.grpc.testing import test_pb2
+from src.proto.grpc.testing import test_pb2_grpc
 
 from tests.interop import methods
 from tests.interop import resources
@@ -53,7 +53,8 @@ def serve():
     args = parser.parse_args()
 
     server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
-    test_pb2.add_TestServiceServicer_to_server(methods.TestService(), server)
+    test_pb2_grpc.add_TestServiceServicer_to_server(methods.TestService(),
+                                                    server)
     if args.use_tls:
         private_key = resources.private_key()
         certificate_chain = resources.certificate_chain()
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py b/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py
index db938e65459c77a5cbc1a21889e575f7cbde4670..6f9269dd402e96a4d9ef32bef379ffdb3b67feb2 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py
@@ -42,6 +42,7 @@ import sys
 import tempfile
 import threading
 import unittest
+import platform
 
 import grpc
 from grpc_tools import protoc
@@ -150,6 +151,8 @@ class CommonTestMixin(object):
         self.assertEqual(expected_response, response)
 
 
+@unittest.skipIf(platform.python_implementation() == "PyPy",
+                 "Skip test if run with PyPy")
 class SameSeparateTest(unittest.TestCase, SeparateTestMixin):
 
     def setUp(self):
@@ -191,6 +194,8 @@ class SameSeparateTest(unittest.TestCase, SeparateTestMixin):
         shutil.rmtree(self.directory)
 
 
+@unittest.skipIf(platform.python_implementation() == "PyPy",
+                 "Skip test if run with PyPy")
 class SameCommonTest(unittest.TestCase, CommonTestMixin):
 
     def setUp(self):
@@ -228,6 +233,8 @@ class SameCommonTest(unittest.TestCase, CommonTestMixin):
         shutil.rmtree(self.directory)
 
 
+@unittest.skipIf(platform.python_implementation() == "PyPy",
+                 "Skip test if run with PyPy")
 class SplitCommonTest(unittest.TestCase, CommonTestMixin):
 
     def setUp(self):
@@ -277,6 +284,8 @@ class SplitCommonTest(unittest.TestCase, CommonTestMixin):
         shutil.rmtree(self.directory)
 
 
+@unittest.skipIf(platform.python_implementation() == "PyPy",
+                 "Skip test if run with PyPy")
 class SplitSeparateTest(unittest.TestCase, SeparateTestMixin):
 
     def setUp(self):
diff --git a/src/python/grpcio_tests/tests/qps/qps_worker.py b/src/python/grpcio_tests/tests/qps/qps_worker.py
index 025dfb9d4a7a933d10f98cda0bef43436b6046ba..7cd53e7bd9acd3770f148314b5e038931acacf27 100644
--- a/src/python/grpcio_tests/tests/qps/qps_worker.py
+++ b/src/python/grpcio_tests/tests/qps/qps_worker.py
@@ -33,7 +33,7 @@ import time
 
 from concurrent import futures
 import grpc
-from src.proto.grpc.testing import services_pb2
+from src.proto.grpc.testing import services_pb2_grpc
 
 from tests.qps import worker_server
 
@@ -41,7 +41,7 @@ from tests.qps import worker_server
 def run_worker_server(port):
     server = grpc.server(futures.ThreadPoolExecutor(max_workers=5))
     servicer = worker_server.WorkerServer()
-    services_pb2.add_WorkerServiceServicer_to_server(servicer, server)
+    services_pb2_grpc.add_WorkerServiceServicer_to_server(servicer, server)
     server.add_insecure_port('[::]:{}'.format(port))
     server.start()
     servicer.wait_for_quit()
diff --git a/src/python/grpcio_tests/tests/qps/worker_server.py b/src/python/grpcio_tests/tests/qps/worker_server.py
index ca1a777611c8cc2010de8f0e7d3eade4e2e1ac1b..de9535f46eb3621c3c54e91fb3ce9869bc37230f 100644
--- a/src/python/grpcio_tests/tests/qps/worker_server.py
+++ b/src/python/grpcio_tests/tests/qps/worker_server.py
@@ -35,7 +35,7 @@ import time
 from concurrent import futures
 import grpc
 from src.proto.grpc.testing import control_pb2
-from src.proto.grpc.testing import services_pb2
+from src.proto.grpc.testing import services_pb2_grpc
 from src.proto.grpc.testing import stats_pb2
 
 from tests.qps import benchmark_client
@@ -45,7 +45,7 @@ from tests.qps import histogram
 from tests.unit import resources
 
 
-class WorkerServer(services_pb2.WorkerServiceServicer):
+class WorkerServer(services_pb2_grpc.WorkerServiceServicer):
     """Python Worker Server implementation."""
 
     def __init__(self):
@@ -87,8 +87,8 @@ class WorkerServer(services_pb2.WorkerServiceServicer):
             futures.ThreadPoolExecutor(max_workers=server_threads))
         if config.server_type == control_pb2.ASYNC_SERVER:
             servicer = benchmark_server.BenchmarkServer()
-            services_pb2.add_BenchmarkServiceServicer_to_server(servicer,
-                                                                server)
+            services_pb2_grpc.add_BenchmarkServiceServicer_to_server(servicer,
+                                                                     server)
         elif config.server_type == control_pb2.ASYNC_GENERIC_SERVER:
             resp_size = config.payload_config.bytebuf_params.resp_size
             servicer = benchmark_server.GenericBenchmarkServer(resp_size)
diff --git a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py
index d06ff064e24cdb5251b76469bc80f3686e6cf473..14e6d64c66b97dffb095229ad3af0748f8f77b2b 100644
--- a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py
+++ b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py
@@ -34,18 +34,24 @@ import grpc
 from grpc.framework.foundation import logging_pool
 from grpc_reflection.v1alpha import reflection
 from grpc_reflection.v1alpha import reflection_pb2
+from grpc_reflection.v1alpha import reflection_pb2_grpc
 
 from google.protobuf import descriptor_pool
 from google.protobuf import descriptor_pb2
 
-from src.proto.grpc.testing.proto2 import empty2_extensions_pb2
 from src.proto.grpc.testing import empty_pb2
+#empty2_pb2 is imported for import-consequent side-effects.
+from src.proto.grpc.testing.proto2 import empty2_pb2  # pylint: disable=unused-import
+from src.proto.grpc.testing.proto2 import empty2_extensions_pb2
+
 from tests.unit.framework.common import test_constants
 
 _EMPTY_PROTO_FILE_NAME = 'src/proto/grpc/testing/empty.proto'
 _EMPTY_PROTO_SYMBOL_NAME = 'grpc.testing.Empty'
 _SERVICE_NAMES = ('Angstrom', 'Bohr', 'Curie', 'Dyson', 'Einstein', 'Feynman',
                   'Galilei')
+_EMPTY_EXTENSIONS_SYMBOL_NAME = 'grpc.testing.proto2.EmptyWithExtensions'
+_EMPTY_EXTENSIONS_NUMBERS = (124, 125, 126, 127, 128,)
 
 
 def _file_descriptor_to_proto(descriptor):
@@ -61,12 +67,12 @@ class ReflectionServicerTest(unittest.TestCase):
         server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
         self._server = grpc.server(server_pool)
         port = self._server.add_insecure_port('[::]:0')
-        reflection_pb2.add_ServerReflectionServicer_to_server(servicer,
-                                                              self._server)
+        reflection_pb2_grpc.add_ServerReflectionServicer_to_server(servicer,
+                                                                   self._server)
         self._server.start()
 
         channel = grpc.insecure_channel('localhost:%d' % port)
-        self._stub = reflection_pb2.ServerReflectionStub(channel)
+        self._stub = reflection_pb2_grpc.ServerReflectionStub(channel)
 
     def testFileByName(self):
         requests = (reflection_pb2.ServerReflectionRequest(
@@ -109,12 +115,12 @@ class ReflectionServicerTest(unittest.TestCase):
         self.assertSequenceEqual(expected_responses, responses)
 
     @unittest.skip(
-        'TODO(atash): implement file-containing-extension reflection '
-        '(see https://github.com/google/protobuf/issues/2248)')
+        'TODO(mmx): enable when (pure) python protobuf issue is fixed'
+        '(see https://github.com/google/protobuf/issues/2882)')
     def testFileContainingExtension(self):
         requests = (reflection_pb2.ServerReflectionRequest(
             file_containing_extension=reflection_pb2.ExtensionRequest(
-                containing_type='grpc.testing.proto2.Empty',
+                containing_type=_EMPTY_EXTENSIONS_SYMBOL_NAME,
                 extension_number=125,),
         ), reflection_pb2.ServerReflectionRequest(
             file_containing_extension=reflection_pb2.ExtensionRequest(
@@ -126,7 +132,28 @@ class ReflectionServicerTest(unittest.TestCase):
                 valid_host='',
                 file_descriptor_response=reflection_pb2.FileDescriptorResponse(
                     file_descriptor_proto=(_file_descriptor_to_proto(
-                        empty_extensions_pb2.DESCRIPTOR),))),
+                        empty2_extensions_pb2.DESCRIPTOR),))),
+            reflection_pb2.ServerReflectionResponse(
+                valid_host='',
+                error_response=reflection_pb2.ErrorResponse(
+                    error_code=grpc.StatusCode.NOT_FOUND.value[0],
+                    error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(),
+                )),)
+        self.assertSequenceEqual(expected_responses, responses)
+
+    def testExtensionNumbersOfType(self):
+        requests = (reflection_pb2.ServerReflectionRequest(
+            all_extension_numbers_of_type=_EMPTY_EXTENSIONS_SYMBOL_NAME
+        ), reflection_pb2.ServerReflectionRequest(
+            all_extension_numbers_of_type='i.donut.exist.co.uk.net.name.foo'),)
+        responses = tuple(self._stub.ServerReflectionInfo(iter(requests)))
+        expected_responses = (
+            reflection_pb2.ServerReflectionResponse(
+                valid_host='',
+                all_extension_numbers_response=reflection_pb2.
+                ExtensionNumberResponse(
+                    base_type_name=_EMPTY_EXTENSIONS_SYMBOL_NAME,
+                    extension_number=_EMPTY_EXTENSIONS_NUMBERS)),
             reflection_pb2.ServerReflectionResponse(
                 valid_host='',
                 error_response=reflection_pb2.ErrorResponse(
diff --git a/src/python/grpcio_tests/tests/stress/client.py b/src/python/grpcio_tests/tests/stress/client.py
index b9dbe61d44bc2266d53967f69d736f964d1f1e70..b7eb12bff8621e6bc001f4a6d7bbf3df1f33bf9f 100644
--- a/src/python/grpcio_tests/tests/stress/client.py
+++ b/src/python/grpcio_tests/tests/stress/client.py
@@ -34,7 +34,7 @@ import threading
 
 import grpc
 from six.moves import queue
-from src.proto.grpc.testing import metrics_pb2
+from src.proto.grpc.testing import metrics_pb2_grpc
 from src.proto.grpc.testing import test_pb2
 
 from tests.interop import methods
@@ -139,7 +139,7 @@ def run_test(args):
     runners = []
 
     server = grpc.server(futures.ThreadPoolExecutor(max_workers=25))
-    metrics_pb2.add_MetricsServiceServicer_to_server(
+    metrics_pb2_grpc.add_MetricsServiceServicer_to_server(
         metrics_server.MetricsServer(hist), server)
     server.add_insecure_port('[::]:{}'.format(args.metrics_port))
     server.start()
diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json
index 70d965d3ca8e232ff58be15b82739f1aafe7d2ad..f750b0510220ee7078896ba7f88503617c1cdbb5 100644
--- a/src/python/grpcio_tests/tests/tests.json
+++ b/src/python/grpcio_tests/tests/tests.json
@@ -31,6 +31,7 @@
   "unit._invocation_defects_test.InvocationDefectsTest",
   "unit._metadata_code_details_test.MetadataCodeDetailsTest",
   "unit._metadata_test.MetadataTest",
+  "unit._resource_exhausted_test.ResourceExhaustedTest",
   "unit._rpc_test.RPCTest",
   "unit._sanity._sanity_test.Sanity",
   "unit._thread_cleanup_test.CleanupThreadTest",
diff --git a/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py b/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..88c82b55414b60b386457c528d4df1d4485139fe
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py
@@ -0,0 +1,270 @@
+# Copyright 2017, 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.
+"""Tests server responding with RESOURCE_EXHAUSTED."""
+
+import threading
+import unittest
+
+import grpc
+from grpc import _channel
+from grpc.framework.foundation import logging_pool
+
+from tests.unit import test_common
+from tests.unit.framework.common import test_constants
+
+_REQUEST = b'\x00\x00\x00'
+_RESPONSE = b'\x00\x00\x00'
+
+_UNARY_UNARY = '/test/UnaryUnary'
+_UNARY_STREAM = '/test/UnaryStream'
+_STREAM_UNARY = '/test/StreamUnary'
+_STREAM_STREAM = '/test/StreamStream'
+
+
+class _TestTrigger(object):
+
+    def __init__(self, total_call_count):
+        self._total_call_count = total_call_count
+        self._pending_calls = 0
+        self._triggered = False
+        self._finish_condition = threading.Condition()
+        self._start_condition = threading.Condition()
+
+    # Wait for all calls be be blocked in their handler
+    def await_calls(self):
+        with self._start_condition:
+            while self._pending_calls < self._total_call_count:
+                self._start_condition.wait()
+
+    # Block in a response handler and wait for a trigger
+    def await_trigger(self):
+        with self._start_condition:
+            self._pending_calls += 1
+            self._start_condition.notify()
+
+        with self._finish_condition:
+            if not self._triggered:
+                self._finish_condition.wait()
+
+    # Finish all response handlers
+    def trigger(self):
+        with self._finish_condition:
+            self._triggered = True
+            self._finish_condition.notify_all()
+
+
+def handle_unary_unary(trigger, request, servicer_context):
+    trigger.await_trigger()
+    return _RESPONSE
+
+
+def handle_unary_stream(trigger, request, servicer_context):
+    trigger.await_trigger()
+    for _ in range(test_constants.STREAM_LENGTH):
+        yield _RESPONSE
+
+
+def handle_stream_unary(trigger, request_iterator, servicer_context):
+    trigger.await_trigger()
+    # TODO(issue:#6891) We should be able to remove this loop
+    for request in request_iterator:
+        pass
+    return _RESPONSE
+
+
+def handle_stream_stream(trigger, request_iterator, servicer_context):
+    trigger.await_trigger()
+    # TODO(issue:#6891) We should be able to remove this loop,
+    # and replace with return; yield
+    for request in request_iterator:
+        yield _RESPONSE
+
+
+class _MethodHandler(grpc.RpcMethodHandler):
+
+    def __init__(self, trigger, request_streaming, response_streaming):
+        self.request_streaming = request_streaming
+        self.response_streaming = response_streaming
+        self.request_deserializer = None
+        self.response_serializer = None
+        self.unary_unary = None
+        self.unary_stream = None
+        self.stream_unary = None
+        self.stream_stream = None
+        if self.request_streaming and self.response_streaming:
+            self.stream_stream = (
+                lambda x, y: handle_stream_stream(trigger, x, y))
+        elif self.request_streaming:
+            self.stream_unary = lambda x, y: handle_stream_unary(trigger, x, y)
+        elif self.response_streaming:
+            self.unary_stream = lambda x, y: handle_unary_stream(trigger, x, y)
+        else:
+            self.unary_unary = lambda x, y: handle_unary_unary(trigger, x, y)
+
+
+class _GenericHandler(grpc.GenericRpcHandler):
+
+    def __init__(self, trigger):
+        self._trigger = trigger
+
+    def service(self, handler_call_details):
+        if handler_call_details.method == _UNARY_UNARY:
+            return _MethodHandler(self._trigger, False, False)
+        elif handler_call_details.method == _UNARY_STREAM:
+            return _MethodHandler(self._trigger, False, True)
+        elif handler_call_details.method == _STREAM_UNARY:
+            return _MethodHandler(self._trigger, True, False)
+        elif handler_call_details.method == _STREAM_STREAM:
+            return _MethodHandler(self._trigger, True, True)
+        else:
+            return None
+
+
+class ResourceExhaustedTest(unittest.TestCase):
+
+    def setUp(self):
+        self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+        self._trigger = _TestTrigger(test_constants.THREAD_CONCURRENCY)
+        self._server = grpc.server(
+            self._server_pool,
+            handlers=(_GenericHandler(self._trigger),),
+            maximum_concurrent_rpcs=test_constants.THREAD_CONCURRENCY)
+        port = self._server.add_insecure_port('[::]:0')
+        self._server.start()
+        self._channel = grpc.insecure_channel('localhost:%d' % port)
+
+    def tearDown(self):
+        self._server.stop(0)
+
+    def testUnaryUnary(self):
+        multi_callable = self._channel.unary_unary(_UNARY_UNARY)
+        futures = []
+        for _ in range(test_constants.THREAD_CONCURRENCY):
+            futures.append(multi_callable.future(_REQUEST))
+
+        self._trigger.await_calls()
+
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            multi_callable(_REQUEST)
+
+        self.assertEqual(grpc.StatusCode.RESOURCE_EXHAUSTED,
+                         exception_context.exception.code())
+
+        future_exception = multi_callable.future(_REQUEST)
+        self.assertEqual(grpc.StatusCode.RESOURCE_EXHAUSTED,
+                         future_exception.exception().code())
+
+        self._trigger.trigger()
+        for future in futures:
+            self.assertEqual(_RESPONSE, future.result())
+
+        # Ensure a new request can be handled
+        self.assertEqual(_RESPONSE, multi_callable(_REQUEST))
+
+    def testUnaryStream(self):
+        multi_callable = self._channel.unary_stream(_UNARY_STREAM)
+        calls = []
+        for _ in range(test_constants.THREAD_CONCURRENCY):
+            calls.append(multi_callable(_REQUEST))
+
+        self._trigger.await_calls()
+
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            next(multi_callable(_REQUEST))
+
+        self.assertEqual(grpc.StatusCode.RESOURCE_EXHAUSTED,
+                         exception_context.exception.code())
+
+        self._trigger.trigger()
+
+        for call in calls:
+            for response in call:
+                self.assertEqual(_RESPONSE, response)
+
+        # Ensure a new request can be handled
+        new_call = multi_callable(_REQUEST)
+        for response in new_call:
+            self.assertEqual(_RESPONSE, response)
+
+    def testStreamUnary(self):
+        multi_callable = self._channel.stream_unary(_STREAM_UNARY)
+        futures = []
+        request = iter([_REQUEST] * test_constants.STREAM_LENGTH)
+        for _ in range(test_constants.THREAD_CONCURRENCY):
+            futures.append(multi_callable.future(request))
+
+        self._trigger.await_calls()
+
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            multi_callable(request)
+
+        self.assertEqual(grpc.StatusCode.RESOURCE_EXHAUSTED,
+                         exception_context.exception.code())
+
+        future_exception = multi_callable.future(request)
+        self.assertEqual(grpc.StatusCode.RESOURCE_EXHAUSTED,
+                         future_exception.exception().code())
+
+        self._trigger.trigger()
+
+        for future in futures:
+            self.assertEqual(_RESPONSE, future.result())
+
+        # Ensure a new request can be handled
+        self.assertEqual(_RESPONSE, multi_callable(request))
+
+    def testStreamStream(self):
+        multi_callable = self._channel.stream_stream(_STREAM_STREAM)
+        calls = []
+        request = iter([_REQUEST] * test_constants.STREAM_LENGTH)
+        for _ in range(test_constants.THREAD_CONCURRENCY):
+            calls.append(multi_callable(request))
+
+        self._trigger.await_calls()
+
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            next(multi_callable(request))
+
+        self.assertEqual(grpc.StatusCode.RESOURCE_EXHAUSTED,
+                         exception_context.exception.code())
+
+        self._trigger.trigger()
+
+        for call in calls:
+            for response in call:
+                self.assertEqual(_RESPONSE, response)
+
+        # Ensure a new request can be handled
+        new_call = multi_callable(request)
+        for response in new_call:
+            self.assertEqual(_RESPONSE, response)
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
diff --git a/src/ruby/.rubocop.yml b/src/ruby/.rubocop.yml
index 0f61ccfa812406ed193f39327cae64da241c7ac8..7174f3b15af62999cfa08aa2a4302ca315d5117a 100644
--- a/src/ruby/.rubocop.yml
+++ b/src/ruby/.rubocop.yml
@@ -9,6 +9,7 @@ AllCops:
     - 'bin/math_services_pb.rb'
     - 'pb/grpc/health/v1/*'
     - 'pb/test/**/*'
+    - 'end2end/lib/*'
 
 Metrics/CyclomaticComplexity:
   Max: 9
diff --git a/src/ruby/end2end/README.md b/src/ruby/end2end/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..ea5ab6d4bcb6e5e9ea5afd802a94fb0a62743dfe
--- /dev/null
+++ b/src/ruby/end2end/README.md
@@ -0,0 +1,18 @@
+This directory contains some grpc-ruby end to end tests.
+
+Each test here involves two files: a "driver" and a "client". For example,
+the "channel_closing" test involves channel_closing_driver.rb
+and channel_closing_client.rb.
+
+Typically, the "driver" will start up a simple "echo" server, and then
+spawn a client. It gives the client the address of the "echo" server as
+well as an address to listen on for control rpcs. Depending on the test, the
+client usually starts up a "ClientControl" grpc server for the driver to
+interact with (the driver can tell the client process to do strange things at
+different times, depending on the test).
+
+So far these tests are mostly useful for testing process-shutdown related
+situations, since the client's run in separate processes.
+
+These tests are invoked through the "tools/run_tests/run_tests.py" script (the
+Rakefile doesn't start these).
diff --git a/src/ruby/end2end/channel_closing_client.rb b/src/ruby/end2end/channel_closing_client.rb
new file mode 100755
index 0000000000000000000000000000000000000000..84497973607a46ef1e20bf30b75f2b03d84c172e
--- /dev/null
+++ b/src/ruby/end2end/channel_closing_client.rb
@@ -0,0 +1,84 @@
+#!/usr/bin/env ruby
+
+# 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.
+
+require_relative './end2end_common'
+
+# Calls '#close' on a Channel when "shutdown" called. This tries to
+# trigger a hang or crash bug by closing a channel actively being watched
+class ChannelClosingClientController < ClientControl::ClientController::Service
+  def initialize(ch)
+    @ch = ch
+  end
+
+  def shutdown(_, _)
+    @ch.close
+    ClientControl::Void.new
+  end
+end
+
+def main
+  client_control_port = ''
+  server_port = ''
+  OptionParser.new do |opts|
+    opts.on('--client_control_port=P', String) do |p|
+      client_control_port = p
+    end
+    opts.on('--server_port=P', String) do |p|
+      server_port = p
+    end
+  end.parse!
+
+  ch = GRPC::Core::Channel.new("localhost:#{server_port}", {},
+                               :this_channel_is_insecure)
+
+  srv = GRPC::RpcServer.new
+  thd = Thread.new do
+    srv.add_http2_port("0.0.0.0:#{client_control_port}", :this_port_is_insecure)
+    srv.handle(ChannelClosingClientController.new(ch))
+    srv.run
+  end
+
+  # this should break out with an exception once the channel is closed
+  loop do
+    begin
+      state = ch.connectivity_state(true)
+      ch.watch_connectivity_state(state, Time.now + 360)
+    rescue RuntimeError => e
+      STDERR.puts "(expected) error occurred: #{e.inspect}"
+      break
+    end
+  end
+
+  srv.stop
+  thd.join
+end
+
+main
diff --git a/src/ruby/end2end/channel_closing_driver.rb b/src/ruby/end2end/channel_closing_driver.rb
new file mode 100755
index 0000000000000000000000000000000000000000..d3e5373b0bb0e4724269d32353e98258d961db08
--- /dev/null
+++ b/src/ruby/end2end/channel_closing_driver.rb
@@ -0,0 +1,67 @@
+#!/usr/bin/env ruby
+
+# 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.
+
+# make sure that the client doesn't hang when channel is closed
+# explictly while it's used
+
+require_relative './end2end_common'
+
+def main
+  STDERR.puts 'start server'
+  server_runner = ServerRunner.new(EchoServerImpl)
+  server_port = server_runner.run
+
+  sleep 1
+
+  STDERR.puts 'start client'
+  control_stub, client_pid = start_client('channel_closing_client.rb',
+                                          server_port)
+
+  sleep 3
+
+  begin
+    Timeout.timeout(10) do
+      control_stub.shutdown(ClientControl::Void.new)
+      Process.wait(client_pid)
+    end
+  rescue Timeout::Error
+    STDERR.puts "timeout wait for client pid #{client_pid}"
+    Process.kill('SIGKILL', client_pid)
+    Process.wait(client_pid)
+    STDERR.puts 'killed client child'
+    raise 'Timed out waiting for client process. It likely hangs when a ' \
+      'channel is closed while connectivity is watched'
+  end
+
+  server_runner.stop
+end
+
+main
diff --git a/tools/dockerfile/bazel/Dockerfile b/src/ruby/end2end/channel_state_client.rb
old mode 100644
new mode 100755
similarity index 73%
rename from tools/dockerfile/bazel/Dockerfile
rename to src/ruby/end2end/channel_state_client.rb
index 2a80a4d4d530bb413dcabac757e827ab5e777852..08c21bbb8e83d667439a70357f6eead99ac27f07
--- a/tools/dockerfile/bazel/Dockerfile
+++ b/src/ruby/end2end/channel_state_client.rb
@@ -1,3 +1,5 @@
+#!/usr/bin/env ruby
+
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -27,26 +29,26 @@
 # (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:wily
-RUN apt-get update
-RUN apt-get -y install software-properties-common python-software-properties
-RUN add-apt-repository ppa:webupd8team/java
-RUN apt-get update
-RUN apt-get -y install \
-	vim            \
-	wget           \
-	openjdk-8-jdk  \
-	pkg-config     \
-	zip            \
-	g++            \
-	zlib1g-dev     \
-	unzip          \
-	git
+require_relative './end2end_common'
+
+def main
+  server_port = ''
+  OptionParser.new do |opts|
+    opts.on('--client_control_port=P', String) do
+      STDERR.puts 'client_control_port ignored'
+    end
+    opts.on('--server_port=P', String) do |p|
+      server_port = p
+    end
+  end.parse!
 
-RUN git clone https://github.com/bazelbuild/bazel.git /bazel
-RUN cd /bazel && ./compile.sh
+  ch = GRPC::Core::Channel.new("localhost:#{server_port}", {},
+                               :this_channel_is_insecure)
 
-RUN ln -s /bazel/output/bazel /bin/
+  loop do
+    state = ch.connectivity_state
+    ch.watch_connectivity_state(state, Time.now + 360)
+  end
+end
 
-# ensure the installation has been extracted
-RUN bazel
+main
diff --git a/src/ruby/end2end/channel_state_driver.rb b/src/ruby/end2end/channel_state_driver.rb
new file mode 100755
index 0000000000000000000000000000000000000000..80fb62899e5aa59f99154ced8906cc5353ffc8ee
--- /dev/null
+++ b/src/ruby/end2end/channel_state_driver.rb
@@ -0,0 +1,64 @@
+#!/usr/bin/env ruby
+
+# 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.
+
+# make sure that the client doesn't hang when process ended abruptly
+
+require_relative './end2end_common'
+
+def main
+  STDERR.puts 'start server'
+  server_runner = ServerRunner.new(EchoServerImpl)
+  server_port = server_runner.run
+
+  sleep 1
+
+  STDERR.puts 'start client'
+  _, client_pid = start_client('channel_state_client.rb', server_port)
+
+  sleep 3
+
+  Process.kill('SIGTERM', client_pid)
+
+  begin
+    Timeout.timeout(10) { Process.wait(client_pid) }
+  rescue Timeout::Error
+    STDERR.puts "timeout wait for client pid #{client_pid}"
+    Process.kill('SIGKILL', client_pid)
+    Process.wait(client_pid)
+    STDERR.puts 'killed client child'
+    raise 'Timed out waiting for client process. ' \
+           'It likely hangs when ended abruptly'
+  end
+
+  server_runner.stop
+end
+
+main
diff --git a/src/ruby/end2end/end2end_common.rb b/src/ruby/end2end/end2end_common.rb
new file mode 100755
index 0000000000000000000000000000000000000000..1c87ceddf1df77e12c974c469b38952b34cddff1
--- /dev/null
+++ b/src/ruby/end2end/end2end_common.rb
@@ -0,0 +1,110 @@
+#!/usr/bin/env ruby
+
+# 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_dir = File.expand_path(File.dirname(__FILE__))
+protos_lib_dir = File.join(this_dir, 'lib')
+grpc_lib_dir = File.join(File.dirname(this_dir), 'lib')
+$LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir)
+$LOAD_PATH.unshift(protos_lib_dir) unless $LOAD_PATH.include?(protos_lib_dir)
+$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
+
+require 'grpc'
+require 'echo_services_pb'
+require 'client_control_services_pb'
+require 'socket'
+require 'optparse'
+require 'thread'
+require 'timeout'
+require 'English' # see https://github.com/bbatsov/rubocop/issues/1747
+
+# GreeterServer is simple server that implements the Helloworld Greeter server.
+class EchoServerImpl < Echo::EchoServer::Service
+  # say_hello implements the SayHello rpc method.
+  def echo(echo_req, _)
+    Echo::EchoReply.new(response: echo_req.request)
+  end
+end
+
+# ServerRunner starts an "echo server" that test clients can make calls to
+class ServerRunner
+  def initialize(service_impl)
+    @service_impl = service_impl
+  end
+
+  def run
+    @srv = GRPC::RpcServer.new
+    port = @srv.add_http2_port('0.0.0.0:0', :this_port_is_insecure)
+    @srv.handle(@service_impl)
+
+    @thd = Thread.new do
+      @srv.run
+    end
+    @srv.wait_till_running
+    port
+  end
+
+  def stop
+    @srv.stop
+    @thd.join
+    fail 'server not stopped' unless @srv.stopped?
+  end
+end
+
+def start_client(client_main, server_port)
+  this_dir = File.expand_path(File.dirname(__FILE__))
+
+  tmp_server = TCPServer.new(0)
+  client_control_port = tmp_server.local_address.ip_port
+  tmp_server.close
+
+  client_path = File.join(this_dir, client_main)
+  client_pid = Process.spawn(RbConfig.ruby,
+                             client_path,
+                             "--client_control_port=#{client_control_port}",
+                             "--server_port=#{server_port}")
+  sleep 1
+  control_stub = ClientControl::ClientController::Stub.new(
+    "localhost:#{client_control_port}", :this_channel_is_insecure)
+  [control_stub, client_pid]
+end
+
+def cleanup(control_stub, client_pid, server_runner)
+  control_stub.shutdown(ClientControl::Void.new)
+  Process.wait(client_pid)
+
+  client_exit_code = $CHILD_STATUS
+
+  if client_exit_code != 0
+    fail "term sig test failure: client exit code: #{client_exit_code}"
+  end
+
+  server_runner.stop
+end
diff --git a/src/ruby/end2end/forking_client_client.rb b/src/ruby/end2end/forking_client_client.rb
new file mode 100755
index 0000000000000000000000000000000000000000..c358d79f5997ebcddde42ce50cee5b3be383f571
--- /dev/null
+++ b/src/ruby/end2end/forking_client_client.rb
@@ -0,0 +1,69 @@
+#!/usr/bin/env ruby
+
+# 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.
+
+# Prompted by and minimal repro of https://github.com/grpc/grpc/issues/10658
+
+require_relative './end2end_common'
+
+def main
+  server_port = ''
+  OptionParser.new do |opts|
+    opts.on('--client_control_port=P', String) do
+      STDERR.puts 'client control port not used'
+    end
+    opts.on('--server_port=P', String) do |p|
+      server_port = p
+    end
+  end.parse!
+
+  p = fork do
+    stub = Echo::EchoServer::Stub.new("localhost:#{server_port}",
+                                      :this_channel_is_insecure)
+    stub.echo(Echo::EchoRequest.new(request: 'hello'))
+  end
+
+  begin
+    Timeout.timeout(10) do
+      Process.wait(p)
+    end
+  rescue Timeout::Error
+    STDERR.puts "timeout waiting for forked process #{p}"
+    Process.kill('SIGKILL', p)
+    Process.wait(p)
+    raise 'Timed out waiting for client process. ' \
+      'It likely hangs when using gRPC after loading it and then forking'
+  end
+
+  client_exit_code = $CHILD_STATUS
+  fail "forked process failed #{client_exit_code}" if client_exit_code != 0
+end
+
+main
diff --git a/src/ruby/end2end/forking_client_driver.rb b/src/ruby/end2end/forking_client_driver.rb
new file mode 100755
index 0000000000000000000000000000000000000000..2c67b33590df696e3e81efa65a71d04001c66eea
--- /dev/null
+++ b/src/ruby/end2end/forking_client_driver.rb
@@ -0,0 +1,69 @@
+#!/usr/bin/env ruby
+
+# 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.
+
+require_relative './end2end_common'
+
+def main
+  STDERR.puts 'start server'
+  server_runner = ServerRunner.new(EchoServerImpl)
+  server_port = server_runner.run
+
+  # TODO(apolcyn) Can we get rid of this sleep?
+  # Without it, an immediate call to the just started EchoServer
+  # fails with UNAVAILABLE
+  sleep 1
+
+  STDERR.puts 'start client'
+  _, client_pid = start_client('forking_client_client.rb',
+                               server_port)
+
+  begin
+    Timeout.timeout(10) do
+      Process.wait(client_pid)
+    end
+  rescue Timeout::Error
+    STDERR.puts "timeout wait for client pid #{client_pid}"
+    Process.kill('SIGKILL', client_pid)
+    Process.wait(client_pid)
+    STDERR.puts 'killed client child'
+    raise 'Timed out waiting for client process. ' \
+      'It likely hangs when requiring grpc, then forking, then using grpc '
+  end
+
+  client_exit_code = $CHILD_STATUS
+  if client_exit_code != 0
+    fail "forking client client failed, exit code #{client_exit_code}"
+  end
+
+  server_runner.stop
+end
+
+main
diff --git a/src/ruby/end2end/gen_protos.sh b/src/ruby/end2end/gen_protos.sh
new file mode 100644
index 0000000000000000000000000000000000000000..f78d9ad394a7a22fbff58f3bff0d529a8c2e5097
--- /dev/null
+++ b/src/ruby/end2end/gen_protos.sh
@@ -0,0 +1,32 @@
+#!/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.
+
+grpc_tools_ruby_protoc -I protos --ruby_out=lib --grpc_out=lib protos/echo.proto protos/client_control.proto
diff --git a/src/ruby/end2end/grpc_class_init_client.rb b/src/ruby/end2end/grpc_class_init_client.rb
new file mode 100755
index 0000000000000000000000000000000000000000..ee79292119a0499e0f7784901c14bd132ba9a43b
--- /dev/null
+++ b/src/ruby/end2end/grpc_class_init_client.rb
@@ -0,0 +1,77 @@
+#!/usr/bin/env ruby
+
+# 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.
+
+# For GRPC::Core classes, which use the grpc c-core, object init
+# is interesting because it's related to overall library init.
+
+require_relative './end2end_common'
+
+def main
+  grpc_class = ''
+  OptionParser.new do |opts|
+    opts.on('--grpc_class=P', String) do |p|
+      grpc_class = p
+    end
+  end.parse!
+
+  test_proc = nil
+
+  case grpc_class
+  when 'channel'
+    test_proc = proc do
+      GRPC::Core::Channel.new('dummy_host', nil, :this_channel_is_insecure)
+    end
+  when 'server'
+    test_proc = proc do
+      GRPC::Core::Server.new({})
+    end
+  when 'channel_credentials'
+    test_proc = proc do
+      GRPC::Core::ChannelCredentials.new
+    end
+  when 'call_credentials'
+    test_proc = proc do
+      GRPC::Core::CallCredentials.new(proc { |noop| noop })
+    end
+  when 'compression_options'
+    test_proc = proc do
+      GRPC::Core::CompressionOptions.new
+    end
+  else
+    fail "bad --grpc_class=#{grpc_class} param"
+  end
+
+  th = Thread.new { test_proc.call }
+  test_proc.call
+  th.join
+end
+
+main
diff --git a/src/ruby/end2end/grpc_class_init_driver.rb b/src/ruby/end2end/grpc_class_init_driver.rb
new file mode 100755
index 0000000000000000000000000000000000000000..764d029f1494df9889069680922669a416cfc0b6
--- /dev/null
+++ b/src/ruby/end2end/grpc_class_init_driver.rb
@@ -0,0 +1,67 @@
+#!/usr/bin/env ruby
+
+# 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.
+
+require_relative './end2end_common'
+
+def main
+  native_grpc_classes = %w( channel
+                            server
+                            channel_credentials
+                            call_credentials
+                            compression_options )
+
+  native_grpc_classes.each do |grpc_class|
+    STDERR.puts 'start client'
+    this_dir = File.expand_path(File.dirname(__FILE__))
+    client_path = File.join(this_dir, 'grpc_class_init_client.rb')
+    client_pid = Process.spawn(RbConfig.ruby,
+                               client_path,
+                               "--grpc_class=#{grpc_class}")
+    begin
+      Timeout.timeout(10) do
+        Process.wait(client_pid)
+      end
+    rescue Timeout::Error
+      STDERR.puts "timeout waiting for client pid #{client_pid}"
+      Process.kill('SIGKILL', client_pid)
+      Process.wait(client_pid)
+      STDERR.puts 'killed client child'
+      raise 'Timed out waiting for client process. ' \
+        'It likely hangs when the first constructed gRPC object has ' \
+        "type: #{grpc_class}"
+    end
+
+    client_exit_code = $CHILD_STATUS
+    fail "client failed, exit code #{client_exit_code}" if client_exit_code != 0
+  end
+end
+
+main
diff --git a/src/ruby/end2end/killed_client_thread_client.rb b/src/ruby/end2end/killed_client_thread_client.rb
new file mode 100755
index 0000000000000000000000000000000000000000..d5a7db7d5866998ada4b4906e3659afb42b70389
--- /dev/null
+++ b/src/ruby/end2end/killed_client_thread_client.rb
@@ -0,0 +1,58 @@
+#!/usr/bin/env ruby
+
+# 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.
+
+# Attempt to reproduce
+# https://github.com/GoogleCloudPlatform/google-cloud-ruby/issues/1327
+
+require_relative './end2end_common'
+
+def main
+  server_port = ''
+  OptionParser.new do |opts|
+    opts.on('--client_control_port=P', String) do
+      STDERR.puts 'client control port not used'
+    end
+    opts.on('--server_port=P', String) do |p|
+      server_port = p
+    end
+  end.parse!
+
+  thd = Thread.new do
+    stub = Echo::EchoServer::Stub.new("localhost:#{server_port}",
+                                      :this_channel_is_insecure)
+    stub.echo(Echo::EchoRequest.new(request: 'hello'))
+    fail 'the clients rpc in this test shouldnt complete. ' \
+      'expecting SIGINT to happen in the middle of the call'
+  end
+  thd.join
+end
+
+main
diff --git a/src/ruby/end2end/killed_client_thread_driver.rb b/src/ruby/end2end/killed_client_thread_driver.rb
new file mode 100755
index 0000000000000000000000000000000000000000..f76d3e1746df321bcdae1fb57645ebbdba5b8766
--- /dev/null
+++ b/src/ruby/end2end/killed_client_thread_driver.rb
@@ -0,0 +1,114 @@
+#!/usr/bin/env ruby
+
+# 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.
+
+require_relative './end2end_common'
+
+# Service that sleeps for a long time upon receiving an 'echo request'
+# Also, this notifies @call_started_cv once it has received a request.
+class SleepingEchoServerImpl < Echo::EchoServer::Service
+  def initialize(call_started, call_started_mu, call_started_cv)
+    @call_started = call_started
+    @call_started_mu = call_started_mu
+    @call_started_cv = call_started_cv
+  end
+
+  def echo(echo_req, _)
+    @call_started_mu.synchronize do
+      @call_started.set_true
+      @call_started_cv.signal
+    end
+    sleep 1000
+    Echo::EchoReply.new(response: echo_req.request)
+  end
+end
+
+# Mutable boolean
+class BoolHolder
+  attr_reader :val
+
+  def init
+    @val = false
+  end
+
+  def set_true
+    @val = true
+  end
+end
+
+def main
+  STDERR.puts 'start server'
+
+  call_started = BoolHolder.new
+  call_started_mu = Mutex.new
+  call_started_cv = ConditionVariable.new
+
+  service_impl = SleepingEchoServerImpl.new(call_started,
+                                            call_started_mu,
+                                            call_started_cv)
+  server_runner = ServerRunner.new(service_impl)
+  server_port = server_runner.run
+
+  STDERR.puts 'start client'
+  _, client_pid = start_client('killed_client_thread_client.rb',
+                               server_port)
+
+  call_started_mu.synchronize do
+    call_started_cv.wait(call_started_mu) until call_started.val
+  end
+
+  # SIGINT the child process now that it's
+  # in the middle of an RPC (happening on a non-main thread)
+  Process.kill('SIGINT', client_pid)
+  STDERR.puts 'sent shutdown'
+
+  begin
+    Timeout.timeout(10) do
+      Process.wait(client_pid)
+    end
+  rescue Timeout::Error
+    STDERR.puts "timeout wait for client pid #{client_pid}"
+    Process.kill('SIGKILL', client_pid)
+    Process.wait(client_pid)
+    STDERR.puts 'killed client child'
+    raise 'Timed out waiting for client process. ' \
+      'It likely hangs when killed while in the middle of an rpc'
+  end
+
+  client_exit_code = $CHILD_STATUS
+  if client_exit_code.termsig != 2 # SIGINT
+    fail 'expected client exit from SIGINT ' \
+      "but got child status: #{client_exit_code}"
+  end
+
+  server_runner.stop
+end
+
+main
diff --git a/src/ruby/end2end/lib/client_control_pb.rb b/src/ruby/end2end/lib/client_control_pb.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1a938f1b5ae928f9fa5ae868bd5c336d321a2884
--- /dev/null
+++ b/src/ruby/end2end/lib/client_control_pb.rb
@@ -0,0 +1,17 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: client_control.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+  add_message "client_control.DoEchoRpcRequest" do
+    optional :request, :string, 1
+  end
+  add_message "client_control.Void" do
+  end
+end
+
+module ClientControl
+  DoEchoRpcRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("client_control.DoEchoRpcRequest").msgclass
+  Void = Google::Protobuf::DescriptorPool.generated_pool.lookup("client_control.Void").msgclass
+end
diff --git a/src/ruby/end2end/lib/client_control_services_pb.rb b/src/ruby/end2end/lib/client_control_services_pb.rb
new file mode 100644
index 0000000000000000000000000000000000000000..04b2291bc78fdb409a009c0210575eb944809db8
--- /dev/null
+++ b/src/ruby/end2end/lib/client_control_services_pb.rb
@@ -0,0 +1,53 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# Source: client_control.proto for package 'client_control'
+# Original file comments:
+# 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.
+#
+
+require 'grpc'
+require 'client_control_pb'
+
+module ClientControl
+  module ClientController
+    class Service
+
+      include GRPC::GenericService
+
+      self.marshal_class_method = :encode
+      self.unmarshal_class_method = :decode
+      self.service_name = 'client_control.ClientController'
+
+      rpc :DoEchoRpc, DoEchoRpcRequest, Void
+      rpc :Shutdown, Void, Void
+    end
+
+    Stub = Service.rpc_stub_class
+  end
+end
diff --git a/src/ruby/end2end/lib/echo_pb.rb b/src/ruby/end2end/lib/echo_pb.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c62adc07534edd7c2795fdd8e5bb40d8dd7be991
--- /dev/null
+++ b/src/ruby/end2end/lib/echo_pb.rb
@@ -0,0 +1,18 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: echo.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+  add_message "echo.EchoRequest" do
+    optional :request, :string, 1
+  end
+  add_message "echo.EchoReply" do
+    optional :response, :string, 1
+  end
+end
+
+module Echo
+  EchoRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("echo.EchoRequest").msgclass
+  EchoReply = Google::Protobuf::DescriptorPool.generated_pool.lookup("echo.EchoReply").msgclass
+end
diff --git a/src/ruby/end2end/lib/echo_services_pb.rb b/src/ruby/end2end/lib/echo_services_pb.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c66e975bf32fb813627d7ba94313ce2c0508ee4e
--- /dev/null
+++ b/src/ruby/end2end/lib/echo_services_pb.rb
@@ -0,0 +1,52 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# Source: echo.proto for package 'echo'
+# Original file comments:
+# 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.
+#
+
+require 'grpc'
+require 'echo_pb'
+
+module Echo
+  module EchoServer
+    class Service
+
+      include GRPC::GenericService
+
+      self.marshal_class_method = :encode
+      self.unmarshal_class_method = :decode
+      self.service_name = 'echo.EchoServer'
+
+      rpc :Echo, EchoRequest, EchoReply
+    end
+
+    Stub = Service.rpc_stub_class
+  end
+end
diff --git a/src/csharp/Grpc.Core.Tests/NUnitVersionTest.cs b/src/ruby/end2end/protos/client_control.proto
similarity index 56%
rename from src/csharp/Grpc.Core.Tests/NUnitVersionTest.cs
rename to src/ruby/end2end/protos/client_control.proto
index 1a9e441611d39e38cb9d54a603ce13b41ee52e80..f985bb486dcee99cc195f9640cd9e6732a9aa287 100644
--- a/src/csharp/Grpc.Core.Tests/NUnitVersionTest.cs
+++ b/src/ruby/end2end/protos/client_control.proto
@@ -1,5 +1,3 @@
-#region Copyright notice and license
-
 // Copyright 2015, Google Inc.
 // All rights reserved.
 //
@@ -29,49 +27,17 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#endregion
-
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Grpc.Core;
-using Grpc.Core.Internal;
-using Grpc.Core.Utils;
-using NUnit.Framework;
-
-namespace Grpc.Core.Tests
-{
-    /// <summary>
-    /// Tests if the version of nunit-console used is sufficient to run async tests.
-    /// </summary>
-    public class NUnitVersionTest
-    {
-        private int testRunCount = 0;
+syntax = "proto3";
 
-        [TestFixtureTearDown]
-        public void Cleanup()
-        {
-            if (testRunCount != 2)
-            {
-                Console.Error.WriteLine("You are using and old version of NUnit that doesn't support async tests and skips them instead. " +
-                "This test has failed to indicate that.");
-                Console.Error.Flush();
-                throw new Exception("NUnitVersionTest has failed.");
-            }
-        }
+package client_control;
 
-        [Test]
-        public void NUnitVersionTest1()
-        {
-            testRunCount++;
-        }
+service ClientController {
+  rpc DoEchoRpc (DoEchoRpcRequest) returns (Void) {}
+  rpc Shutdown(Void) returns (Void) {}
+}
 
-        // Old version of NUnit will skip this test
-        [Test]
-        public async Task NUnitVersionTest2()
-        {
-            testRunCount++;
-            await Task.Delay(10);
-        }
-    }
+message DoEchoRpcRequest {
+  string request = 1;
 }
+
+message Void{}
diff --git a/src/ruby/end2end/protos/echo.proto b/src/ruby/end2end/protos/echo.proto
new file mode 100644
index 0000000000000000000000000000000000000000..d47afef70f19b367a8f07332f1226ad76e062ccf
--- /dev/null
+++ b/src/ruby/end2end/protos/echo.proto
@@ -0,0 +1,46 @@
+// 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.
+
+syntax = "proto3";
+
+package echo;
+
+service EchoServer {
+  rpc Echo (EchoRequest) returns (EchoReply) {}
+}
+
+// The request message containing the user's name.
+message EchoRequest {
+  string request = 1;
+}
+
+// The response message containing the greetings
+message EchoReply {
+  string response = 1;
+}
diff --git a/src/ruby/end2end/sig_handling_client.rb b/src/ruby/end2end/sig_handling_client.rb
new file mode 100755
index 0000000000000000000000000000000000000000..5b1e54718ec9191ead07e411cb1b5c28b1e83f7c
--- /dev/null
+++ b/src/ruby/end2end/sig_handling_client.rb
@@ -0,0 +1,89 @@
+#!/usr/bin/env ruby
+
+# 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.
+
+require_relative './end2end_common'
+
+# Test client. Sends RPC's as normal but process also has signal handlers
+class SigHandlingClientController < ClientControl::ClientController::Service
+  def initialize(srv, stub)
+    @srv = srv
+    @stub = stub
+  end
+
+  def do_echo_rpc(req, _)
+    response = @stub.echo(Echo::EchoRequest.new(request: req.request))
+    fail 'bad response' unless response.response == req.request
+    ClientControl::Void.new
+  end
+
+  def shutdown(_, _)
+    Thread.new do
+      # TODO(apolcyn) There is a race between stopping the
+      # server and the "shutdown" rpc completing,
+      # See if stop method on server can end active RPC cleanly, to
+      # avoid this sleep.
+      sleep 3
+      @srv.stop
+    end
+    ClientControl::Void.new
+  end
+end
+
+def main
+  client_control_port = ''
+  server_port = ''
+  OptionParser.new do |opts|
+    opts.on('--client_control_port=P', String) do |p|
+      client_control_port = p
+    end
+    opts.on('--server_port=P', String) do |p|
+      server_port = p
+    end
+  end.parse!
+
+  Signal.trap('TERM') do
+    STDERR.puts 'SIGTERM received'
+  end
+
+  Signal.trap('INT') do
+    STDERR.puts 'SIGINT received'
+  end
+
+  srv = GRPC::RpcServer.new
+  srv.add_http2_port("0.0.0.0:#{client_control_port}",
+                     :this_port_is_insecure)
+  stub = Echo::EchoServer::Stub.new("localhost:#{server_port}",
+                                    :this_channel_is_insecure)
+  srv.handle(SigHandlingClientController.new(srv, stub))
+  srv.run
+end
+
+main
diff --git a/src/ruby/end2end/sig_handling_driver.rb b/src/ruby/end2end/sig_handling_driver.rb
new file mode 100755
index 0000000000000000000000000000000000000000..6691464dc69a50bff29502d0ee60a5d20aa76681
--- /dev/null
+++ b/src/ruby/end2end/sig_handling_driver.rb
@@ -0,0 +1,61 @@
+#!/usr/bin/env ruby
+
+# 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.
+
+# smoke test for a grpc-using app that receives and
+# handles process-ending signals
+
+require_relative './end2end_common'
+
+def main
+  STDERR.puts 'start server'
+  server_runner = ServerRunner.new(EchoServerImpl)
+  server_port = server_runner.run
+
+  sleep 1
+
+  STDERR.puts 'start client'
+  control_stub, client_pid = start_client('sig_handling_client.rb', server_port)
+
+  sleep 1
+
+  count = 0
+  while count < 5
+    control_stub.do_echo_rpc(
+      ClientControl::DoEchoRpcRequest.new(request: 'hello'))
+    Process.kill('SIGTERM', client_pid)
+    Process.kill('SIGINT', client_pid)
+    count += 1
+  end
+
+  cleanup(control_stub, client_pid, server_runner)
+end
+
+main
diff --git a/src/ruby/end2end/sig_int_during_channel_watch_client.rb b/src/ruby/end2end/sig_int_during_channel_watch_client.rb
new file mode 100755
index 0000000000000000000000000000000000000000..389fc5ba332be5ab6e46871ba45572dfa847d4d4
--- /dev/null
+++ b/src/ruby/end2end/sig_int_during_channel_watch_client.rb
@@ -0,0 +1,70 @@
+#!/usr/bin/env ruby
+
+# 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.
+
+require_relative './end2end_common'
+
+# Start polling the channel state in both the main thread
+# and a child thread. Try to get the driver to send process-ending
+# interrupt while both a child thread and the main thread are in the
+# middle of a blocking connectivity_state call.
+def main
+  server_port = ''
+  OptionParser.new do |opts|
+    opts.on('--client_control_port=P', String) do
+      STDERR.puts 'client_control_port not used'
+    end
+    opts.on('--server_port=P', String) do |p|
+      server_port = p
+    end
+  end.parse!
+
+  thd = Thread.new do
+    child_thread_channel = GRPC::Core::Channel.new("localhost:#{server_port}",
+                                                   {},
+                                                   :this_channel_is_insecure)
+    loop do
+      state = child_thread_channel.connectivity_state(false)
+      child_thread_channel.watch_connectivity_state(state, Time.now + 360)
+    end
+  end
+
+  main_channel = GRPC::Core::Channel.new("localhost:#{server_port}",
+                                         {},
+                                         :this_channel_is_insecure)
+  loop do
+    state = main_channel.connectivity_state(false)
+    main_channel.watch_connectivity_state(state, Time.now + 360)
+  end
+
+  thd.join
+end
+
+main
diff --git a/src/ruby/end2end/sig_int_during_channel_watch_driver.rb b/src/ruby/end2end/sig_int_during_channel_watch_driver.rb
new file mode 100755
index 0000000000000000000000000000000000000000..670cda0919f869ac468f78f93e5317b948fcc64a
--- /dev/null
+++ b/src/ruby/end2end/sig_int_during_channel_watch_driver.rb
@@ -0,0 +1,69 @@
+#!/usr/bin/env ruby
+
+# 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.
+
+# abruptly end a process that has active calls to
+# Channel.watch_connectivity_state
+
+require_relative './end2end_common'
+
+def main
+  STDERR.puts 'start server'
+  server_runner = ServerRunner.new(EchoServerImpl)
+  server_port = server_runner.run
+
+  sleep 1
+
+  STDERR.puts 'start client'
+  _, client_pid = start_client('sig_int_during_channel_watch_client.rb',
+                               server_port)
+
+  # give time for the client to get into the middle
+  # of a channel state watch call
+  sleep 1
+  Process.kill('SIGINT', client_pid)
+
+  begin
+    Timeout.timeout(10) do
+      Process.wait(client_pid)
+    end
+  rescue Timeout::Error
+    STDERR.puts "timeout wait for client pid #{client_pid}"
+    Process.kill('SIGKILL', client_pid)
+    Process.wait(client_pid)
+    STDERR.puts 'killed client child'
+    raise 'Timed out waiting for client process. It likely hangs when a ' \
+      'SIGINT is sent while there is an active connectivity_state call'
+  end
+
+  server_runner.stop
+end
+
+main
diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb
index b379664bab8d39e866ec320c6f9dd3389b9af6c5..6c0486f1a8cbda124b56f22f60535a4a42c1804f 100644
--- a/src/ruby/ext/grpc/extconf.rb
+++ b/src/ruby/ext/grpc/extconf.rb
@@ -27,6 +27,7 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+require 'etc'
 require 'mkmf'
 
 LIBDIR = RbConfig::CONFIG['libdir']
@@ -64,12 +65,14 @@ ENV['MACOSX_DEPLOYMENT_TARGET'] = '10.7'
 
 ENV['AR'] = RbConfig::CONFIG['AR'] + ' rcs'
 ENV['CC'] = RbConfig::CONFIG['CC']
+ENV['CXX'] = RbConfig::CONFIG['CXX']
 ENV['LD'] = ENV['CC']
 
 ENV['AR'] = 'libtool -o' if RUBY_PLATFORM =~ /darwin/
 
 ENV['EMBED_OPENSSL'] = 'true'
 ENV['EMBED_ZLIB'] = 'true'
+ENV['EMBED_CARES'] = 'true'
 ENV['ARCH_FLAGS'] = RbConfig::CONFIG['ARCH_FLAG']
 ENV['ARCH_FLAGS'] = '-arch i386 -arch x86_64' if RUBY_PLATFORM =~ /darwin/
 ENV['CFLAGS'] = '-DGPR_BACKWARDS_COMPATIBILITY_MODE'
@@ -80,7 +83,9 @@ ENV['BUILDDIR'] = output_dir
 
 unless windows
   puts 'Building internal gRPC into ' + grpc_lib_dir
-  system("make -j -C #{grpc_root} #{grpc_lib_dir}/libgrpc.a CONFIG=#{grpc_config}")
+  nproc = 4
+  nproc = Etc.nprocessors * 2 if Etc.respond_to? :nprocessors
+  system("make -j#{nproc} -C #{grpc_root} #{grpc_lib_dir}/libgrpc.a CONFIG=#{grpc_config} Q=")
   exit 1 unless $? == 0
 end
 
diff --git a/src/ruby/ext/grpc/rb_byte_buffer.c b/src/ruby/ext/grpc/rb_byte_buffer.c
index 65fa2f2cf624b08ed94e97123dbb31e9dda06794..f5be19298fdbd6279f05ad18938375f1faafd02d 100644
--- a/src/ruby/ext/grpc/rb_byte_buffer.c
+++ b/src/ruby/ext/grpc/rb_byte_buffer.c
@@ -33,15 +33,15 @@
 
 #include <ruby/ruby.h>
 
-#include "rb_grpc_imports.generated.h"
 #include "rb_byte_buffer.h"
+#include "rb_grpc_imports.generated.h"
 
-#include <grpc/grpc.h>
 #include <grpc/byte_buffer_reader.h>
+#include <grpc/grpc.h>
 #include <grpc/slice.h>
 #include "rb_grpc.h"
 
-grpc_byte_buffer* grpc_rb_s_to_byte_buffer(char *string, size_t length) {
+grpc_byte_buffer *grpc_rb_s_to_byte_buffer(char *string, size_t length) {
   grpc_slice slice = grpc_slice_from_copied_buffer(string, length);
   grpc_byte_buffer *buffer = grpc_raw_byte_buffer_create(&slice, 1);
   grpc_slice_unref(slice);
@@ -61,7 +61,7 @@ VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer) {
     return Qnil;
   }
   while (grpc_byte_buffer_reader_next(&reader, &next) != 0) {
-    rb_str_cat(rb_string, (const char *) GRPC_SLICE_START_PTR(next),
+    rb_str_cat(rb_string, (const char *)GRPC_SLICE_START_PTR(next),
                GRPC_SLICE_LENGTH(next));
     grpc_slice_unref(next);
   }
@@ -71,7 +71,9 @@ VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer) {
 
 VALUE grpc_rb_slice_to_ruby_string(grpc_slice slice) {
   if (GRPC_SLICE_START_PTR(slice) == NULL) {
-    rb_raise(rb_eRuntimeError, "attempt to convert uninitialized grpc_slice to ruby string");
+    rb_raise(rb_eRuntimeError,
+             "attempt to convert uninitialized grpc_slice to ruby string");
   }
-  return rb_str_new((char*)GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice));
+  return rb_str_new((char *)GRPC_SLICE_START_PTR(slice),
+                    GRPC_SLICE_LENGTH(slice));
 }
diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c
index 82d340b25442554d8de3f747efb8bc5c7c866297..0067e1086667f60fb1cbf8986f12f7474c78028a 100644
--- a/src/ruby/ext/grpc/rb_call.c
+++ b/src/ruby/ext/grpc/rb_call.c
@@ -33,12 +33,12 @@
 
 #include <ruby/ruby.h>
 
-#include "rb_grpc_imports.generated.h"
 #include "rb_call.h"
+#include "rb_grpc_imports.generated.h"
 
 #include <grpc/grpc.h>
-#include <grpc/support/alloc.h>
 #include <grpc/impl/codegen/compression_types.h>
+#include <grpc/support/alloc.h>
 
 #include "rb_byte_buffer.h"
 #include "rb_call_credentials.h"
@@ -101,7 +101,7 @@ typedef struct grpc_rb_call {
 static void destroy_call(grpc_rb_call *call) {
   /* Ensure that we only try to destroy the call once */
   if (call->wrapped != NULL) {
-    grpc_call_destroy(call->wrapped);
+    grpc_call_unref(call->wrapped);
     call->wrapped = NULL;
     grpc_rb_completion_queue_destroy(call->queue);
     call->queue = NULL;
@@ -113,7 +113,7 @@ static void grpc_rb_call_destroy(void *p) {
   if (p == NULL) {
     return;
   }
-  destroy_call((grpc_rb_call*)p);
+  destroy_call((grpc_rb_call *)p);
 }
 
 static size_t md_ary_datasize(const void *p) {
@@ -130,7 +130,9 @@ static size_t md_ary_datasize(const void *p) {
 
 static const rb_data_type_t grpc_rb_md_ary_data_type = {
     "grpc_metadata_array",
-    {GRPC_RB_GC_NOT_MARKED, GRPC_RB_GC_DONT_FREE, md_ary_datasize,
+    {GRPC_RB_GC_NOT_MARKED,
+     GRPC_RB_GC_DONT_FREE,
+     md_ary_datasize,
      {NULL, NULL}},
     NULL,
     NULL,
@@ -140,19 +142,20 @@ static const rb_data_type_t grpc_rb_md_ary_data_type = {
      * touches a hash object.
      * TODO(yugui) Directly use st_table and call the free function earlier?
      */
-     0,
+    0,
 #endif
 };
 
 /* Describes grpc_call struct for RTypedData */
-static const rb_data_type_t grpc_call_data_type = {
-    "grpc_call",
-    {GRPC_RB_GC_NOT_MARKED, grpc_rb_call_destroy, GRPC_RB_MEMSIZE_UNAVAILABLE,
-     {NULL, NULL}},
-    NULL,
-    NULL,
+static const rb_data_type_t grpc_call_data_type = {"grpc_call",
+                                                   {GRPC_RB_GC_NOT_MARKED,
+                                                    grpc_rb_call_destroy,
+                                                    GRPC_RB_MEMSIZE_UNAVAILABLE,
+                                                    {NULL, NULL}},
+                                                   NULL,
+                                                   NULL,
 #ifdef RUBY_TYPED_FREE_IMMEDIATELY
-    RUBY_TYPED_FREE_IMMEDIATELY
+                                                   RUBY_TYPED_FREE_IMMEDIATELY
 #endif
 };
 
@@ -175,7 +178,7 @@ static VALUE grpc_rb_call_cancel(VALUE self) {
   grpc_rb_call *call = NULL;
   grpc_call_error err;
   if (RTYPEDDATA_DATA(self) == NULL) {
-    //This call has been closed
+    // This call has been closed
     return Qnil;
   }
 
@@ -196,7 +199,7 @@ static VALUE grpc_rb_call_cancel(VALUE self) {
 static VALUE grpc_rb_call_close(VALUE self) {
   grpc_rb_call *call = NULL;
   TypedData_Get_Struct(self, grpc_rb_call, &grpc_call_data_type, call);
-  if(call != NULL) {
+  if (call != NULL) {
     destroy_call(call);
     RTYPEDDATA_DATA(self) = NULL;
   }
@@ -238,8 +241,8 @@ static VALUE grpc_rb_call_get_peer_cert(VALUE self) {
   }
 
   {
-    grpc_auth_property_iterator it =
-        grpc_auth_context_find_properties_by_name(ctx, GRPC_X509_PEM_CERT_PROPERTY_NAME);
+    grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name(
+        ctx, GRPC_X509_PEM_CERT_PROPERTY_NAME);
     const grpc_auth_property *prop = grpc_auth_property_iterator_next(&it);
     if (prop == NULL) {
       return Qnil;
@@ -388,21 +391,22 @@ static int grpc_rb_md_ary_fill_hash_cb(VALUE key, VALUE val, VALUE md_ary_obj) {
   long i;
   grpc_slice key_slice;
   grpc_slice value_slice;
-  char* tmp_str;
+  char *tmp_str;
 
   if (TYPE(key) == T_SYMBOL) {
     key_slice = grpc_slice_from_static_string(rb_id2name(SYM2ID(key)));
   } else if (TYPE(key) == T_STRING) {
-    key_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(key), RSTRING_LEN(key));
+    key_slice =
+        grpc_slice_from_copied_buffer(RSTRING_PTR(key), RSTRING_LEN(key));
   } else {
-    rb_raise(rb_eTypeError, "grpc_rb_md_ary_fill_hash_cb: bad type for key parameter");
+    rb_raise(rb_eTypeError,
+             "grpc_rb_md_ary_fill_hash_cb: bad type for key parameter");
   }
 
   if (!grpc_header_key_is_legal(key_slice)) {
     tmp_str = grpc_slice_to_c_string(key_slice);
     rb_raise(rb_eArgError,
-             "'%s' is an invalid header key, must match [a-z0-9-_.]+",
-             tmp_str);
+             "'%s' is an invalid header key, must match [a-z0-9-_.]+", tmp_str);
     return ST_STOP;
   }
 
@@ -414,13 +418,14 @@ static int grpc_rb_md_ary_fill_hash_cb(VALUE key, VALUE val, VALUE md_ary_obj) {
     array_length = RARRAY_LEN(val);
     /* If the value is an array, add capacity for each value in the array */
     for (i = 0; i < array_length; i++) {
-      value_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(rb_ary_entry(val, i)), RSTRING_LEN(rb_ary_entry(val, i)));
+      value_slice = grpc_slice_from_copied_buffer(
+          RSTRING_PTR(rb_ary_entry(val, i)), RSTRING_LEN(rb_ary_entry(val, i)));
       if (!grpc_is_binary_header(key_slice) &&
           !grpc_header_nonbin_value_is_legal(value_slice)) {
         // The value has invalid characters
         tmp_str = grpc_slice_to_c_string(value_slice);
-        rb_raise(rb_eArgError,
-                 "Header value '%s' has invalid characters", tmp_str);
+        rb_raise(rb_eArgError, "Header value '%s' has invalid characters",
+                 tmp_str);
         return ST_STOP;
       }
       md_ary->metadata[md_ary->count].key = key_slice;
@@ -428,21 +433,21 @@ static int grpc_rb_md_ary_fill_hash_cb(VALUE key, VALUE val, VALUE md_ary_obj) {
       md_ary->count += 1;
     }
   } else if (TYPE(val) == T_STRING) {
-    value_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(val), RSTRING_LEN(val));
+    value_slice =
+        grpc_slice_from_copied_buffer(RSTRING_PTR(val), RSTRING_LEN(val));
     if (!grpc_is_binary_header(key_slice) &&
         !grpc_header_nonbin_value_is_legal(value_slice)) {
       // The value has invalid characters
       tmp_str = grpc_slice_to_c_string(value_slice);
-      rb_raise(rb_eArgError,
-               "Header value '%s' has invalid characters", tmp_str);
+      rb_raise(rb_eArgError, "Header value '%s' has invalid characters",
+               tmp_str);
       return ST_STOP;
     }
     md_ary->metadata[md_ary->count].key = key_slice;
     md_ary->metadata[md_ary->count].value = value_slice;
     md_ary->count += 1;
   } else {
-    rb_raise(rb_eArgError,
-               "Header values must be of type string or array");
+    rb_raise(rb_eArgError, "Header values must be of type string or array");
     return ST_STOP;
   }
 
@@ -474,8 +479,7 @@ static int grpc_rb_md_ary_capacity_hash_cb(VALUE key, VALUE val,
 /* grpc_rb_md_ary_convert converts a ruby metadata hash into
    a grpc_metadata_array.
 */
-void grpc_rb_md_ary_convert(VALUE md_ary_hash,
-                                   grpc_metadata_array *md_ary) {
+void grpc_rb_md_ary_convert(VALUE md_ary_hash, grpc_metadata_array *md_ary) {
   VALUE md_ary_obj = Qnil;
   if (md_ary_hash == Qnil) {
     return; /* Do nothing if the expected has value is nil */
@@ -511,12 +515,14 @@ VALUE grpc_rb_md_ary_to_h(grpc_metadata_array *md_ary) {
       rb_hash_aset(result, key, value);
     } else if (TYPE(value) == T_ARRAY) {
       /* Add the string to the returned array */
-      rb_ary_push(value, grpc_rb_slice_to_ruby_string(md_ary->metadata[i].value));
+      rb_ary_push(value,
+                  grpc_rb_slice_to_ruby_string(md_ary->metadata[i].value));
     } else {
       /* Add the current value with this key and the new one to an array */
       new_ary = rb_ary_new();
       rb_ary_push(new_ary, value);
-      rb_ary_push(new_ary, grpc_rb_slice_to_ruby_string(md_ary->metadata[i].value));
+      rb_ary_push(new_ary,
+                  grpc_rb_slice_to_ruby_string(md_ary->metadata[i].value));
       rb_hash_aset(result, key, new_ary);
     }
   }
@@ -556,10 +562,9 @@ static int grpc_rb_call_check_op_keys_hash_cb(VALUE key, VALUE val,
 /* grpc_rb_op_update_status_from_server adds the values in a ruby status
    struct to the 'send_status_from_server' portion of an op.
 */
-static void grpc_rb_op_update_status_from_server(grpc_op *op,
-                                                 grpc_metadata_array *md_ary,
-                                                 grpc_slice *send_status_details,
-                                                 VALUE status) {
+static void grpc_rb_op_update_status_from_server(
+    grpc_op *op, grpc_metadata_array *md_ary, grpc_slice *send_status_details,
+    VALUE status) {
   VALUE code = rb_struct_aref(status, sym_code);
   VALUE details = rb_struct_aref(status, sym_details);
   VALUE metadata_hash = rb_struct_aref(status, sym_metadata);
@@ -576,7 +581,8 @@ static void grpc_rb_op_update_status_from_server(grpc_op *op,
     return;
   }
 
-  *send_status_details = grpc_slice_from_copied_buffer(RSTRING_PTR(details), RSTRING_LEN(details));
+  *send_status_details =
+      grpc_slice_from_copied_buffer(RSTRING_PTR(details), RSTRING_LEN(details));
 
   op->data.send_status_from_server.status = NUM2INT(code);
   op->data.send_status_from_server.status_details = send_status_details;
@@ -687,7 +693,8 @@ static void grpc_run_batch_stack_fill_ops(run_batch_stack *st, VALUE ops_hash) {
         /* N.B. later there is no need to explicitly delete the metadata keys
          * and values, they are references to data in ruby objects. */
         grpc_rb_op_update_status_from_server(
-            &st->ops[st->op_num], &st->send_trailing_metadata, &st->send_status_details, this_value);
+            &st->ops[st->op_num], &st->send_trailing_metadata,
+            &st->send_status_details, this_value);
         break;
       case GRPC_OP_RECV_INITIAL_METADATA:
         st->ops[st->op_num].data.recv_initial_metadata.recv_initial_metadata =
@@ -749,12 +756,12 @@ static VALUE grpc_run_batch_stack_build_result(run_batch_stack *st) {
       case GRPC_OP_RECV_STATUS_ON_CLIENT:
         rb_struct_aset(
             result, sym_status,
-            rb_struct_new(grpc_rb_sStatus, UINT2NUM(st->recv_status),
-                          (GRPC_SLICE_START_PTR(st->recv_status_details) == NULL
-                               ? Qnil
-                               : grpc_rb_slice_to_ruby_string(st->recv_status_details)),
-                          grpc_rb_md_ary_to_h(&st->recv_trailing_metadata),
-                          NULL));
+            rb_struct_new(
+                grpc_rb_sStatus, UINT2NUM(st->recv_status),
+                (GRPC_SLICE_START_PTR(st->recv_status_details) == NULL
+                     ? Qnil
+                     : grpc_rb_slice_to_ruby_string(st->recv_status_details)),
+                grpc_rb_md_ary_to_h(&st->recv_trailing_metadata), NULL));
         break;
       case GRPC_OP_RECV_CLOSE_ON_SERVER:
         rb_struct_aset(result, sym_send_close, Qtrue);
@@ -784,14 +791,15 @@ static VALUE grpc_run_batch_stack_build_result(run_batch_stack *st) {
    Only one operation of each type can be active at once in any given
    batch */
 static VALUE grpc_rb_call_run_batch(VALUE self, VALUE ops_hash) {
-  run_batch_stack st;
+  run_batch_stack *st = NULL;
   grpc_rb_call *call = NULL;
   grpc_event ev;
   grpc_call_error err;
   VALUE result = Qnil;
   VALUE rb_write_flag = rb_ivar_get(self, id_write_flag);
   unsigned write_flag = 0;
-  void *tag = (void*)&st;
+  void *tag = (void *)&st;
+
   if (RTYPEDDATA_DATA(self) == NULL) {
     rb_raise(grpc_rb_eCallError, "Cannot run batch on closed call");
     return Qnil;
@@ -806,14 +814,16 @@ static VALUE grpc_rb_call_run_batch(VALUE self, VALUE ops_hash) {
   if (rb_write_flag != Qnil) {
     write_flag = NUM2UINT(rb_write_flag);
   }
-  grpc_run_batch_stack_init(&st, write_flag);
-  grpc_run_batch_stack_fill_ops(&st, ops_hash);
+  st = gpr_malloc(sizeof(run_batch_stack));
+  grpc_run_batch_stack_init(st, write_flag);
+  grpc_run_batch_stack_fill_ops(st, ops_hash);
 
   /* call grpc_call_start_batch, then wait for it to complete using
    * pluck_event */
-  err = grpc_call_start_batch(call->wrapped, st.ops, st.op_num, tag, NULL);
+  err = grpc_call_start_batch(call->wrapped, st->ops, st->op_num, tag, NULL);
   if (err != GRPC_CALL_OK) {
-    grpc_run_batch_stack_cleanup(&st);
+    grpc_run_batch_stack_cleanup(st);
+    gpr_free(st);
     rb_raise(grpc_rb_eCallError,
              "grpc_call_start_batch failed with %s (code=%d)",
              grpc_call_error_detail_of(err), err);
@@ -826,8 +836,9 @@ static VALUE grpc_rb_call_run_batch(VALUE self, VALUE ops_hash) {
   }
   /* Build and return the BatchResult struct result,
      if there is an error, it's reflected in the status */
-  result = grpc_run_batch_stack_build_result(&st);
-  grpc_run_batch_stack_cleanup(&st);
+  result = grpc_run_batch_stack_build_result(st);
+  grpc_run_batch_stack_cleanup(st);
+  gpr_free(st);
   return result;
 }
 
@@ -915,7 +926,8 @@ static void Init_grpc_op_codes() {
 }
 
 static void Init_grpc_metadata_keys() {
-  VALUE grpc_rb_mMetadataKeys = rb_define_module_under(grpc_rb_mGrpcCore, "MetadataKeys");
+  VALUE grpc_rb_mMetadataKeys =
+      rb_define_module_under(grpc_rb_mGrpcCore, "MetadataKeys");
   rb_define_const(grpc_rb_mMetadataKeys, "COMPRESSION_REQUEST_ALGORITHM",
                   rb_str_new2(GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY));
 }
diff --git a/src/ruby/ext/grpc/rb_call.h b/src/ruby/ext/grpc/rb_call.h
index 56becdc5a4edfaf6101d17bb531314e6fd914d6b..dc597f7ba73c14b6f4f71d73a7266fb4ef2caa3e 100644
--- a/src/ruby/ext/grpc/rb_call.h
+++ b/src/ruby/ext/grpc/rb_call.h
@@ -39,13 +39,13 @@
 #include <grpc/grpc.h>
 
 /* Gets the wrapped call from a VALUE. */
-grpc_call* grpc_rb_get_wrapped_call(VALUE v);
+grpc_call *grpc_rb_get_wrapped_call(VALUE v);
 
 /* Gets the VALUE corresponding to given grpc_call. */
 VALUE grpc_rb_wrap_call(grpc_call *c, grpc_completion_queue *q);
 
 /* Provides the details of an call error */
-const char* grpc_call_error_detail_of(grpc_call_error err);
+const char *grpc_call_error_detail_of(grpc_call_error err);
 
 /* Converts a metadata array to a hash. */
 VALUE grpc_rb_md_ary_to_h(grpc_metadata_array *md_ary);
@@ -53,8 +53,7 @@ VALUE grpc_rb_md_ary_to_h(grpc_metadata_array *md_ary);
 /* grpc_rb_md_ary_convert converts a ruby metadata hash into
    a grpc_metadata_array.
 */
-void grpc_rb_md_ary_convert(VALUE md_ary_hash,
-                            grpc_metadata_array *md_ary);
+void grpc_rb_md_ary_convert(VALUE md_ary_hash, grpc_metadata_array *md_ary);
 
 /* grpc_rb_eCallError is the ruby class of the exception thrown during call
    operations. */
diff --git a/src/ruby/ext/grpc/rb_call_credentials.c b/src/ruby/ext/grpc/rb_call_credentials.c
index 280f21c9731c2412729455587416781ccc1e3c4e..7a5a74580d137684869582d8a286c06795ce1571 100644
--- a/src/ruby/ext/grpc/rb_call_credentials.c
+++ b/src/ruby/ext/grpc/rb_call_credentials.c
@@ -33,8 +33,8 @@
 
 #include <ruby/ruby.h>
 
-#include "rb_grpc_imports.generated.h"
 #include "rb_call_credentials.h"
+#include "rb_grpc_imports.generated.h"
 
 #include <ruby/thread.h>
 
@@ -82,20 +82,18 @@ static VALUE grpc_rb_call_credentials_callback(VALUE callback_args) {
 static VALUE grpc_rb_call_credentials_callback_rescue(VALUE args,
                                                       VALUE exception_object) {
   VALUE result = rb_hash_new();
-  VALUE backtrace = rb_funcall(
-      rb_funcall(exception_object, rb_intern("backtrace"), 0),
-      rb_intern("join"),
-      1, rb_str_new2("\n\tfrom "));
-  VALUE rb_exception_info = rb_funcall(exception_object, rb_intern("inspect"), 0);
+  VALUE backtrace =
+      rb_funcall(rb_funcall(exception_object, rb_intern("backtrace"), 0),
+                 rb_intern("join"), 1, rb_str_new2("\n\tfrom "));
+  VALUE rb_exception_info =
+      rb_funcall(exception_object, rb_intern("inspect"), 0);
   (void)args;
   gpr_log(GPR_INFO, "Call credentials callback failed: %s\n%s",
-          StringValueCStr(rb_exception_info),
-          StringValueCStr(backtrace));
+          StringValueCStr(rb_exception_info), StringValueCStr(backtrace));
   rb_hash_aset(result, rb_str_new2("metadata"), Qnil);
   rb_hash_aset(result, rb_str_new2("status"),
                INT2NUM(GRPC_STATUS_UNAUTHENTICATED));
-  rb_hash_aset(result, rb_str_new2("details"),
-               rb_exception_info);
+  rb_hash_aset(result, rb_str_new2("details"), rb_exception_info);
   return result;
 }
 
@@ -118,7 +116,8 @@ static void grpc_rb_call_credentials_callback_with_gil(void *param) {
   result = rb_rescue(grpc_rb_call_credentials_callback, callback_args,
                      grpc_rb_call_credentials_callback_rescue, Qnil);
   // Both callbacks return a hash, so result should be a hash
-  grpc_rb_md_ary_convert(rb_hash_aref(result, rb_str_new2("metadata")), &md_ary);
+  grpc_rb_md_ary_convert(rb_hash_aref(result, rb_str_new2("metadata")),
+                         &md_ary);
   status = NUM2INT(rb_hash_aref(result, rb_str_new2("status")));
   details = rb_hash_aref(result, rb_str_new2("details"));
   error_details = StringValueCStr(details);
@@ -138,7 +137,7 @@ static void grpc_rb_call_credentials_plugin_get_metadata(
   params->callback = cb;
 
   grpc_rb_event_queue_enqueue(grpc_rb_call_credentials_callback_with_gil,
-                              (void*)(params));
+                              (void *)(params));
 }
 
 static void grpc_rb_call_credentials_plugin_destroy(void *state) {
@@ -172,13 +171,15 @@ static void grpc_rb_call_credentials_mark(void *p) {
 }
 
 static rb_data_type_t grpc_rb_call_credentials_data_type = {
-  "grpc_call_credentials",
-  {grpc_rb_call_credentials_mark, grpc_rb_call_credentials_free,
-   GRPC_RB_MEMSIZE_UNAVAILABLE, {NULL, NULL}},
-  NULL,
-  NULL,
+    "grpc_call_credentials",
+    {grpc_rb_call_credentials_mark,
+     grpc_rb_call_credentials_free,
+     GRPC_RB_MEMSIZE_UNAVAILABLE,
+     {NULL, NULL}},
+    NULL,
+    NULL,
 #ifdef RUBY_TYPED_FREE_IMMEDIATELY
-  RUBY_TYPED_FREE_IMMEDIATELY
+    RUBY_TYPED_FREE_IMMEDIATELY
 #endif
 };
 
@@ -188,7 +189,8 @@ static VALUE grpc_rb_call_credentials_alloc(VALUE cls) {
   grpc_rb_call_credentials *wrapper = ALLOC(grpc_rb_call_credentials);
   wrapper->wrapped = NULL;
   wrapper->mark = Qnil;
-  return TypedData_Wrap_Struct(cls, &grpc_rb_call_credentials_data_type, wrapper);
+  return TypedData_Wrap_Struct(cls, &grpc_rb_call_credentials_data_type,
+                               wrapper);
 }
 
 /* Creates a wrapping object for a given call credentials. This should only be
@@ -221,6 +223,8 @@ static VALUE grpc_rb_call_credentials_init(VALUE self, VALUE proc) {
   grpc_call_credentials *creds = NULL;
   grpc_metadata_credentials_plugin plugin;
 
+  grpc_ruby_once_init();
+
   TypedData_Get_Struct(self, grpc_rb_call_credentials,
                        &grpc_rb_call_credentials_data_type, wrapper);
 
@@ -230,7 +234,7 @@ static VALUE grpc_rb_call_credentials_init(VALUE self, VALUE proc) {
     rb_raise(rb_eTypeError, "Argument to CallCredentials#new must be a proc");
     return Qnil;
   }
-  plugin.state = (void*)proc;
+  plugin.state = (void *)proc;
   plugin.type = "";
 
   creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL);
@@ -281,15 +285,12 @@ void Init_grpc_call_credentials() {
                    grpc_rb_call_credentials_compose, -1);
 
   id_callback = rb_intern("__callback");
-
-  grpc_rb_event_queue_thread_start();
 }
 
 /* Gets the wrapped grpc_call_credentials from the ruby wrapper */
 grpc_call_credentials *grpc_rb_get_wrapped_call_credentials(VALUE v) {
   grpc_rb_call_credentials *wrapper = NULL;
   TypedData_Get_Struct(v, grpc_rb_call_credentials,
-                       &grpc_rb_call_credentials_data_type,
-                       wrapper);
+                       &grpc_rb_call_credentials_data_type, wrapper);
   return wrapper->wrapped;
 }
diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c
index 84e43d3f7bf46937ca10d8d02d5659d6962980b7..a8021837264296d19418f08ca5b5efea7c43e19c 100644
--- a/src/ruby/ext/grpc/rb_channel.c
+++ b/src/ruby/ext/grpc/rb_channel.c
@@ -32,21 +32,22 @@
  */
 
 #include <ruby/ruby.h>
+#include <ruby/thread.h>
 
-#include "rb_grpc_imports.generated.h"
-#include "rb_channel.h"
 #include "rb_byte_buffer.h"
+#include "rb_channel.h"
+#include "rb_grpc_imports.generated.h"
 
 #include <grpc/grpc.h>
 #include <grpc/grpc_security.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
-#include "rb_grpc.h"
 #include "rb_call.h"
 #include "rb_channel_args.h"
 #include "rb_channel_credentials.h"
 #include "rb_completion_queue.h"
+#include "rb_grpc.h"
 #include "rb_server.h"
 
 /* id_channel is the name of the hidden ivar that preserves a reference to the
@@ -73,9 +74,30 @@ typedef struct grpc_rb_channel {
 
   /* The actual channel */
   grpc_channel *wrapped;
-  grpc_completion_queue *queue;
+  int request_safe_destroy;
+  int safe_to_destroy;
+  grpc_connectivity_state current_connectivity_state;
+
+  int mu_init_done;
+  int abort_watch_connectivity_state;
+  gpr_mu channel_mu;
+  gpr_cv channel_cv;
 } grpc_rb_channel;
 
+/* Forward declarations of functions involved in temporary fix to
+ * https://github.com/grpc/grpc/issues/9941 */
+static void grpc_rb_channel_try_register_connection_polling(
+    grpc_rb_channel *wrapper);
+static void grpc_rb_channel_safe_destroy(grpc_rb_channel *wrapper);
+static void *wait_until_channel_polling_thread_started_no_gil(void *);
+static void wait_until_channel_polling_thread_started_unblocking_func(void *);
+
+static grpc_completion_queue *channel_polling_cq;
+static gpr_mu global_connection_polling_mu;
+static gpr_cv global_connection_polling_cv;
+static int abort_channel_polling = 0;
+static int channel_polling_thread_started = 0;
+
 /* Destroys Channel instances. */
 static void grpc_rb_channel_free(void *p) {
   grpc_rb_channel *ch = NULL;
@@ -85,8 +107,13 @@ static void grpc_rb_channel_free(void *p) {
   ch = (grpc_rb_channel *)p;
 
   if (ch->wrapped != NULL) {
-    grpc_channel_destroy(ch->wrapped);
-    grpc_rb_completion_queue_destroy(ch->queue);
+    grpc_rb_channel_safe_destroy(ch);
+    ch->wrapped = NULL;
+  }
+
+  if (ch->mu_init_done) {
+    gpr_mu_destroy(&ch->channel_mu);
+    gpr_cv_destroy(&ch->channel_cv);
   }
 
   xfree(p);
@@ -104,13 +131,15 @@ static void grpc_rb_channel_mark(void *p) {
   }
 }
 
-static rb_data_type_t grpc_channel_data_type = {
-    "grpc_channel",
-    {grpc_rb_channel_mark, grpc_rb_channel_free, GRPC_RB_MEMSIZE_UNAVAILABLE,
-     {NULL, NULL}},
-    NULL, NULL,
+static rb_data_type_t grpc_channel_data_type = {"grpc_channel",
+                                                {grpc_rb_channel_mark,
+                                                 grpc_rb_channel_free,
+                                                 GRPC_RB_MEMSIZE_UNAVAILABLE,
+                                                 {NULL, NULL}},
+                                                NULL,
+                                                NULL,
 #ifdef RUBY_TYPED_FREE_IMMEDIATELY
-    RUBY_TYPED_FREE_IMMEDIATELY
+                                                RUBY_TYPED_FREE_IMMEDIATELY
 #endif
 };
 
@@ -141,10 +170,16 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
   grpc_channel_args args;
   MEMZERO(&args, grpc_channel_args, 1);
 
+  grpc_ruby_once_init();
+  rb_thread_call_without_gvl(
+      wait_until_channel_polling_thread_started_no_gil, NULL,
+      wait_until_channel_polling_thread_started_unblocking_func, NULL);
+
   /* "3" == 3 mandatory args */
   rb_scan_args(argc, argv, "3", &target, &channel_args, &credentials);
 
   TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
+  wrapper->mu_init_done = 0;
   target_chars = StringValueCStr(target);
   grpc_rb_hash_convert_to_channel_args(channel_args, &args);
   if (TYPE(credentials) == T_SYMBOL) {
@@ -159,6 +194,27 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
     creds = grpc_rb_get_wrapped_channel_credentials(credentials);
     ch = grpc_secure_channel_create(creds, target_chars, &args, NULL);
   }
+
+  GPR_ASSERT(ch);
+
+  wrapper->wrapped = ch;
+
+  gpr_mu_init(&wrapper->channel_mu);
+  gpr_cv_init(&wrapper->channel_cv);
+  wrapper->mu_init_done = 1;
+
+  gpr_mu_lock(&wrapper->channel_mu);
+  wrapper->abort_watch_connectivity_state = 0;
+  wrapper->current_connectivity_state =
+      grpc_channel_check_connectivity_state(wrapper->wrapped, 0);
+  wrapper->safe_to_destroy = 0;
+  wrapper->request_safe_destroy = 0;
+
+  gpr_cv_broadcast(&wrapper->channel_cv);
+  gpr_mu_unlock(&wrapper->channel_mu);
+
+  grpc_rb_channel_try_register_connection_polling(wrapper);
+
   if (args.args != NULL) {
     xfree(args.args); /* Allocated by grpc_rb_hash_convert_to_channel_args */
   }
@@ -169,25 +225,28 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
   }
   rb_ivar_set(self, id_target, target);
   wrapper->wrapped = ch;
-  wrapper->queue = grpc_completion_queue_create(NULL);
   return self;
 }
 
 /*
   call-seq:
-    insecure_channel = Channel:new("myhost:8080", {'arg1': 'value1'})
-    creds = ...
-    secure_channel = Channel:new("myhost:443", {'arg1': 'value1'}, creds)
+    ch.connectivity_state       -> state
+    ch.connectivity_state(true) -> state
 
-  Creates channel instances. */
+  Indicates the current state of the channel, whose value is one of the
+  constants defined in GRPC::Core::ConnectivityStates.
+
+  It also tries to connect if the chennel is idle in the second form. */
 static VALUE grpc_rb_channel_get_connectivity_state(int argc, VALUE *argv,
                                                     VALUE self) {
-  VALUE try_to_connect = Qfalse;
+  VALUE try_to_connect_param = Qfalse;
+  int grpc_try_to_connect = 0;
   grpc_rb_channel *wrapper = NULL;
   grpc_channel *ch = NULL;
 
   /* "01" == 0 mandatory args, 1 (try_to_connect) is optional */
-  rb_scan_args(argc, argv, "01", try_to_connect);
+  rb_scan_args(argc, argv, "01", &try_to_connect_param);
+  grpc_try_to_connect = RTEST(try_to_connect_param) ? 1 : 0;
 
   TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
   ch = wrapper->wrapped;
@@ -195,57 +254,92 @@ static VALUE grpc_rb_channel_get_connectivity_state(int argc, VALUE *argv,
     rb_raise(rb_eRuntimeError, "closed!");
     return Qnil;
   }
-  return NUM2LONG(
-      grpc_channel_check_connectivity_state(ch, (int)try_to_connect));
+  return LONG2NUM(grpc_channel_check_connectivity_state(wrapper->wrapped,
+                                                        grpc_try_to_connect));
 }
 
-/* Watch for a change in connectivity state.
+typedef struct watch_state_stack {
+  grpc_rb_channel *wrapper;
+  gpr_timespec deadline;
+  int last_state;
+} watch_state_stack;
+
+static void *watch_channel_state_without_gvl(void *arg) {
+  watch_state_stack *stack = (watch_state_stack *)arg;
+  gpr_timespec deadline = stack->deadline;
+  grpc_rb_channel *wrapper = stack->wrapper;
+  int last_state = stack->last_state;
+  void *return_value = (void *)0;
+
+  gpr_mu_lock(&wrapper->channel_mu);
+  while (wrapper->current_connectivity_state == last_state &&
+         !wrapper->request_safe_destroy && !wrapper->safe_to_destroy &&
+         !wrapper->abort_watch_connectivity_state &&
+         gpr_time_cmp(deadline, gpr_now(GPR_CLOCK_REALTIME)) > 0) {
+    gpr_cv_wait(&wrapper->channel_cv, &wrapper->channel_mu, deadline);
+  }
+  if (wrapper->current_connectivity_state != last_state) {
+    return_value = (void *)1;
+  }
+  gpr_mu_unlock(&wrapper->channel_mu);
+
+  return return_value;
+}
 
-   Once the channel connectivity state is different from the last observed
-   state, tag will be enqueued on cq with success=1
+static void watch_channel_state_unblocking_func(void *arg) {
+  grpc_rb_channel *wrapper = (grpc_rb_channel *)arg;
+  gpr_log(GPR_DEBUG, "GRPC_RUBY: watch channel state unblocking func called");
+  gpr_mu_lock(&wrapper->channel_mu);
+  wrapper->abort_watch_connectivity_state = 1;
+  gpr_cv_broadcast(&wrapper->channel_cv);
+  gpr_mu_unlock(&wrapper->channel_mu);
+}
 
-   If deadline expires BEFORE the state is changed, tag will be enqueued on
-   the completion queue with success=0 */
+/* Wait until the channel's connectivity state becomes different from
+ * "last_state", or "deadline" expires.
+ * Returns true if the the channel's connectivity state becomes
+ * different from "last_state" within "deadline".
+ * Returns false if "deadline" expires before the channel's connectivity
+ * state changes from "last_state".
+ * */
 static VALUE grpc_rb_channel_watch_connectivity_state(VALUE self,
                                                       VALUE last_state,
                                                       VALUE deadline) {
   grpc_rb_channel *wrapper = NULL;
-  grpc_channel *ch = NULL;
-  grpc_completion_queue *cq = NULL;
-
-  void *tag = wrapper;
-
-  grpc_event event;
+  watch_state_stack stack;
+  void *out;
 
   TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
-  ch = wrapper->wrapped;
-  cq = wrapper->queue;
-  if (ch == NULL) {
+
+  if (wrapper->wrapped == NULL) {
     rb_raise(rb_eRuntimeError, "closed!");
     return Qnil;
   }
-  grpc_channel_watch_connectivity_state(
-      ch,
-      (grpc_connectivity_state)NUM2LONG(last_state),
-      grpc_rb_time_timeval(deadline, /* absolute time */ 0),
-      cq,
-      tag);
 
-  event = rb_completion_queue_pluck(cq, tag,
-                                    gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+  if (!FIXNUM_P(last_state)) {
+    rb_raise(
+        rb_eTypeError,
+        "bad type for last_state. want a GRPC::Core::ChannelState constant");
+    return Qnil;
+  }
 
-  if (event.success) {
+  stack.wrapper = wrapper;
+  stack.deadline = grpc_rb_time_timeval(deadline, 0);
+  stack.last_state = NUM2LONG(last_state);
+  out =
+      rb_thread_call_without_gvl(watch_channel_state_without_gvl, &stack,
+                                 watch_channel_state_unblocking_func, wrapper);
+  if (out) {
     return Qtrue;
-  } else {
-    return Qfalse;
   }
+  return Qfalse;
 }
 
 /* Create a call given a grpc_channel, in order to call method. The request
    is not sent until grpc_call_invoke is called. */
-static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent,
-                                         VALUE mask, VALUE method,
-                                         VALUE host, VALUE deadline) {
+static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent, VALUE mask,
+                                         VALUE method, VALUE host,
+                                         VALUE deadline) {
   VALUE res = Qnil;
   grpc_rb_channel *wrapper = NULL;
   grpc_call *call = NULL;
@@ -256,10 +350,11 @@ static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent,
   grpc_slice method_slice;
   grpc_slice host_slice;
   grpc_slice *host_slice_ptr = NULL;
-  char* tmp_str = NULL;
+  char *tmp_str = NULL;
 
   if (host != Qnil) {
-    host_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(host), RSTRING_LEN(host));
+    host_slice =
+        grpc_slice_from_copied_buffer(RSTRING_PTR(host), RSTRING_LEN(host));
     host_slice_ptr = &host_slice;
   }
   if (mask != Qnil) {
@@ -269,7 +364,7 @@ static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent,
     parent_call = grpc_rb_get_wrapped_call(parent);
   }
 
-  cq = grpc_completion_queue_create(NULL);
+  cq = grpc_completion_queue_create_for_pluck(NULL);
   TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
   ch = wrapper->wrapped;
   if (ch == NULL) {
@@ -277,17 +372,18 @@ static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent,
     return Qnil;
   }
 
-  method_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(method), RSTRING_LEN(method));
+  method_slice =
+      grpc_slice_from_copied_buffer(RSTRING_PTR(method), RSTRING_LEN(method));
 
   call = grpc_channel_create_call(ch, parent_call, flags, cq, method_slice,
-                                  host_slice_ptr, grpc_rb_time_timeval(
-                                      deadline,
-                                      /* absolute time */ 0), NULL);
+                                  host_slice_ptr,
+                                  grpc_rb_time_timeval(deadline,
+                                                       /* absolute time */ 0),
+                                  NULL);
 
   if (call == NULL) {
     tmp_str = grpc_slice_to_c_string(method_slice);
-    rb_raise(rb_eRuntimeError, "cannot create call with method %s",
-             tmp_str);
+    rb_raise(rb_eRuntimeError, "cannot create call with method %s", tmp_str);
     return Qnil;
   }
 
@@ -304,7 +400,6 @@ static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent,
   return res;
 }
 
-
 /* Closes the channel, calling it's destroy method */
 static VALUE grpc_rb_channel_destroy(VALUE self) {
   grpc_rb_channel *wrapper = NULL;
@@ -313,19 +408,18 @@ static VALUE grpc_rb_channel_destroy(VALUE self) {
   TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
   ch = wrapper->wrapped;
   if (ch != NULL) {
-    grpc_channel_destroy(ch);
+    grpc_rb_channel_safe_destroy(wrapper);
     wrapper->wrapped = NULL;
   }
 
   return Qnil;
 }
 
-
 /* Called to obtain the target that this channel accesses. */
 static VALUE grpc_rb_channel_get_target(VALUE self) {
   grpc_rb_channel *wrapper = NULL;
   VALUE res = Qnil;
-  char* target = NULL;
+  char *target = NULL;
 
   TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
   target = grpc_channel_get_target(wrapper->wrapped);
@@ -335,10 +429,180 @@ static VALUE grpc_rb_channel_get_target(VALUE self) {
   return res;
 }
 
+// Either start polling channel connection state or signal that it's free to
+// destroy.
+// Not safe to call while a channel's connection state is polled.
+static void grpc_rb_channel_try_register_connection_polling(
+    grpc_rb_channel *wrapper) {
+  grpc_connectivity_state conn_state;
+  gpr_timespec sleep_time = gpr_time_add(
+      gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(20, GPR_TIMESPAN));
+
+  GPR_ASSERT(wrapper);
+  GPR_ASSERT(wrapper->wrapped);
+  gpr_mu_lock(&wrapper->channel_mu);
+  if (wrapper->request_safe_destroy) {
+    wrapper->safe_to_destroy = 1;
+    gpr_cv_broadcast(&wrapper->channel_cv);
+    gpr_mu_unlock(&wrapper->channel_mu);
+    return;
+  }
+  gpr_mu_lock(&global_connection_polling_mu);
+
+  GPR_ASSERT(channel_polling_thread_started || abort_channel_polling);
+  conn_state = grpc_channel_check_connectivity_state(wrapper->wrapped, 0);
+  if (conn_state != wrapper->current_connectivity_state) {
+    wrapper->current_connectivity_state = conn_state;
+    gpr_cv_broadcast(&wrapper->channel_cv);
+  }
+  // avoid posting work to the channel polling cq if it's been shutdown
+  if (!abort_channel_polling && conn_state != GRPC_CHANNEL_SHUTDOWN) {
+    grpc_channel_watch_connectivity_state(
+        wrapper->wrapped, conn_state, sleep_time, channel_polling_cq, wrapper);
+  } else {
+    wrapper->safe_to_destroy = 1;
+    gpr_cv_broadcast(&wrapper->channel_cv);
+  }
+  gpr_mu_unlock(&global_connection_polling_mu);
+  gpr_mu_unlock(&wrapper->channel_mu);
+}
+
+// Note requires wrapper->wrapped, wrapper->channel_mu/cv initialized
+static void grpc_rb_channel_safe_destroy(grpc_rb_channel *wrapper) {
+  gpr_mu_lock(&wrapper->channel_mu);
+  wrapper->request_safe_destroy = 1;
+
+  while (!wrapper->safe_to_destroy) {
+    gpr_cv_wait(&wrapper->channel_cv, &wrapper->channel_mu,
+                gpr_inf_future(GPR_CLOCK_REALTIME));
+  }
+  GPR_ASSERT(wrapper->safe_to_destroy);
+  gpr_mu_unlock(&wrapper->channel_mu);
+
+  grpc_channel_destroy(wrapper->wrapped);
+}
+
+// Note this loop breaks out with a single call of
+// "run_poll_channels_loop_no_gil".
+// This assumes that a ruby call the unblocking func
+// indicates process shutdown.
+// In the worst case, this stops polling channel connectivity
+// early and falls back to current behavior.
+static void *run_poll_channels_loop_no_gil(void *arg) {
+  grpc_event event;
+  (void)arg;
+  gpr_log(GPR_DEBUG, "GRPC_RUBY: run_poll_channels_loop_no_gil - begin");
+
+  gpr_mu_lock(&global_connection_polling_mu);
+  GPR_ASSERT(!channel_polling_thread_started);
+  channel_polling_thread_started = 1;
+  gpr_cv_broadcast(&global_connection_polling_cv);
+  gpr_mu_unlock(&global_connection_polling_mu);
+
+  for (;;) {
+    event = grpc_completion_queue_next(
+        channel_polling_cq, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+    if (event.type == GRPC_QUEUE_SHUTDOWN) {
+      break;
+    }
+    if (event.type == GRPC_OP_COMPLETE) {
+      grpc_rb_channel_try_register_connection_polling(
+          (grpc_rb_channel *)event.tag);
+    }
+  }
+  grpc_completion_queue_destroy(channel_polling_cq);
+  gpr_log(GPR_DEBUG,
+          "GRPC_RUBY: run_poll_channels_loop_no_gil - exit connection polling "
+          "loop");
+  return NULL;
+}
+
+// Notify the channel polling loop to cleanup and shutdown.
+static void run_poll_channels_loop_unblocking_func(void *arg) {
+  (void)arg;
+  gpr_mu_lock(&global_connection_polling_mu);
+  gpr_log(GPR_DEBUG,
+          "GRPC_RUBY: grpc_rb_event_unblocking_func - begin aborting "
+          "connection polling");
+  abort_channel_polling = 1;
+  grpc_completion_queue_shutdown(channel_polling_cq);
+  gpr_mu_unlock(&global_connection_polling_mu);
+}
+
+// Poll channel connectivity states in background thread without the GIL.
+static VALUE run_poll_channels_loop(VALUE arg) {
+  (void)arg;
+  gpr_log(
+      GPR_DEBUG,
+      "GRPC_RUBY: run_poll_channels_loop - create connection polling thread");
+  rb_thread_call_without_gvl(run_poll_channels_loop_no_gil, NULL,
+                             run_poll_channels_loop_unblocking_func, NULL);
+
+  return Qnil;
+}
+
+static void *wait_until_channel_polling_thread_started_no_gil(void *arg) {
+  (void)arg;
+  gpr_log(GPR_DEBUG, "GRPC_RUBY: wait for channel polling thread to start");
+  gpr_mu_lock(&global_connection_polling_mu);
+  while (!channel_polling_thread_started && !abort_channel_polling) {
+    gpr_cv_wait(&global_connection_polling_cv, &global_connection_polling_mu,
+                gpr_inf_future(GPR_CLOCK_REALTIME));
+  }
+  gpr_mu_unlock(&global_connection_polling_mu);
+
+  return NULL;
+}
+
+static void wait_until_channel_polling_thread_started_unblocking_func(
+    void *arg) {
+  (void)arg;
+  gpr_mu_lock(&global_connection_polling_mu);
+  gpr_log(GPR_DEBUG,
+          "GRPC_RUBY: "
+          "wait_until_channel_polling_thread_started_unblocking_func - begin "
+          "aborting connection polling");
+  abort_channel_polling = 1;
+  gpr_cv_broadcast(&global_connection_polling_cv);
+  gpr_mu_unlock(&global_connection_polling_mu);
+}
+
+/* Temporary fix for
+ * https://github.com/GoogleCloudPlatform/google-cloud-ruby/issues/899.
+ * Transports in idle channels can get destroyed. Normally c-core re-connects,
+ * but in grpc-ruby core never gets a thread until an RPC is made, because ruby
+ * only calls c-core's "completion_queu_pluck" API.
+ * This uses a global background thread that calls
+ * "completion_queue_next" on registered "watch_channel_connectivity_state"
+ * calls - so that c-core can reconnect if needed, when there aren't any RPC's.
+ * TODO(apolcyn) remove this when core handles new RPCs on dead connections.
+ */
+void grpc_rb_channel_polling_thread_start() {
+  VALUE background_thread = Qnil;
+
+  GPR_ASSERT(!abort_channel_polling);
+  GPR_ASSERT(!channel_polling_thread_started);
+  GPR_ASSERT(channel_polling_cq == NULL);
+
+  gpr_mu_init(&global_connection_polling_mu);
+  gpr_cv_init(&global_connection_polling_cv);
+
+  channel_polling_cq = grpc_completion_queue_create_for_next(NULL);
+  background_thread = rb_thread_create(run_poll_channels_loop, NULL);
+
+  if (!RTEST(background_thread)) {
+    gpr_log(GPR_DEBUG, "GRPC_RUBY: failed to spawn channel polling thread");
+    gpr_mu_lock(&global_connection_polling_mu);
+    abort_channel_polling = 1;
+    gpr_cv_broadcast(&global_connection_polling_cv);
+    gpr_mu_unlock(&global_connection_polling_mu);
+  }
+}
+
 static void Init_grpc_propagate_masks() {
   /* Constants representing call propagation masks in grpc.h */
-  VALUE grpc_rb_mPropagateMasks = rb_define_module_under(
-      grpc_rb_mGrpcCore, "PropagateMasks");
+  VALUE grpc_rb_mPropagateMasks =
+      rb_define_module_under(grpc_rb_mGrpcCore, "PropagateMasks");
   rb_define_const(grpc_rb_mPropagateMasks, "DEADLINE",
                   UINT2NUM(GRPC_PROPAGATE_DEADLINE));
   rb_define_const(grpc_rb_mPropagateMasks, "CENSUS_STATS_CONTEXT",
@@ -353,8 +617,8 @@ static void Init_grpc_propagate_masks() {
 
 static void Init_grpc_connectivity_states() {
   /* Constants representing call propagation masks in grpc.h */
-  VALUE grpc_rb_mConnectivityStates = rb_define_module_under(
-      grpc_rb_mGrpcCore, "ConnectivityStates");
+  VALUE grpc_rb_mConnectivityStates =
+      rb_define_module_under(grpc_rb_mGrpcCore, "ConnectivityStates");
   rb_define_const(grpc_rb_mConnectivityStates, "IDLE",
                   LONG2NUM(GRPC_CHANNEL_IDLE));
   rb_define_const(grpc_rb_mConnectivityStates, "CONNECTING",
@@ -382,12 +646,11 @@ void Init_grpc_channel() {
 
   /* Add ruby analogues of the Channel methods. */
   rb_define_method(grpc_rb_cChannel, "connectivity_state",
-                   grpc_rb_channel_get_connectivity_state,
-                   -1);
+                   grpc_rb_channel_get_connectivity_state, -1);
   rb_define_method(grpc_rb_cChannel, "watch_connectivity_state",
-                   grpc_rb_channel_watch_connectivity_state, 4);
-  rb_define_method(grpc_rb_cChannel, "create_call",
-                   grpc_rb_channel_create_call, 5);
+                   grpc_rb_channel_watch_connectivity_state, 2);
+  rb_define_method(grpc_rb_cChannel, "create_call", grpc_rb_channel_create_call,
+                   5);
   rb_define_method(grpc_rb_cChannel, "target", grpc_rb_channel_get_target, 0);
   rb_define_method(grpc_rb_cChannel, "destroy", grpc_rb_channel_destroy, 0);
   rb_define_alias(grpc_rb_cChannel, "close", "destroy");
diff --git a/src/ruby/ext/grpc/rb_channel.h b/src/ruby/ext/grpc/rb_channel.h
index 77e1f6acbca9dac26fa3f5969f17e5cc86a171fb..fdceb79bca5181d9aabe50c7353f8f05db6f96fe 100644
--- a/src/ruby/ext/grpc/rb_channel.h
+++ b/src/ruby/ext/grpc/rb_channel.h
@@ -41,6 +41,8 @@
 /* Initializes the Channel class. */
 void Init_grpc_channel();
 
+void grpc_rb_channel_polling_thread_start();
+
 /* Gets the wrapped channel from the ruby wrapper */
 grpc_channel* grpc_rb_get_wrapped_channel(VALUE v);
 
diff --git a/src/ruby/ext/grpc/rb_channel_args.c b/src/ruby/ext/grpc/rb_channel_args.c
index 87c0e0a7055bec5cac7210669aa475e439bb4d6d..fa9ddee37281e32fdfde808aa711280b1c6629ce 100644
--- a/src/ruby/ext/grpc/rb_channel_args.c
+++ b/src/ruby/ext/grpc/rb_channel_args.c
@@ -33,8 +33,8 @@
 
 #include <ruby/ruby.h>
 
-#include "rb_grpc_imports.generated.h"
 #include "rb_channel_args.h"
+#include "rb_grpc_imports.generated.h"
 
 #include <grpc/grpc.h>
 
@@ -42,9 +42,12 @@
 
 static rb_data_type_t grpc_rb_channel_args_data_type = {
     "grpc_channel_args",
-    {GRPC_RB_GC_NOT_MARKED, GRPC_RB_GC_DONT_FREE, GRPC_RB_MEMSIZE_UNAVAILABLE,
+    {GRPC_RB_GC_NOT_MARKED,
+     GRPC_RB_GC_DONT_FREE,
+     GRPC_RB_MEMSIZE_UNAVAILABLE,
      {NULL, NULL}},
-    NULL, NULL,
+    NULL,
+    NULL,
 #ifdef RUBY_TYPED_FREE_IMMEDIATELY
     RUBY_TYPED_FREE_IMMEDIATELY
 #endif
@@ -137,11 +140,10 @@ static VALUE grpc_rb_hash_convert_to_channel_args0(VALUE as_value) {
     params->dst->num_args = num_args;
     params->dst->args = ALLOC_N(grpc_arg, num_args);
     MEMZERO(params->dst->args, grpc_arg, num_args);
-    rb_hash_foreach(params->src_hash,
-                    grpc_rb_channel_create_in_process_add_args_hash_cb,
-                    TypedData_Wrap_Struct(grpc_rb_cChannelArgs,
-                                          &grpc_rb_channel_args_data_type,
-                                          params->dst));
+    rb_hash_foreach(
+        params->src_hash, grpc_rb_channel_create_in_process_add_args_hash_cb,
+        TypedData_Wrap_Struct(grpc_rb_cChannelArgs,
+                              &grpc_rb_channel_args_data_type, params->dst));
     /* reset num_args as grpc_rb_channel_create_in_process_add_args_hash_cb
      * decrements it during has processing */
     params->dst->num_args = num_args;
@@ -157,7 +159,7 @@ void grpc_rb_hash_convert_to_channel_args(VALUE src_hash,
   /* Make a protected call to grpc_rb_hash_convert_channel_args */
   params.src_hash = src_hash;
   params.dst = dst;
-  rb_protect(grpc_rb_hash_convert_to_channel_args0, (VALUE) & params, &status);
+  rb_protect(grpc_rb_hash_convert_to_channel_args0, (VALUE)&params, &status);
   if (status != 0) {
     if (dst->args != NULL) {
       /* Free any allocated memory before propagating the error */
diff --git a/src/ruby/ext/grpc/rb_channel_credentials.c b/src/ruby/ext/grpc/rb_channel_credentials.c
index 5b7aa3417e6ce300a2bd561eec43d0266ab8b44e..db713ed8216d10cd477394217a325f43b5a954e0 100644
--- a/src/ruby/ext/grpc/rb_channel_credentials.c
+++ b/src/ruby/ext/grpc/rb_channel_credentials.c
@@ -35,8 +35,8 @@
 
 #include <string.h>
 
-#include "rb_grpc_imports.generated.h"
 #include "rb_channel_credentials.h"
+#include "rb_grpc_imports.generated.h"
 
 #include <grpc/grpc.h>
 #include <grpc/grpc_security.h>
@@ -91,8 +91,10 @@ static void grpc_rb_channel_credentials_mark(void *p) {
 
 static rb_data_type_t grpc_rb_channel_credentials_data_type = {
     "grpc_channel_credentials",
-    {grpc_rb_channel_credentials_mark, grpc_rb_channel_credentials_free,
-     GRPC_RB_MEMSIZE_UNAVAILABLE, {NULL, NULL}},
+    {grpc_rb_channel_credentials_mark,
+     grpc_rb_channel_credentials_free,
+     GRPC_RB_MEMSIZE_UNAVAILABLE,
+     {NULL, NULL}},
     NULL,
     NULL,
 #ifdef RUBY_TYPED_FREE_IMMEDIATELY
@@ -106,13 +108,15 @@ static VALUE grpc_rb_channel_credentials_alloc(VALUE cls) {
   grpc_rb_channel_credentials *wrapper = ALLOC(grpc_rb_channel_credentials);
   wrapper->wrapped = NULL;
   wrapper->mark = Qnil;
-  return TypedData_Wrap_Struct(cls, &grpc_rb_channel_credentials_data_type, wrapper);
+  return TypedData_Wrap_Struct(cls, &grpc_rb_channel_credentials_data_type,
+                               wrapper);
 }
 
 /* Creates a wrapping object for a given channel credentials. This should only
  * be called with grpc_channel_credentials objects that are not already
  * associated with any Ruby object. */
-VALUE grpc_rb_wrap_channel_credentials(grpc_channel_credentials *c, VALUE mark) {
+VALUE grpc_rb_wrap_channel_credentials(grpc_channel_credentials *c,
+                                       VALUE mark) {
   VALUE rb_wrapper;
   grpc_rb_channel_credentials *wrapper;
   if (c == NULL) {
@@ -147,7 +151,8 @@ static ID id_pem_cert_chain;
     pem_private_key: (optional) PEM encoding of the client's private key
     pem_cert_chain: (optional) PEM encoding of the client's cert chain
     Initializes Credential instances. */
-static VALUE grpc_rb_channel_credentials_init(int argc, VALUE *argv, VALUE self) {
+static VALUE grpc_rb_channel_credentials_init(int argc, VALUE *argv,
+                                              VALUE self) {
   VALUE pem_root_certs = Qnil;
   VALUE pem_private_key = Qnil;
   VALUE pem_cert_chain = Qnil;
@@ -156,6 +161,9 @@ static VALUE grpc_rb_channel_credentials_init(int argc, VALUE *argv, VALUE self)
   grpc_ssl_pem_key_cert_pair key_cert_pair;
   const char *pem_root_certs_cstr = NULL;
   MEMZERO(&key_cert_pair, grpc_ssl_pem_key_cert_pair, 1);
+
+  grpc_ruby_once_init();
+
   /* "03" == no mandatory arg, 3 optional */
   rb_scan_args(argc, argv, "03", &pem_root_certs, &pem_private_key,
                &pem_cert_chain);
@@ -170,8 +178,8 @@ static VALUE grpc_rb_channel_credentials_init(int argc, VALUE *argv, VALUE self)
   } else {
     key_cert_pair.private_key = RSTRING_PTR(pem_private_key);
     key_cert_pair.cert_chain = RSTRING_PTR(pem_cert_chain);
-    creds = grpc_ssl_credentials_create(pem_root_certs_cstr,
-                                        &key_cert_pair, NULL);
+    creds =
+        grpc_ssl_credentials_create(pem_root_certs_cstr, &key_cert_pair, NULL);
   }
   if (creds == NULL) {
     rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why");
@@ -230,8 +238,8 @@ static VALUE grpc_rb_set_default_roots_pem(VALUE self, VALUE roots) {
 }
 
 void Init_grpc_channel_credentials() {
-  grpc_rb_cChannelCredentials =
-      rb_define_class_under(grpc_rb_mGrpcCore, "ChannelCredentials", rb_cObject);
+  grpc_rb_cChannelCredentials = rb_define_class_under(
+      grpc_rb_mGrpcCore, "ChannelCredentials", rb_cObject);
 
   /* Allocates an object managed by the ruby runtime */
   rb_define_alloc_func(grpc_rb_cChannelCredentials,
@@ -259,7 +267,6 @@ void Init_grpc_channel_credentials() {
 grpc_channel_credentials *grpc_rb_get_wrapped_channel_credentials(VALUE v) {
   grpc_rb_channel_credentials *wrapper = NULL;
   TypedData_Get_Struct(v, grpc_rb_channel_credentials,
-                       &grpc_rb_channel_credentials_data_type,
-                       wrapper);
+                       &grpc_rb_channel_credentials_data_type, wrapper);
   return wrapper->wrapped;
 }
diff --git a/src/ruby/ext/grpc/rb_completion_queue.c b/src/ruby/ext/grpc/rb_completion_queue.c
index fd75d2f691f38039aca516885406990eda9da8aa..c9d67739a5f87dbedaf217f8953474fb03a75886 100644
--- a/src/ruby/ext/grpc/rb_completion_queue.c
+++ b/src/ruby/ext/grpc/rb_completion_queue.c
@@ -33,14 +33,14 @@
 
 #include <ruby/ruby.h>
 
-#include "rb_grpc_imports.generated.h"
 #include "rb_completion_queue.h"
+#include "rb_grpc_imports.generated.h"
 
 #include <ruby/thread.h>
 
 #include <grpc/grpc.h>
-#include <grpc/support/time.h>
 #include <grpc/support/log.h>
+#include <grpc/support/time.h>
 #include "rb_grpc.h"
 
 /* Used to allow grpc_completion_queue_next call to release the GIL */
@@ -54,14 +54,13 @@ typedef struct next_call_stack {
 
 /* Calls grpc_completion_queue_pluck without holding the ruby GIL */
 static void *grpc_rb_completion_queue_pluck_no_gil(void *param) {
-  next_call_stack *const next_call = (next_call_stack*)param;
+  next_call_stack *const next_call = (next_call_stack *)param;
   gpr_timespec increment = gpr_time_from_millis(20, GPR_TIMESPAN);
   gpr_timespec deadline;
   do {
     deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), increment);
-    next_call->event = grpc_completion_queue_pluck(next_call->cq,
-                                                   next_call->tag,
-                                                   deadline, NULL);
+    next_call->event = grpc_completion_queue_pluck(
+        next_call->cq, next_call->tag, deadline, NULL);
     if (next_call->event.type != GRPC_QUEUE_TIMEOUT ||
         gpr_time_cmp(deadline, next_call->timeout) > 0) {
       break;
@@ -81,7 +80,7 @@ void grpc_rb_completion_queue_destroy(grpc_completion_queue *cq) {
 }
 
 static void unblock_func(void *param) {
-  next_call_stack *const next_call = (next_call_stack*)param;
+  next_call_stack *const next_call = (next_call_stack *)param;
   next_call->interrupted = 1;
 }
 
@@ -111,7 +110,6 @@ grpc_event rb_completion_queue_pluck(grpc_completion_queue *queue, void *tag,
                                (void *)&next_call);
     /* If an interrupt prevented pluck from returning useful information, then
        any plucks that did complete must have timed out */
-  } while (next_call.interrupted &&
-           next_call.event.type == GRPC_QUEUE_TIMEOUT);
+  } while (next_call.interrupted && next_call.event.type == GRPC_QUEUE_TIMEOUT);
   return next_call.event;
 }
diff --git a/src/ruby/ext/grpc/rb_compression_options.c b/src/ruby/ext/grpc/rb_compression_options.c
index 6b2467ee4614decf0fee6f5ac28638230cc8df33..45c963dca6eddefd7aaff59c22d0588da3075cd2 100644
--- a/src/ruby/ext/grpc/rb_compression_options.c
+++ b/src/ruby/ext/grpc/rb_compression_options.c
@@ -33,15 +33,15 @@
 
 #include <ruby/ruby.h>
 
-#include "rb_compression_options.h"
 #include "rb_byte_buffer.h"
+#include "rb_compression_options.h"
 #include "rb_grpc_imports.generated.h"
 
 #include <grpc/compression.h>
 #include <grpc/grpc.h>
-#include <grpc/support/alloc.h>
 #include <grpc/impl/codegen/compression_types.h>
 #include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/support/alloc.h>
 #include <string.h>
 
 #include "rb_grpc.h"
@@ -100,8 +100,11 @@ static rb_data_type_t grpc_rb_compression_options_data_type = {
    Allocate the wrapped grpc compression options and
    initialize it here too. */
 static VALUE grpc_rb_compression_options_alloc(VALUE cls) {
-  grpc_rb_compression_options *wrapper =
-      gpr_malloc(sizeof(grpc_rb_compression_options));
+  grpc_rb_compression_options *wrapper = NULL;
+
+  grpc_ruby_once_init();
+
+  wrapper = gpr_malloc(sizeof(grpc_rb_compression_options));
   wrapper->wrapped = NULL;
   wrapper->wrapped = gpr_malloc(sizeof(grpc_compression_options));
   grpc_compression_options_init(wrapper->wrapped);
@@ -179,15 +182,16 @@ void grpc_rb_compression_options_algorithm_name_to_value_internal(
    * correct C string out of it. */
   algorithm_name_as_string = rb_funcall(algorithm_name, rb_intern("to_s"), 0);
 
-  name_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(algorithm_name_as_string), RSTRING_LEN(algorithm_name_as_string));
+  name_slice =
+      grpc_slice_from_copied_buffer(RSTRING_PTR(algorithm_name_as_string),
+                                    RSTRING_LEN(algorithm_name_as_string));
 
   /* Raise an error if the name isn't recognized as a compression algorithm by
    * the algorithm parse function
    * in GRPC core. */
-  if(!grpc_compression_algorithm_parse(name_slice, algorithm_value)) {
+  if (!grpc_compression_algorithm_parse(name_slice, algorithm_value)) {
     tmp_str = grpc_slice_to_c_string(name_slice);
-    rb_raise(rb_eNameError, "Invalid compression algorithm name: %s",
-             tmp_str);
+    rb_raise(rb_eNameError, "Invalid compression algorithm name: %s", tmp_str);
   }
 
   grpc_slice_unref(name_slice);
diff --git a/src/ruby/ext/grpc/rb_event_thread.c b/src/ruby/ext/grpc/rb_event_thread.c
index 9e85bbcfbf2f46e2b8cfb89792d83995de77b1b1..9a3b56ddfb73fbc0334cbd1b1ff2f950fb84c3a4 100644
--- a/src/ruby/ext/grpc/rb_event_thread.c
+++ b/src/ruby/ext/grpc/rb_event_thread.c
@@ -33,20 +33,20 @@
 
 #include <ruby/ruby.h>
 
-#include "rb_grpc_imports.generated.h"
 #include "rb_event_thread.h"
+#include "rb_grpc_imports.generated.h"
 
 #include <stdbool.h>
 
-#include <ruby/thread.h>
 #include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
-#include <grpc/support/log.h>
+#include <ruby/thread.h>
 
 typedef struct grpc_rb_event {
   // callback will be called with argument while holding the GVL
-  void (*callback)(void*);
+  void (*callback)(void *);
   void *argument;
 
   struct grpc_rb_event *next;
@@ -65,8 +65,7 @@ typedef struct grpc_rb_event_queue {
 
 static grpc_rb_event_queue event_queue;
 
-void grpc_rb_event_queue_enqueue(void (*callback)(void*),
-                                 void *argument) {
+void grpc_rb_event_queue_enqueue(void (*callback)(void *), void *argument) {
   grpc_rb_event *event = gpr_malloc(sizeof(grpc_rb_event));
   event->callback = callback;
   event->argument = argument;
@@ -107,8 +106,7 @@ static void *grpc_rb_wait_for_event_no_gil(void *param) {
   (void)param;
   gpr_mu_lock(&event_queue.mu);
   while ((event = grpc_rb_event_queue_dequeue()) == NULL) {
-    gpr_cv_wait(&event_queue.cv,
-                &event_queue.mu,
+    gpr_cv_wait(&event_queue.cv, &event_queue.mu,
                 gpr_inf_future(GPR_CLOCK_REALTIME));
     if (event_queue.abort) {
       gpr_mu_unlock(&event_queue.mu);
@@ -132,10 +130,10 @@ static void grpc_rb_event_unblocking_func(void *arg) {
 static VALUE grpc_rb_event_thread(VALUE arg) {
   grpc_rb_event *event;
   (void)arg;
-  while(true) {
-    event = (grpc_rb_event*)rb_thread_call_without_gvl(
-        grpc_rb_wait_for_event_no_gil, NULL,
-        grpc_rb_event_unblocking_func, NULL);
+  while (true) {
+    event = (grpc_rb_event *)rb_thread_call_without_gvl(
+        grpc_rb_wait_for_event_no_gil, NULL, grpc_rb_event_unblocking_func,
+        NULL);
     if (event == NULL) {
       // Indicates that the thread needs to shut down
       break;
diff --git a/src/ruby/ext/grpc/rb_event_thread.h b/src/ruby/ext/grpc/rb_event_thread.h
index 46638bfcf531680c46ebbd761993128ed1e47e51..d7eff760a1797888bf7e6d4d1e07b5340e8c162f 100644
--- a/src/ruby/ext/grpc/rb_event_thread.h
+++ b/src/ruby/ext/grpc/rb_event_thread.h
@@ -33,5 +33,4 @@
 
 void grpc_rb_event_queue_thread_start();
 
-void grpc_rb_event_queue_enqueue(void (*callback)(void*),
-                                 void *argument);
+void grpc_rb_event_queue_enqueue(void (*callback)(void *), void *argument);
diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c
index 17cd165a91da4abb29e95bd2f3ee588f3841d14e..5be8861e0c4c68b7169098e0263bd2b6af9b7fe1 100644
--- a/src/ruby/ext/grpc/rb_grpc.c
+++ b/src/ruby/ext/grpc/rb_grpc.c
@@ -33,8 +33,8 @@
 
 #include <ruby/ruby.h>
 
-#include "rb_grpc_imports.generated.h"
 #include "rb_grpc.h"
+#include "rb_grpc_imports.generated.h"
 
 #include <math.h>
 #include <ruby/vm.h>
@@ -46,16 +46,19 @@
 #include "rb_call_credentials.h"
 #include "rb_channel.h"
 #include "rb_channel_credentials.h"
+#include "rb_compression_options.h"
+#include "rb_event_thread.h"
 #include "rb_loader.h"
 #include "rb_server.h"
 #include "rb_server_credentials.h"
-#include "rb_compression_options.h"
 
 static VALUE grpc_rb_cTimeVal = Qnil;
 
 static rb_data_type_t grpc_rb_timespec_data_type = {
     "gpr_timespec",
-    {GRPC_RB_GC_NOT_MARKED, GRPC_RB_GC_DONT_FREE, GRPC_RB_MEMSIZE_UNAVAILABLE,
+    {GRPC_RB_GC_NOT_MARKED,
+     GRPC_RB_GC_DONT_FREE,
+     GRPC_RB_MEMSIZE_UNAVAILABLE,
      {NULL, NULL}},
     NULL,
     NULL,
@@ -84,8 +87,7 @@ VALUE grpc_rb_cannot_init(VALUE self) {
 /* Init/Clone func that fails by raising an exception. */
 VALUE grpc_rb_cannot_init_copy(VALUE copy, VALUE self) {
   (void)self;
-  rb_raise(rb_eTypeError,
-           "Copy initialization of %s is not supported",
+  rb_raise(rb_eTypeError, "Copy initialization of %s is not supported",
            rb_obj_classname(copy));
   return Qnil;
 }
@@ -143,8 +145,7 @@ gpr_timespec grpc_rb_time_timeval(VALUE time, int interval) {
         }
         t.tv_sec = (int64_t)f;
         if (f != t.tv_sec) {
-          rb_raise(rb_eRangeError, "%f out of Time range",
-                   RFLOAT_VALUE(time));
+          rb_raise(rb_eRangeError, "%f out of Time range", RFLOAT_VALUE(time));
         }
         t.tv_nsec = (int)(d * 1e9 + 0.5);
       }
@@ -269,9 +270,7 @@ static void Init_grpc_time_consts() {
   id_tv_nsec = rb_intern("tv_nsec");
 }
 
-static void grpc_rb_shutdown(void) {
-  grpc_shutdown();
-}
+static void grpc_rb_shutdown(void) { grpc_shutdown(); }
 
 /* Initialize the GRPC module structs */
 
@@ -291,17 +290,14 @@ VALUE sym_metadata = Qundef;
 
 static gpr_once g_once_init = GPR_ONCE_INIT;
 
-static void grpc_ruby_once_init() {
+static void grpc_ruby_once_init_internal() {
   grpc_init();
+  grpc_rb_event_queue_thread_start();
+  grpc_rb_channel_polling_thread_start();
   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;
-  }
-
+void grpc_ruby_once_init() {
   /* 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
@@ -312,13 +308,19 @@ void Init_grpc_c() {
    * 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);
+  gpr_once_init(&g_once_init, grpc_ruby_once_init_internal);
+}
+
+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_rb_mGRPC = rb_define_module("GRPC");
   grpc_rb_mGrpcCore = rb_define_module_under(grpc_rb_mGRPC, "Core");
-  grpc_rb_sNewServerRpc =
-      rb_struct_define("NewServerRpc", "method", "host",
-                       "deadline", "metadata", "call", NULL);
+  grpc_rb_sNewServerRpc = rb_struct_define(
+      "NewServerRpc", "method", "host", "deadline", "metadata", "call", NULL);
   grpc_rb_sStatus =
       rb_struct_define("Status", "code", "details", "metadata", NULL);
   sym_code = ID2SYM(rb_intern("code"));
diff --git a/src/ruby/ext/grpc/rb_grpc.h b/src/ruby/ext/grpc/rb_grpc.h
index 6ea6cbd0b6c98d2655869260e3a01a5762cabb76..8538a74211bfce08768f4a750a1ac241da8a0f0f 100644
--- a/src/ruby/ext/grpc/rb_grpc.h
+++ b/src/ruby/ext/grpc/rb_grpc.h
@@ -34,8 +34,8 @@
 #ifndef GRPC_RB_H_
 #define GRPC_RB_H_
 
-#include <sys/time.h>
 #include <ruby/ruby.h>
+#include <sys/time.h>
 
 #include <grpc/support/time.h>
 
@@ -68,7 +68,7 @@ extern VALUE sym_metadata;
 
 /* GRPC_RB_MEMSIZE_UNAVAILABLE is used in rb_data_type_t to indicate that the
  * number of bytes used by the wrapped struct is not available. */
-#define GRPC_RB_MEMSIZE_UNAVAILABLE (size_t (*)(const void*))(NULL)
+#define GRPC_RB_MEMSIZE_UNAVAILABLE (size_t(*)(const void*))(NULL)
 
 /* A ruby object alloc func that fails by raising an exception. */
 VALUE grpc_rb_cannot_alloc(VALUE cls);
@@ -82,4 +82,6 @@ VALUE grpc_rb_cannot_init_copy(VALUE copy, VALUE self);
 /* grpc_rb_time_timeval creates a gpr_timespec from a ruby time object. */
 gpr_timespec grpc_rb_time_timeval(VALUE time, int interval);
 
+void grpc_ruby_once_init();
+
 #endif /* GRPC_RB_H_ */
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index 52465a4dd70527ecf2c6fd066b5deb6118d5aa5c..221a1e14ec73f185d27f30511c9a64bddc059403 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
@@ -91,6 +91,9 @@ grpc_init_type grpc_init_import;
 grpc_shutdown_type grpc_shutdown_import;
 grpc_version_string_type grpc_version_string_import;
 grpc_g_stands_for_type grpc_g_stands_for_import;
+grpc_completion_queue_factory_lookup_type grpc_completion_queue_factory_lookup_import;
+grpc_completion_queue_create_for_next_type grpc_completion_queue_create_for_next_import;
+grpc_completion_queue_create_for_pluck_type grpc_completion_queue_create_for_pluck_import;
 grpc_completion_queue_create_type grpc_completion_queue_create_import;
 grpc_completion_queue_next_type grpc_completion_queue_next_import;
 grpc_completion_queue_pluck_type grpc_completion_queue_pluck_import;
@@ -105,9 +108,9 @@ grpc_channel_create_call_type grpc_channel_create_call_import;
 grpc_channel_ping_type grpc_channel_ping_import;
 grpc_channel_register_call_type grpc_channel_register_call_import;
 grpc_channel_create_registered_call_type grpc_channel_create_registered_call_import;
+grpc_call_arena_alloc_type grpc_call_arena_alloc_import;
 grpc_call_start_batch_type grpc_call_start_batch_import;
 grpc_call_get_peer_type grpc_call_get_peer_import;
-grpc_call_set_load_reporting_cost_context_type grpc_call_set_load_reporting_cost_context_import;
 grpc_census_call_set_context_type grpc_census_call_set_context_import;
 grpc_census_call_get_context_type grpc_census_call_get_context_import;
 grpc_channel_get_target_type grpc_channel_get_target_import;
@@ -117,13 +120,13 @@ grpc_lame_client_channel_create_type grpc_lame_client_channel_create_import;
 grpc_channel_destroy_type grpc_channel_destroy_import;
 grpc_call_cancel_type grpc_call_cancel_import;
 grpc_call_cancel_with_status_type grpc_call_cancel_with_status_import;
-grpc_call_destroy_type grpc_call_destroy_import;
+grpc_call_ref_type grpc_call_ref_import;
+grpc_call_unref_type grpc_call_unref_import;
 grpc_server_request_call_type grpc_server_request_call_import;
 grpc_server_register_method_type grpc_server_register_method_import;
 grpc_server_request_registered_call_type grpc_server_request_registered_call_import;
 grpc_server_create_type grpc_server_create_import;
 grpc_server_register_completion_queue_type grpc_server_register_completion_queue_import;
-grpc_server_register_non_listening_completion_queue_type grpc_server_register_non_listening_completion_queue_import;
 grpc_server_add_insecure_http2_port_type grpc_server_add_insecure_http2_port_import;
 grpc_server_start_type grpc_server_start_import;
 grpc_server_shutdown_and_notify_type grpc_server_shutdown_and_notify_import;
@@ -176,10 +179,12 @@ grpc_call_set_credentials_type grpc_call_set_credentials_import;
 grpc_server_credentials_set_auth_metadata_processor_type grpc_server_credentials_set_auth_metadata_processor_import;
 grpc_slice_ref_type grpc_slice_ref_import;
 grpc_slice_unref_type grpc_slice_unref_import;
+grpc_slice_copy_type grpc_slice_copy_import;
 grpc_slice_new_type grpc_slice_new_import;
 grpc_slice_new_with_user_data_type grpc_slice_new_with_user_data_import;
 grpc_slice_new_with_len_type grpc_slice_new_with_len_import;
 grpc_slice_malloc_type grpc_slice_malloc_import;
+grpc_slice_malloc_large_type grpc_slice_malloc_large_import;
 grpc_slice_intern_type grpc_slice_intern_import;
 grpc_slice_from_copied_string_type grpc_slice_from_copied_string_import;
 grpc_slice_from_copied_buffer_type grpc_slice_from_copied_buffer_import;
@@ -188,6 +193,7 @@ grpc_slice_from_static_buffer_type grpc_slice_from_static_buffer_import;
 grpc_slice_sub_type grpc_slice_sub_import;
 grpc_slice_sub_no_ref_type grpc_slice_sub_no_ref_import;
 grpc_slice_split_tail_type grpc_slice_split_tail_import;
+grpc_slice_split_tail_maybe_ref_type grpc_slice_split_tail_maybe_ref_import;
 grpc_slice_split_head_type grpc_slice_split_head_import;
 grpc_empty_slice_type grpc_empty_slice_import;
 grpc_slice_default_hash_impl_type grpc_slice_default_hash_impl_import;
@@ -216,6 +222,7 @@ grpc_slice_buffer_swap_type grpc_slice_buffer_swap_import;
 grpc_slice_buffer_move_into_type grpc_slice_buffer_move_into_import;
 grpc_slice_buffer_trim_end_type grpc_slice_buffer_trim_end_import;
 grpc_slice_buffer_move_first_type grpc_slice_buffer_move_first_import;
+grpc_slice_buffer_move_first_no_ref_type grpc_slice_buffer_move_first_no_ref_import;
 grpc_slice_buffer_move_first_into_buffer_type grpc_slice_buffer_move_first_into_buffer_import;
 grpc_slice_buffer_take_first_type grpc_slice_buffer_take_first_import;
 grpc_slice_buffer_undo_take_first_type grpc_slice_buffer_undo_take_first_import;
@@ -296,6 +303,7 @@ 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_ref_is_unique_type gpr_ref_is_unique_import;
 gpr_stats_init_type gpr_stats_init_import;
 gpr_stats_inc_type gpr_stats_inc_import;
 gpr_stats_read_type gpr_stats_read_import;
@@ -384,6 +392,9 @@ void grpc_rb_load_imports(HMODULE library) {
   grpc_shutdown_import = (grpc_shutdown_type) GetProcAddress(library, "grpc_shutdown");
   grpc_version_string_import = (grpc_version_string_type) GetProcAddress(library, "grpc_version_string");
   grpc_g_stands_for_import = (grpc_g_stands_for_type) GetProcAddress(library, "grpc_g_stands_for");
+  grpc_completion_queue_factory_lookup_import = (grpc_completion_queue_factory_lookup_type) GetProcAddress(library, "grpc_completion_queue_factory_lookup");
+  grpc_completion_queue_create_for_next_import = (grpc_completion_queue_create_for_next_type) GetProcAddress(library, "grpc_completion_queue_create_for_next");
+  grpc_completion_queue_create_for_pluck_import = (grpc_completion_queue_create_for_pluck_type) GetProcAddress(library, "grpc_completion_queue_create_for_pluck");
   grpc_completion_queue_create_import = (grpc_completion_queue_create_type) GetProcAddress(library, "grpc_completion_queue_create");
   grpc_completion_queue_next_import = (grpc_completion_queue_next_type) GetProcAddress(library, "grpc_completion_queue_next");
   grpc_completion_queue_pluck_import = (grpc_completion_queue_pluck_type) GetProcAddress(library, "grpc_completion_queue_pluck");
@@ -398,9 +409,9 @@ void grpc_rb_load_imports(HMODULE library) {
   grpc_channel_ping_import = (grpc_channel_ping_type) GetProcAddress(library, "grpc_channel_ping");
   grpc_channel_register_call_import = (grpc_channel_register_call_type) GetProcAddress(library, "grpc_channel_register_call");
   grpc_channel_create_registered_call_import = (grpc_channel_create_registered_call_type) GetProcAddress(library, "grpc_channel_create_registered_call");
+  grpc_call_arena_alloc_import = (grpc_call_arena_alloc_type) GetProcAddress(library, "grpc_call_arena_alloc");
   grpc_call_start_batch_import = (grpc_call_start_batch_type) GetProcAddress(library, "grpc_call_start_batch");
   grpc_call_get_peer_import = (grpc_call_get_peer_type) GetProcAddress(library, "grpc_call_get_peer");
-  grpc_call_set_load_reporting_cost_context_import = (grpc_call_set_load_reporting_cost_context_type) GetProcAddress(library, "grpc_call_set_load_reporting_cost_context");
   grpc_census_call_set_context_import = (grpc_census_call_set_context_type) GetProcAddress(library, "grpc_census_call_set_context");
   grpc_census_call_get_context_import = (grpc_census_call_get_context_type) GetProcAddress(library, "grpc_census_call_get_context");
   grpc_channel_get_target_import = (grpc_channel_get_target_type) GetProcAddress(library, "grpc_channel_get_target");
@@ -410,13 +421,13 @@ void grpc_rb_load_imports(HMODULE library) {
   grpc_channel_destroy_import = (grpc_channel_destroy_type) GetProcAddress(library, "grpc_channel_destroy");
   grpc_call_cancel_import = (grpc_call_cancel_type) GetProcAddress(library, "grpc_call_cancel");
   grpc_call_cancel_with_status_import = (grpc_call_cancel_with_status_type) GetProcAddress(library, "grpc_call_cancel_with_status");
-  grpc_call_destroy_import = (grpc_call_destroy_type) GetProcAddress(library, "grpc_call_destroy");
+  grpc_call_ref_import = (grpc_call_ref_type) GetProcAddress(library, "grpc_call_ref");
+  grpc_call_unref_import = (grpc_call_unref_type) GetProcAddress(library, "grpc_call_unref");
   grpc_server_request_call_import = (grpc_server_request_call_type) GetProcAddress(library, "grpc_server_request_call");
   grpc_server_register_method_import = (grpc_server_register_method_type) GetProcAddress(library, "grpc_server_register_method");
   grpc_server_request_registered_call_import = (grpc_server_request_registered_call_type) GetProcAddress(library, "grpc_server_request_registered_call");
   grpc_server_create_import = (grpc_server_create_type) GetProcAddress(library, "grpc_server_create");
   grpc_server_register_completion_queue_import = (grpc_server_register_completion_queue_type) GetProcAddress(library, "grpc_server_register_completion_queue");
-  grpc_server_register_non_listening_completion_queue_import = (grpc_server_register_non_listening_completion_queue_type) GetProcAddress(library, "grpc_server_register_non_listening_completion_queue");
   grpc_server_add_insecure_http2_port_import = (grpc_server_add_insecure_http2_port_type) GetProcAddress(library, "grpc_server_add_insecure_http2_port");
   grpc_server_start_import = (grpc_server_start_type) GetProcAddress(library, "grpc_server_start");
   grpc_server_shutdown_and_notify_import = (grpc_server_shutdown_and_notify_type) GetProcAddress(library, "grpc_server_shutdown_and_notify");
@@ -469,10 +480,12 @@ void grpc_rb_load_imports(HMODULE library) {
   grpc_server_credentials_set_auth_metadata_processor_import = (grpc_server_credentials_set_auth_metadata_processor_type) GetProcAddress(library, "grpc_server_credentials_set_auth_metadata_processor");
   grpc_slice_ref_import = (grpc_slice_ref_type) GetProcAddress(library, "grpc_slice_ref");
   grpc_slice_unref_import = (grpc_slice_unref_type) GetProcAddress(library, "grpc_slice_unref");
+  grpc_slice_copy_import = (grpc_slice_copy_type) GetProcAddress(library, "grpc_slice_copy");
   grpc_slice_new_import = (grpc_slice_new_type) GetProcAddress(library, "grpc_slice_new");
   grpc_slice_new_with_user_data_import = (grpc_slice_new_with_user_data_type) GetProcAddress(library, "grpc_slice_new_with_user_data");
   grpc_slice_new_with_len_import = (grpc_slice_new_with_len_type) GetProcAddress(library, "grpc_slice_new_with_len");
   grpc_slice_malloc_import = (grpc_slice_malloc_type) GetProcAddress(library, "grpc_slice_malloc");
+  grpc_slice_malloc_large_import = (grpc_slice_malloc_large_type) GetProcAddress(library, "grpc_slice_malloc_large");
   grpc_slice_intern_import = (grpc_slice_intern_type) GetProcAddress(library, "grpc_slice_intern");
   grpc_slice_from_copied_string_import = (grpc_slice_from_copied_string_type) GetProcAddress(library, "grpc_slice_from_copied_string");
   grpc_slice_from_copied_buffer_import = (grpc_slice_from_copied_buffer_type) GetProcAddress(library, "grpc_slice_from_copied_buffer");
@@ -481,6 +494,7 @@ void grpc_rb_load_imports(HMODULE library) {
   grpc_slice_sub_import = (grpc_slice_sub_type) GetProcAddress(library, "grpc_slice_sub");
   grpc_slice_sub_no_ref_import = (grpc_slice_sub_no_ref_type) GetProcAddress(library, "grpc_slice_sub_no_ref");
   grpc_slice_split_tail_import = (grpc_slice_split_tail_type) GetProcAddress(library, "grpc_slice_split_tail");
+  grpc_slice_split_tail_maybe_ref_import = (grpc_slice_split_tail_maybe_ref_type) GetProcAddress(library, "grpc_slice_split_tail_maybe_ref");
   grpc_slice_split_head_import = (grpc_slice_split_head_type) GetProcAddress(library, "grpc_slice_split_head");
   grpc_empty_slice_import = (grpc_empty_slice_type) GetProcAddress(library, "grpc_empty_slice");
   grpc_slice_default_hash_impl_import = (grpc_slice_default_hash_impl_type) GetProcAddress(library, "grpc_slice_default_hash_impl");
@@ -509,6 +523,7 @@ void grpc_rb_load_imports(HMODULE library) {
   grpc_slice_buffer_move_into_import = (grpc_slice_buffer_move_into_type) GetProcAddress(library, "grpc_slice_buffer_move_into");
   grpc_slice_buffer_trim_end_import = (grpc_slice_buffer_trim_end_type) GetProcAddress(library, "grpc_slice_buffer_trim_end");
   grpc_slice_buffer_move_first_import = (grpc_slice_buffer_move_first_type) GetProcAddress(library, "grpc_slice_buffer_move_first");
+  grpc_slice_buffer_move_first_no_ref_import = (grpc_slice_buffer_move_first_no_ref_type) GetProcAddress(library, "grpc_slice_buffer_move_first_no_ref");
   grpc_slice_buffer_move_first_into_buffer_import = (grpc_slice_buffer_move_first_into_buffer_type) GetProcAddress(library, "grpc_slice_buffer_move_first_into_buffer");
   grpc_slice_buffer_take_first_import = (grpc_slice_buffer_take_first_type) GetProcAddress(library, "grpc_slice_buffer_take_first");
   grpc_slice_buffer_undo_take_first_import = (grpc_slice_buffer_undo_take_first_type) GetProcAddress(library, "grpc_slice_buffer_undo_take_first");
@@ -589,6 +604,7 @@ void grpc_rb_load_imports(HMODULE library) {
   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_ref_is_unique_import = (gpr_ref_is_unique_type) GetProcAddress(library, "gpr_ref_is_unique");
   gpr_stats_init_import = (gpr_stats_init_type) GetProcAddress(library, "gpr_stats_init");
   gpr_stats_inc_import = (gpr_stats_inc_type) GetProcAddress(library, "gpr_stats_inc");
   gpr_stats_read_import = (gpr_stats_read_type) GetProcAddress(library, "gpr_stats_read");
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index b16e6738781abc30871609d5328f7fa04b2c5faa..f62b31e83d083e3a0399267d06a5bc015ae4edde 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -224,7 +224,16 @@ extern grpc_version_string_type grpc_version_string_import;
 typedef const char *(*grpc_g_stands_for_type)(void);
 extern grpc_g_stands_for_type grpc_g_stands_for_import;
 #define grpc_g_stands_for grpc_g_stands_for_import
-typedef grpc_completion_queue *(*grpc_completion_queue_create_type)(void *reserved);
+typedef const grpc_completion_queue_factory *(*grpc_completion_queue_factory_lookup_type)(const grpc_completion_queue_attributes *attributes);
+extern grpc_completion_queue_factory_lookup_type grpc_completion_queue_factory_lookup_import;
+#define grpc_completion_queue_factory_lookup grpc_completion_queue_factory_lookup_import
+typedef grpc_completion_queue *(*grpc_completion_queue_create_for_next_type)(void *reserved);
+extern grpc_completion_queue_create_for_next_type grpc_completion_queue_create_for_next_import;
+#define grpc_completion_queue_create_for_next grpc_completion_queue_create_for_next_import
+typedef grpc_completion_queue *(*grpc_completion_queue_create_for_pluck_type)(void *reserved);
+extern grpc_completion_queue_create_for_pluck_type grpc_completion_queue_create_for_pluck_import;
+#define grpc_completion_queue_create_for_pluck grpc_completion_queue_create_for_pluck_import
+typedef grpc_completion_queue *(*grpc_completion_queue_create_type)(const grpc_completion_queue_factory *factory, const grpc_completion_queue_attributes *attributes, void *reserved);
 extern grpc_completion_queue_create_type grpc_completion_queue_create_import;
 #define grpc_completion_queue_create grpc_completion_queue_create_import
 typedef grpc_event(*grpc_completion_queue_next_type)(grpc_completion_queue *cq, gpr_timespec deadline, void *reserved);
@@ -266,15 +275,15 @@ extern grpc_channel_register_call_type grpc_channel_register_call_import;
 typedef grpc_call *(*grpc_channel_create_registered_call_type)(grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *completion_queue, void *registered_call_handle, gpr_timespec deadline, void *reserved);
 extern grpc_channel_create_registered_call_type grpc_channel_create_registered_call_import;
 #define grpc_channel_create_registered_call grpc_channel_create_registered_call_import
+typedef void *(*grpc_call_arena_alloc_type)(grpc_call *call, size_t size);
+extern grpc_call_arena_alloc_type grpc_call_arena_alloc_import;
+#define grpc_call_arena_alloc grpc_call_arena_alloc_import
 typedef grpc_call_error(*grpc_call_start_batch_type)(grpc_call *call, const grpc_op *ops, size_t nops, void *tag, void *reserved);
 extern grpc_call_start_batch_type grpc_call_start_batch_import;
 #define grpc_call_start_batch grpc_call_start_batch_import
 typedef char *(*grpc_call_get_peer_type)(grpc_call *call);
 extern grpc_call_get_peer_type grpc_call_get_peer_import;
 #define grpc_call_get_peer grpc_call_get_peer_import
-typedef void(*grpc_call_set_load_reporting_cost_context_type)(grpc_call *call, struct grpc_load_reporting_cost_context *context);
-extern grpc_call_set_load_reporting_cost_context_type grpc_call_set_load_reporting_cost_context_import;
-#define grpc_call_set_load_reporting_cost_context grpc_call_set_load_reporting_cost_context_import
 typedef void(*grpc_census_call_set_context_type)(grpc_call *call, struct census_context *context);
 extern grpc_census_call_set_context_type grpc_census_call_set_context_import;
 #define grpc_census_call_set_context grpc_census_call_set_context_import
@@ -302,9 +311,12 @@ extern grpc_call_cancel_type grpc_call_cancel_import;
 typedef grpc_call_error(*grpc_call_cancel_with_status_type)(grpc_call *call, grpc_status_code status, const char *description, void *reserved);
 extern grpc_call_cancel_with_status_type grpc_call_cancel_with_status_import;
 #define grpc_call_cancel_with_status grpc_call_cancel_with_status_import
-typedef void(*grpc_call_destroy_type)(grpc_call *call);
-extern grpc_call_destroy_type grpc_call_destroy_import;
-#define grpc_call_destroy grpc_call_destroy_import
+typedef void(*grpc_call_ref_type)(grpc_call *call);
+extern grpc_call_ref_type grpc_call_ref_import;
+#define grpc_call_ref grpc_call_ref_import
+typedef void(*grpc_call_unref_type)(grpc_call *call);
+extern grpc_call_unref_type grpc_call_unref_import;
+#define grpc_call_unref grpc_call_unref_import
 typedef grpc_call_error(*grpc_server_request_call_type)(grpc_server *server, grpc_call **call, grpc_call_details *details, grpc_metadata_array *request_metadata, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new);
 extern grpc_server_request_call_type grpc_server_request_call_import;
 #define grpc_server_request_call grpc_server_request_call_import
@@ -320,9 +332,6 @@ extern grpc_server_create_type grpc_server_create_import;
 typedef void(*grpc_server_register_completion_queue_type)(grpc_server *server, grpc_completion_queue *cq, void *reserved);
 extern grpc_server_register_completion_queue_type grpc_server_register_completion_queue_import;
 #define grpc_server_register_completion_queue grpc_server_register_completion_queue_import
-typedef void(*grpc_server_register_non_listening_completion_queue_type)(grpc_server *server, grpc_completion_queue *q, void *reserved);
-extern grpc_server_register_non_listening_completion_queue_type grpc_server_register_non_listening_completion_queue_import;
-#define grpc_server_register_non_listening_completion_queue grpc_server_register_non_listening_completion_queue_import
 typedef int(*grpc_server_add_insecure_http2_port_type)(grpc_server *server, const char *addr);
 extern grpc_server_add_insecure_http2_port_type grpc_server_add_insecure_http2_port_import;
 #define grpc_server_add_insecure_http2_port grpc_server_add_insecure_http2_port_import
@@ -479,6 +488,9 @@ extern grpc_slice_ref_type grpc_slice_ref_import;
 typedef void(*grpc_slice_unref_type)(grpc_slice s);
 extern grpc_slice_unref_type grpc_slice_unref_import;
 #define grpc_slice_unref grpc_slice_unref_import
+typedef grpc_slice(*grpc_slice_copy_type)(grpc_slice s);
+extern grpc_slice_copy_type grpc_slice_copy_import;
+#define grpc_slice_copy grpc_slice_copy_import
 typedef grpc_slice(*grpc_slice_new_type)(void *p, size_t len, void (*destroy)(void *));
 extern grpc_slice_new_type grpc_slice_new_import;
 #define grpc_slice_new grpc_slice_new_import
@@ -491,6 +503,9 @@ extern grpc_slice_new_with_len_type grpc_slice_new_with_len_import;
 typedef grpc_slice(*grpc_slice_malloc_type)(size_t length);
 extern grpc_slice_malloc_type grpc_slice_malloc_import;
 #define grpc_slice_malloc grpc_slice_malloc_import
+typedef grpc_slice(*grpc_slice_malloc_large_type)(size_t length);
+extern grpc_slice_malloc_large_type grpc_slice_malloc_large_import;
+#define grpc_slice_malloc_large grpc_slice_malloc_large_import
 typedef grpc_slice(*grpc_slice_intern_type)(grpc_slice slice);
 extern grpc_slice_intern_type grpc_slice_intern_import;
 #define grpc_slice_intern grpc_slice_intern_import
@@ -515,6 +530,9 @@ extern grpc_slice_sub_no_ref_type grpc_slice_sub_no_ref_import;
 typedef grpc_slice(*grpc_slice_split_tail_type)(grpc_slice *s, size_t split);
 extern grpc_slice_split_tail_type grpc_slice_split_tail_import;
 #define grpc_slice_split_tail grpc_slice_split_tail_import
+typedef grpc_slice(*grpc_slice_split_tail_maybe_ref_type)(grpc_slice *s, size_t split, grpc_slice_ref_whom ref_whom);
+extern grpc_slice_split_tail_maybe_ref_type grpc_slice_split_tail_maybe_ref_import;
+#define grpc_slice_split_tail_maybe_ref grpc_slice_split_tail_maybe_ref_import
 typedef grpc_slice(*grpc_slice_split_head_type)(grpc_slice *s, size_t split);
 extern grpc_slice_split_head_type grpc_slice_split_head_import;
 #define grpc_slice_split_head grpc_slice_split_head_import
@@ -599,6 +617,9 @@ extern grpc_slice_buffer_trim_end_type grpc_slice_buffer_trim_end_import;
 typedef void(*grpc_slice_buffer_move_first_type)(grpc_slice_buffer *src, size_t n, grpc_slice_buffer *dst);
 extern grpc_slice_buffer_move_first_type grpc_slice_buffer_move_first_import;
 #define grpc_slice_buffer_move_first grpc_slice_buffer_move_first_import
+typedef void(*grpc_slice_buffer_move_first_no_ref_type)(grpc_slice_buffer *src, size_t n, grpc_slice_buffer *dst);
+extern grpc_slice_buffer_move_first_no_ref_type grpc_slice_buffer_move_first_no_ref_import;
+#define grpc_slice_buffer_move_first_no_ref grpc_slice_buffer_move_first_no_ref_import
 typedef void(*grpc_slice_buffer_move_first_into_buffer_type)(grpc_exec_ctx *exec_ctx, grpc_slice_buffer *src, size_t n, void *dst);
 extern grpc_slice_buffer_move_first_into_buffer_type grpc_slice_buffer_move_first_into_buffer_import;
 #define grpc_slice_buffer_move_first_into_buffer grpc_slice_buffer_move_first_into_buffer_import
@@ -839,6 +860,9 @@ extern gpr_refn_type gpr_refn_import;
 typedef int(*gpr_unref_type)(gpr_refcount *r);
 extern gpr_unref_type gpr_unref_import;
 #define gpr_unref gpr_unref_import
+typedef int(*gpr_ref_is_unique_type)(gpr_refcount *r);
+extern gpr_ref_is_unique_type gpr_ref_is_unique_import;
+#define gpr_ref_is_unique gpr_ref_is_unique_import
 typedef void(*gpr_stats_init_type)(gpr_stats_counter *c, intptr_t n);
 extern gpr_stats_init_type gpr_stats_init_import;
 #define gpr_stats_init gpr_stats_init_import
diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c
index 7b2f5774aa1170c234bf1fcdb55ef926ff8350bf..d7408f683dbf47ef641929a56f9dd8b2caa05104 100644
--- a/src/ruby/ext/grpc/rb_server.c
+++ b/src/ruby/ext/grpc/rb_server.c
@@ -37,15 +37,15 @@
 #include "rb_server.h"
 
 #include <grpc/grpc.h>
-#include <grpc/support/atm.h>
 #include <grpc/grpc_security.h>
+#include <grpc/support/atm.h>
 #include <grpc/support/log.h>
+#include "rb_byte_buffer.h"
 #include "rb_call.h"
 #include "rb_channel_args.h"
 #include "rb_completion_queue.h"
-#include "rb_server_credentials.h"
-#include "rb_byte_buffer.h"
 #include "rb_grpc.h"
+#include "rb_server_credentials.h"
 
 /* grpc_rb_cServer is the ruby class that proxies grpc_server. */
 static VALUE grpc_rb_cServer = Qnil;
@@ -93,9 +93,8 @@ static void grpc_rb_server_free(void *p) {
   };
   svr = (grpc_rb_server *)p;
 
-  deadline = gpr_time_add(
-      gpr_now(GPR_CLOCK_REALTIME),
-      gpr_time_from_seconds(2, GPR_TIMESPAN));
+  deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+                          gpr_time_from_seconds(2, GPR_TIMESPAN));
 
   destroy_server(svr, deadline);
 
@@ -104,13 +103,15 @@ static void grpc_rb_server_free(void *p) {
 
 static const rb_data_type_t grpc_rb_server_data_type = {
     "grpc_server",
-    {GRPC_RB_GC_NOT_MARKED, grpc_rb_server_free, GRPC_RB_MEMSIZE_UNAVAILABLE,
+    {GRPC_RB_GC_NOT_MARKED,
+     grpc_rb_server_free,
+     GRPC_RB_MEMSIZE_UNAVAILABLE,
      {NULL, NULL}},
     NULL,
     NULL,
 #ifdef RUBY_TYPED_FREE_IMMEDIATELY
-    /* It is unsafe to specify RUBY_TYPED_FREE_IMMEDIATELY because the free function would block
-     * and we might want to unlock GVL
+    /* It is unsafe to specify RUBY_TYPED_FREE_IMMEDIATELY because the free
+     * function would block and we might want to unlock GVL
      * TODO(yugui) Unlock GVL?
      */
     0,
@@ -131,11 +132,15 @@ static VALUE grpc_rb_server_alloc(VALUE cls) {
 
   Initializes server instances. */
 static VALUE grpc_rb_server_init(VALUE self, VALUE channel_args) {
-  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+  grpc_completion_queue *cq = NULL;
   grpc_rb_server *wrapper = NULL;
   grpc_server *srv = NULL;
   grpc_channel_args args;
   MEMZERO(&args, grpc_channel_args, 1);
+
+  grpc_ruby_once_init();
+
+  cq = grpc_completion_queue_create_for_pluck(NULL);
   TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type,
                        wrapper);
   grpc_rb_hash_convert_to_channel_args(channel_args, &args);
@@ -163,7 +168,7 @@ typedef struct request_call_stack {
 
 /* grpc_request_call_stack_init ensures the request_call_stack is properly
  * initialized */
-static void grpc_request_call_stack_init(request_call_stack* st) {
+static void grpc_request_call_stack_init(request_call_stack *st) {
   MEMZERO(st, request_call_stack, 1);
   grpc_metadata_array_init(&st->md_ary);
   grpc_call_details_init(&st->details);
@@ -171,7 +176,7 @@ static void grpc_request_call_stack_init(request_call_stack* st) {
 
 /* grpc_request_call_stack_cleanup ensures the request_call_stack is properly
  * cleaned up */
-static void grpc_request_call_stack_cleanup(request_call_stack* st) {
+static void grpc_request_call_stack_cleanup(request_call_stack *st) {
   grpc_metadata_array_destroy(&st->md_ary);
   grpc_call_details_destroy(&st->details);
 }
@@ -187,8 +192,9 @@ static VALUE grpc_rb_server_request_call(VALUE self) {
   grpc_call_error err;
   request_call_stack st;
   VALUE result;
-  void *tag = (void*)&st;
-  grpc_completion_queue *call_queue = grpc_completion_queue_create(NULL);
+  void *tag = (void *)&st;
+  grpc_completion_queue *call_queue =
+      grpc_completion_queue_create_for_pluck(NULL);
   gpr_timespec deadline;
 
   TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
@@ -199,9 +205,8 @@ static VALUE grpc_rb_server_request_call(VALUE self) {
   grpc_request_call_stack_init(&st);
   /* call grpc_server_request_call, then wait for it to complete using
    * pluck_event */
-  err = grpc_server_request_call(
-      s->wrapped, &call, &st.details, &st.md_ary,
-      call_queue, s->queue, tag);
+  err = grpc_server_request_call(s->wrapped, &call, &st.details, &st.md_ary,
+                                 call_queue, s->queue, tag);
   if (err != GRPC_CALL_OK) {
     grpc_request_call_stack_cleanup(&st);
     rb_raise(grpc_rb_eCallError,
@@ -218,8 +223,6 @@ static VALUE grpc_rb_server_request_call(VALUE self) {
     return Qnil;
   }
 
-
-
   /* build the NewServerRpc struct result */
   deadline = gpr_convert_clock_type(st.details.deadline, GPR_CLOCK_REALTIME);
   result = rb_struct_new(
@@ -299,8 +302,7 @@ static VALUE grpc_rb_server_add_http2_port(VALUE self, VALUE port,
     return Qnil;
   } else if (TYPE(rb_creds) == T_SYMBOL) {
     if (id_insecure_server != SYM2ID(rb_creds)) {
-      rb_raise(rb_eTypeError,
-               "bad creds symbol, want :this_port_is_insecure");
+      rb_raise(rb_eTypeError, "bad creds symbol, want :this_port_is_insecure");
       return Qnil;
     }
     recvd_port =
@@ -312,9 +314,8 @@ static VALUE grpc_rb_server_add_http2_port(VALUE self, VALUE port,
     }
   } else {
     creds = grpc_rb_get_wrapped_server_credentials(rb_creds);
-    recvd_port =
-        grpc_server_add_secure_http2_port(s->wrapped, StringValueCStr(port),
-                                          creds);
+    recvd_port = grpc_server_add_secure_http2_port(
+        s->wrapped, StringValueCStr(port), creds);
     if (recvd_port == 0) {
       rb_raise(rb_eRuntimeError,
                "could not add secure port %s to server, not sure why",
@@ -333,18 +334,17 @@ void Init_grpc_server() {
 
   /* Provides a ruby constructor and support for dup/clone. */
   rb_define_method(grpc_rb_cServer, "initialize", grpc_rb_server_init, 1);
-  rb_define_method(grpc_rb_cServer, "initialize_copy",
-                   grpc_rb_cannot_init_copy, 1);
+  rb_define_method(grpc_rb_cServer, "initialize_copy", grpc_rb_cannot_init_copy,
+                   1);
 
   /* Add the server methods. */
-  rb_define_method(grpc_rb_cServer, "request_call",
-                   grpc_rb_server_request_call, 0);
+  rb_define_method(grpc_rb_cServer, "request_call", grpc_rb_server_request_call,
+                   0);
   rb_define_method(grpc_rb_cServer, "start", grpc_rb_server_start, 0);
   rb_define_method(grpc_rb_cServer, "destroy", grpc_rb_server_destroy, -1);
   rb_define_alias(grpc_rb_cServer, "close", "destroy");
   rb_define_method(grpc_rb_cServer, "add_http2_port",
-                   grpc_rb_server_add_http2_port,
-                   2);
+                   grpc_rb_server_add_http2_port, 2);
   id_at = rb_intern("at");
   id_insecure_server = rb_intern("this_port_is_insecure");
 }
diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb
index ce0892decfbe640eb6b3faed21a0ad8756bb5b63..f30dff335f1af4606a0b3cb37581beb67dcf9148 100644
--- a/src/ruby/lib/grpc/version.rb
+++ b/src/ruby/lib/grpc/version.rb
@@ -29,5 +29,5 @@
 
 # GRPC contains the General RPC module.
 module GRPC
-  VERSION = '1.2.0.dev'
+  VERSION = '1.4.0.dev'
 end
diff --git a/src/ruby/qps/proxy-worker.rb b/src/ruby/qps/proxy-worker.rb
new file mode 100755
index 0000000000000000000000000000000000000000..077920d1d3c13e8371937695fa654e82a227e4b6
--- /dev/null
+++ b/src/ruby/qps/proxy-worker.rb
@@ -0,0 +1,160 @@
+#!/usr/bin/env ruby
+
+# Copyright 2017, 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.
+
+# Proxy of worker service implementation for running a PHP client
+
+this_dir = File.expand_path(File.dirname(__FILE__))
+lib_dir = File.join(File.dirname(this_dir), 'lib')
+$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
+$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
+
+require 'grpc'
+require 'optparse'
+require 'histogram'
+require 'etc'
+require 'facter'
+require 'qps-common'
+require 'src/proto/grpc/testing/services_services_pb'
+require 'src/proto/grpc/testing/proxy-service_services_pb'
+
+class ProxyBenchmarkClientServiceImpl < Grpc::Testing::ProxyClientService::Service
+  def initialize(port)
+    @mytarget = "localhost:" + port.to_s
+  end
+  def setup(config)
+    @config = config
+    @histres = config.histogram_params.resolution
+    @histmax = config.histogram_params.max_possible
+    @histogram = Histogram.new(@histres, @histmax)
+    @start_time = Time.now
+    # TODO(vjpai): Support multiple client channels by spawning off a PHP client per channel
+    command = "php " + File.expand_path(File.dirname(__FILE__)) + "/../../php/tests/qps/client.php " + @mytarget
+    puts "Starting command: " + command
+    @php_pid = spawn(command)
+  end
+  def stop
+    Process.kill("TERM", @php_pid)
+    Process.wait(@php_pid)
+  end
+  def get_config(_args, _call)
+    puts "Answering get_config"
+    @config
+  end
+  def report_time(call)
+    puts "Starting a time reporting stream"
+    call.each_remote_read do |lat|
+      @histogram.add((lat.latency)*1e9)
+    end
+    Grpc::Testing::Void.new
+  end
+  def mark(reset)
+    lat = Grpc::Testing::HistogramData.new(
+      bucket: @histogram.contents,
+      min_seen: @histogram.minimum,
+      max_seen: @histogram.maximum,
+      sum: @histogram.sum,
+      sum_of_squares: @histogram.sum_of_squares,
+      count: @histogram.count
+    )
+    elapsed = Time.now-@start_time
+    if reset
+      @start_time = Time.now
+      @histogram = Histogram.new(@histres, @histmax)
+    end
+    Grpc::Testing::ClientStats.new(latencies: lat, time_elapsed: elapsed)
+  end
+end
+
+class ProxyWorkerServiceImpl < Grpc::Testing::WorkerService::Service
+  def cpu_cores
+    Facter.value('processors')['count']
+  end
+  # Leave run_server unimplemented since this proxies for a client only.
+  # If the driver tries to use this as a server, it will get an unimplemented
+  # status return value.
+  def run_client(reqs)
+    q = EnumeratorQueue.new(self)
+    Thread.new {
+      reqs.each do |req|
+        case req.argtype.to_s
+        when 'setup'
+          @bmc.setup(req.setup)
+          q.push(Grpc::Testing::ClientStatus.new(stats: @bmc.mark(false)))
+        when 'mark'
+          q.push(Grpc::Testing::ClientStatus.new(stats:
+                                                   @bmc.mark(req.mark.reset)))
+        end
+      end
+      @bmc.stop
+      q.push(self)
+    }
+    q.each_item
+  end
+  def core_count(_args, _call)
+    Grpc::Testing::CoreResponse.new(cores: cpu_cores)
+  end
+  def quit_worker(_args, _call)
+    Thread.new {
+      sleep 3
+      @server.stop
+    }
+    Grpc::Testing::Void.new
+  end
+  def initialize(s, bmc)
+    @server = s
+    @bmc = bmc
+  end
+end
+
+def proxymain
+  options = {
+    'driver_port' => 0
+  }
+  OptionParser.new do |opts|
+    opts.banner = 'Usage: [--driver_port <port>]'
+    opts.on('--driver_port PORT', '<port>') do |v|
+      options['driver_port'] = v
+    end
+  end.parse!
+
+  # Configure any errors with client or server child threads to surface
+  Thread.abort_on_exception = true
+
+  s = GRPC::RpcServer.new
+  port = s.add_http2_port("0.0.0.0:" + options['driver_port'].to_s,
+                          :this_port_is_insecure)
+  bmc = ProxyBenchmarkClientServiceImpl.new(port)
+  s.handle(bmc)
+  s.handle(ProxyWorkerServiceImpl.new(s, bmc))
+  s.run
+end
+
+proxymain
diff --git a/src/ruby/qps/src/proto/grpc/testing/proxy-service_pb.rb b/src/ruby/qps/src/proto/grpc/testing/proxy-service_pb.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d238198cca3765c01e0ca98444c709caeafadbbf
--- /dev/null
+++ b/src/ruby/qps/src/proto/grpc/testing/proxy-service_pb.rb
@@ -0,0 +1,17 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/proxy-service.proto
+
+require 'google/protobuf'
+
+require 'src/proto/grpc/testing/control_pb'
+Google::Protobuf::DescriptorPool.generated_pool.build do
+  add_message "grpc.testing.ProxyStat" do
+    optional :latency, :double, 1
+  end
+end
+
+module Grpc
+  module Testing
+    ProxyStat = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ProxyStat").msgclass
+  end
+end
diff --git a/src/ruby/qps/src/proto/grpc/testing/proxy-service_services_pb.rb b/src/ruby/qps/src/proto/grpc/testing/proxy-service_services_pb.rb
new file mode 100644
index 0000000000000000000000000000000000000000..37ddbf5b030348f97cac937f613224b5d1354640
--- /dev/null
+++ b/src/ruby/qps/src/proto/grpc/testing/proxy-service_services_pb.rb
@@ -0,0 +1,55 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# Source: src/proto/grpc/testing/proxy-service.proto for package 'grpc.testing'
+# Original file comments:
+# Copyright 2017, 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.
+#
+
+require 'grpc'
+require 'src/proto/grpc/testing/proxy-service_pb'
+
+module Grpc
+  module Testing
+    module ProxyClientService
+      class Service
+
+        include GRPC::GenericService
+
+        self.marshal_class_method = :encode
+        self.unmarshal_class_method = :decode
+        self.service_name = 'grpc.testing.ProxyClientService'
+
+        rpc :GetConfig, Void, ClientConfig
+        rpc :ReportTime, stream(ProxyStat), Void
+      end
+
+      Stub = Service.rpc_stub_class
+    end
+  end
+end
diff --git a/src/ruby/spec/channel_connection_spec.rb b/src/ruby/spec/channel_connection_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..940d68b9b04a94c13703b47a4fea9b92bc9b3360
--- /dev/null
+++ b/src/ruby/spec/channel_connection_spec.rb
@@ -0,0 +1,141 @@
+# 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.
+
+require 'grpc'
+
+# A test message
+class EchoMsg
+  def self.marshal(_o)
+    ''
+  end
+
+  def self.unmarshal(_o)
+    EchoMsg.new
+  end
+end
+
+# A test service with an echo implementation.
+class EchoService
+  include GRPC::GenericService
+  rpc :an_rpc, EchoMsg, EchoMsg
+  attr_reader :received_md
+
+  def initialize(**kw)
+    @trailing_metadata = kw
+    @received_md = []
+  end
+
+  def an_rpc(req, call)
+    GRPC.logger.info('echo service received a request')
+    call.output_metadata.update(@trailing_metadata)
+    @received_md << call.metadata unless call.metadata.nil?
+    req
+  end
+end
+
+EchoStub = EchoService.rpc_stub_class
+
+def start_server(port = 0)
+  @srv = GRPC::RpcServer.new
+  server_port = @srv.add_http2_port("localhost:#{port}", :this_port_is_insecure)
+  @srv.handle(EchoService)
+  @server_thd = Thread.new { @srv.run }
+  @srv.wait_till_running
+  server_port
+end
+
+def stop_server
+  expect(@srv.stopped?).to be(false)
+  @srv.stop
+  @server_thd.join
+  expect(@srv.stopped?).to be(true)
+end
+
+describe 'channel connection behavior' do
+  it 'the client channel handles temporary loss of a transport' do
+    port = start_server
+    stub = EchoStub.new("localhost:#{port}", :this_channel_is_insecure)
+    req = EchoMsg.new
+    expect(stub.an_rpc(req)).to be_a(EchoMsg)
+    stop_server
+    sleep 1
+    # TODO(apolcyn) grabbing the same port might fail, is this stable enough?
+    start_server(port)
+    expect(stub.an_rpc(req)).to be_a(EchoMsg)
+    stop_server
+  end
+
+  it 'observably connects and reconnects to transient server' \
+    ' when using the channel state API' do
+    port = start_server
+    ch = GRPC::Core::Channel.new("localhost:#{port}", {},
+                                 :this_channel_is_insecure)
+
+    expect(ch.connectivity_state).to be(GRPC::Core::ConnectivityStates::IDLE)
+
+    state = ch.connectivity_state(true)
+
+    count = 0
+    while count < 20 && state != GRPC::Core::ConnectivityStates::READY
+      ch.watch_connectivity_state(state, Time.now + 60)
+      state = ch.connectivity_state(true)
+      count += 1
+    end
+
+    expect(state).to be(GRPC::Core::ConnectivityStates::READY)
+
+    stop_server
+
+    state = ch.connectivity_state
+
+    count = 0
+    while count < 20 && state == GRPC::Core::ConnectivityStates::READY
+      ch.watch_connectivity_state(state, Time.now + 60)
+      state = ch.connectivity_state
+      count += 1
+    end
+
+    expect(state).to_not be(GRPC::Core::ConnectivityStates::READY)
+
+    start_server(port)
+
+    state = ch.connectivity_state(true)
+
+    count = 0
+    while count < 20 && state != GRPC::Core::ConnectivityStates::READY
+      ch.watch_connectivity_state(state, Time.now + 60)
+      state = ch.connectivity_state(true)
+      count += 1
+    end
+
+    expect(state).to be(GRPC::Core::ConnectivityStates::READY)
+
+    stop_server
+  end
+end
diff --git a/src/ruby/spec/channel_spec.rb b/src/ruby/spec/channel_spec.rb
index 740eac631a3e40a1697da49954a2db8f360e0c5b..a289a00f0437113d370ba7c24bb7de6595a00473 100644
--- a/src/ruby/spec/channel_spec.rb
+++ b/src/ruby/spec/channel_spec.rb
@@ -153,6 +153,35 @@ describe GRPC::Core::Channel do
     end
   end
 
+  describe '#connectivity_state' do
+    it 'returns an enum' do
+      ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
+      valid_states = [
+        GRPC::Core::ConnectivityStates::IDLE,
+        GRPC::Core::ConnectivityStates::CONNECTING,
+        GRPC::Core::ConnectivityStates::READY,
+        GRPC::Core::ConnectivityStates::TRANSIENT_FAILURE,
+        GRPC::Core::ConnectivityStates::FATAL_FAILURE
+      ]
+
+      expect(valid_states).to include(ch.connectivity_state)
+    end
+
+    it 'returns an enum when trying to connect' do
+      ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
+      ch.connectivity_state(true)
+      valid_states = [
+        GRPC::Core::ConnectivityStates::IDLE,
+        GRPC::Core::ConnectivityStates::CONNECTING,
+        GRPC::Core::ConnectivityStates::READY,
+        GRPC::Core::ConnectivityStates::TRANSIENT_FAILURE,
+        GRPC::Core::ConnectivityStates::FATAL_FAILURE
+      ]
+
+      expect(valid_states).to include(ch.connectivity_state)
+    end
+  end
+
   describe '::SSL_TARGET' do
     it 'is a symbol' do
       expect(GRPC::Core::Channel::SSL_TARGET).to be_a(Symbol)
diff --git a/src/ruby/spec/generic/rpc_server_pool_spec.rb b/src/ruby/spec/generic/rpc_server_pool_spec.rb
index 69e8222cb97f4bf0031e3efbc7b06597fbe8c179..0803ca74ed67ae041fe97c9e44821244a00cce2a 100644
--- a/src/ruby/spec/generic/rpc_server_pool_spec.rb
+++ b/src/ruby/spec/generic/rpc_server_pool_spec.rb
@@ -52,28 +52,31 @@ describe GRPC::Pool do
       expect(p.ready_for_work?).to be(false)
     end
 
-    it 'it stops being ready after all workers jobs waiting or running' do
+    it 'it stops being ready after all workers are busy' do
       p = Pool.new(5)
       p.start
-      job = proc { sleep(3) } # sleep so workers busy when done scheduling
-      5.times do
-        expect(p.ready_for_work?).to be(true)
-        p.schedule(&job)
+
+      wait_mu = Mutex.new
+      wait_cv = ConditionVariable.new
+      wait = true
+
+      job = proc do
+        wait_mu.synchronize do
+          wait_cv.wait(wait_mu) while wait
+        end
       end
-      expect(p.ready_for_work?).to be(false)
-    end
 
-    it 'it becomes ready again after jobs complete' do
-      p = Pool.new(5)
-      p.start
-      job = proc {}
       5.times do
         expect(p.ready_for_work?).to be(true)
         p.schedule(&job)
       end
+
       expect(p.ready_for_work?).to be(false)
-      sleep 5 # give the pool time do get at least one task done
-      expect(p.ready_for_work?).to be(true)
+
+      wait_mu.synchronize do
+        wait = false
+        wait_cv.broadcast
+      end
     end
   end
 
@@ -105,13 +108,20 @@ describe GRPC::Pool do
     it 'stops jobs when there are long running jobs' do
       p = Pool.new(1)
       p.start
-      o, q = Object.new, Queue.new
+
+      wait_forever_mu = Mutex.new
+      wait_forever_cv = ConditionVariable.new
+      wait_forever = true
+
+      job_running = Queue.new
       job = proc do
-        sleep(5)  # long running
-        q.push(o)
+        job_running.push(Object.new)
+        wait_forever_mu.synchronize do
+          wait_forever_cv.wait while wait_forever
+        end
       end
       p.schedule(&job)
-      sleep(1)  # should ensure the long job gets scheduled
+      job_running.pop
       expect { p.stop }.not_to raise_error
     end
   end
diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb
index 8f3d2ba81ccb807f726f9e96ae305c8e642e68d8..1f8d4afb95f2fcfe4da299292e1aaf1ef4af7501 100644
--- a/src/ruby/tools/version.rb
+++ b/src/ruby/tools/version.rb
@@ -29,6 +29,6 @@
 
 module GRPC
   module Tools
-    VERSION = '1.2.0.dev'
+    VERSION = '1.4.0.dev'
   end
 end
diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template
index 1c2ef0a9c16748c3af3b136098207090114f6483..2252a7ea80a18f12d1607e412f2b635cc82de581 100644
--- a/templates/CMakeLists.txt.template
+++ b/templates/CMakeLists.txt.template
@@ -7,9 +7,6 @@
   # This file can be regenerated from the template by running
   # tools/buildgen/generate_projects.sh
   #
-  # Additionally, this is currently very experimental, and unsupported.
-  # Further work will happen on that file.
-  #
   # Copyright 2015, Google Inc.
   # All rights reserved.
   #
@@ -40,17 +37,17 @@
   # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
   <%!
-  
+
   import re
-  
+
   proto_re = re.compile('(.*)\\.proto')
-  
+
   def proto_replace_ext(filename, ext):
       m = proto_re.match(filename)
       if not m:
         return filename
       return '${_gRPC_PROTO_GENS_DIR}/' + m.group(1) + ext
-  
+
   def get_deps(target_dict):
     deps = []
     if target_dict.get('baselib', False):
@@ -63,19 +60,20 @@
       deps.append("${_gRPC_PROTOBUF_LIBRARIES}")
     if target_dict['name'] in ['grpc']:
       deps.append("${_gRPC_ZLIB_LIBRARIES}")
+      deps.append("${_gRPC_CARES_LIBRARIES}")
     deps.append("${_gRPC_ALLTARGETS_LIBRARIES}")
     for d in target_dict.get('deps', []):
       deps.append(d)
     if target_dict.build == 'test' and target_dict.language == 'c++':
       deps.append("${_gRPC_GFLAGS_LIBRARIES}")
     return deps
-  
+
   def get_platforms_condition_begin(platforms):
     if all(platform in platforms for platform in ['linux', 'mac', 'posix', 'windows']):
       return ''
     cond = ' OR '.join(['_gRPC_PLATFORM_%s' % platform.upper() for platform in platforms])
     return 'if(%s)\n' % cond
-  
+
   def get_platforms_condition_end(platforms):
     if not get_platforms_condition_begin(platforms):
       return ''
@@ -90,7 +88,7 @@
   set(PACKAGE_TARNAME   "<%text>${PACKAGE_NAME}-${PACKAGE_VERSION}</%text>")
   set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
   project(<%text>${PACKAGE_NAME}</%text> C CXX)
-  
+
   # Options
   option(gRPC_BUILD_TESTS "Build tests" OFF)
 
@@ -103,18 +101,21 @@
   set(gRPC_ZLIB_PROVIDER "module" CACHE STRING "Provider of zlib library")
   set_property(CACHE gRPC_ZLIB_PROVIDER PROPERTY STRINGS "module" "package")
 
+  set(gRPC_CARES_PROVIDER "module" CACHE STRING "Provider of c-ares library")
+  set_property(CACHE gRPC_CARES_PROVIDER PROPERTY STRINGS "module" "package")
+
   set(gRPC_SSL_PROVIDER "module" CACHE STRING "Provider of ssl library")
   set_property(CACHE gRPC_SSL_PROVIDER PROPERTY STRINGS "module" "package")
 
   set(gRPC_PROTOBUF_PROVIDER "module" CACHE STRING "Provider of protobuf library")
   set_property(CACHE gRPC_PROTOBUF_PROVIDER PROPERTY STRINGS "module" "package")
-  
+
   set(gRPC_GFLAGS_PROVIDER "module" CACHE STRING "Provider of gflags library")
   set_property(CACHE gRPC_GFLAGS_PROVIDER PROPERTY STRINGS "module" "package")
-  
+
   set(gRPC_BENCHMARK_PROVIDER "module" CACHE STRING "Provider of benchmark library")
   set_property(CACHE gRPC_BENCHMARK_PROVIDER PROPERTY STRINGS "module" "package")
-  
+
   set(gRPC_USE_PROTO_LITE OFF CACHE BOOL "Use the protobuf-lite library")
 
   if(UNIX)
@@ -129,7 +130,7 @@
   if(WIN32)
     set(_gRPC_PLATFORM_WINDOWS ON)
   endif()
-  
+
   ## Some libraries are shared even with BUILD_SHARED_LIBRARIES=OFF
   set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
 
@@ -170,6 +171,37 @@
     set(_gRPC_FIND_ZLIB "if(NOT ZLIB_FOUND)\n  find_package(ZLIB)\nendif()")
   endif()
 
+  if("<%text>${gRPC_CARES_PROVIDER}</%text>" STREQUAL "module")
+    if(NOT CARES_ROOT_DIR)
+      set(CARES_ROOT_DIR <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/src/c-ares)
+    endif()
+    string(TOLOWER <%text>${CMAKE_SYSTEM_NAME}</%text> CARES_SYSTEM_NAME)
+    set(CARES_INCLUDE_DIR "<%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/third_party/cares/cares")
+    set(CARES_BUILD_INCLUDE_DIR "<%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/third_party/cares")
+    set(CARES_PLATFORM_INCLUDE_DIR "<%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/third_party/cares/config_<%text>${CARES_SYSTEM_NAME}</%text>")
+    if(EXISTS "<%text>${CARES_ROOT_DIR}</%text>/CMakeLists.txt")
+      if("<%text>${CARES_SYSTEM_NAME}</%text>" MATCHES "windows")
+        add_definitions(-DCARES_STATICLIB=1)
+        add_definitions(-DWIN32_LEAN_AND_MEAN=1)
+      else()
+        add_definitions(-DHAVE_CONFIG_H=1)
+        add_definitions(-D_GNU_SOURCE=1)
+      endif()
+      add_subdirectory(src/c-ares third_party/cares)
+      if(TARGET cares)
+          set(_gRPC_CARES_LIBRARIES cares)
+      endif()
+    else()
+      message(WARNING "gRPC_CARES_PROVIDER is \"module\" but CARES_ROOT_DIR is wrong")
+    endif()
+  elseif("<%text>${gRPC_CARES_PROVIDER}</%text>" STREQUAL "package")
+    find_package(CARES)
+    if(TARGET CARES::CARES)
+      set(_gRPC_CARES_LIBRARIES CARES::CARES)
+    endif()
+    set(_gRPC_FIND_CARES "if(NOT CARES_FOUND)\n  find_package(CARES)\nendif()")
+  endif()
+
   if("<%text>${gRPC_PROTOBUF_PROVIDER}</%text>" STREQUAL "module")
     # Building the protobuf tests require gmock what is not part of a standard protobuf checkout.
     # Disable them unless they are explicitly requested from the cmake command line (when we assume
@@ -180,6 +212,7 @@
     if(NOT PROTOBUF_ROOT_DIR)
       set(PROTOBUF_ROOT_DIR <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/third_party/protobuf)
     endif()
+    set(PROTOBUF_WELLKNOWN_IMPORT_DIR <%text>${PROTOBUF_ROOT_DIR}</%text>/src)
     if(EXISTS "<%text>${PROTOBUF_ROOT_DIR}</%text>/cmake/CMakeLists.txt")
       set(protobuf_MSVC_STATIC_RUNTIME OFF CACHE BOOL "Link static runtime libraries")
       add_subdirectory(<%text>${PROTOBUF_ROOT_DIR}</%text>/cmake third_party/protobuf)
@@ -212,6 +245,7 @@
       find_package(Protobuf MODULE)
       set(_gRPC_FIND_PROTOBUF "if(NOT Protobuf_FOUND)\n  find_package(Protobuf)\nendif()")
     endif()
+    set(PROTOBUF_WELLKNOWN_IMPORT_DIR /usr/local/include)
   endif()
 
   if("<%text>${gRPC_SSL_PROVIDER}</%text>" STREQUAL "module")
@@ -234,7 +268,7 @@
     endif()
     set(_gRPC_FIND_SSL "if(NOT OpenSSL_FOUND)\n  find_package(OpenSSL)\nendif()")
   endif()
-  
+
   if("<%text>${gRPC_GFLAGS_PROVIDER}</%text>" STREQUAL "module")
     if(NOT GFLAGS_ROOT_DIR)
       set(GFLAGS_ROOT_DIR <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/third_party/gflags)
@@ -254,7 +288,7 @@
     endif()
     set(_gRPC_FIND_GFLAGS "if(NOT gflags_FOUND)\n  find_package(gflags)\nendif()")
   endif()
-  
+
   if("<%text>${gRPC_BENCHMARK_PROVIDER}</%text>" STREQUAL "module")
     if(NOT BENCHMARK_ROOT_DIR)
       set(BENCHMARK_ROOT_DIR <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/third_party/benchmark)
@@ -280,8 +314,10 @@
     set(CMAKE_CXX_FLAGS "<%text>${CMAKE_CXX_FLAGS}</%text> -std=c++11")
   endif()
 
-  if(UNIX)
-    set(_gRPC_ALLTARGETS_LIBRARIES dl rt m pthread)
+  if(_gRPC_PLATFORM_MAC)
+    set(_gRPC_ALLTARGETS_LIBRARIES <%text>${CMAKE_DL_LIBS}</%text> m pthread)
+  elseif(UNIX)
+    set(_gRPC_ALLTARGETS_LIBRARIES <%text>${CMAKE_DL_LIBS}</%text> rt m pthread)
   endif()
 
   if(WIN32 AND MSVC)
@@ -292,11 +328,11 @@
   if(NOT DEFINED CMAKE_INSTALL_CMAKEDIR)
     set(CMAKE_INSTALL_CMAKEDIR "<%text>${CMAKE_INSTALL_LIBDIR}</%text>/cmake/gRPC")
   endif()
-  
+
   # Create directory for generated .proto files
   set(_gRPC_PROTO_GENS_DIR <%text>${CMAKE_BINARY_DIR}/gens</%text>)
   file(MAKE_DIRECTORY <%text>${_gRPC_PROTO_GENS_DIR}</%text>)
-  
+
   #  protobuf_generate_grpc_cpp
   #  --------------------------
   #
@@ -313,35 +349,36 @@
       message(SEND_ERROR "Error: PROTOBUF_GENERATE_GRPC_CPP() called without any proto files")
       return()
     endif()
-  
-    set(_protobuf_include_path -I .)
+
+    set(_protobuf_include_path -I . -I <%text>${PROTOBUF_WELLKNOWN_IMPORT_DIR}</%text>)
     foreach(FIL <%text>${ARGN}</%text>)
       get_filename_component(ABS_FIL <%text>${FIL}</%text> ABSOLUTE)
       get_filename_component(FIL_WE <%text>${FIL}</%text> NAME_WE)
-      file(RELATIVE_PATH REL_FIL <%text>${CMAKE_SOURCE_DIR}</%text> <%text>${ABS_FIL}</%text>)
+      file(RELATIVE_PATH REL_FIL <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text> <%text>${ABS_FIL}</%text>)
       get_filename_component(REL_DIR <%text>${REL_FIL}</%text> DIRECTORY)
       set(RELFIL_WE "<%text>${REL_DIR}/${FIL_WE}</%text>")
-      
+
       add_custom_command(
         OUTPUT <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc"</%text>
                <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h"</%text>
+               <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}_mock.grpc.pb.h"</%text>
                <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc"</%text>
                <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h"</%text>
         COMMAND <%text>${_gRPC_PROTOBUF_PROTOC}</%text>
-        ARGS --grpc_out=<%text>${_gRPC_PROTO_GENS_DIR}</%text>
+        ARGS --grpc_out=<%text>generate_mock_code=true:${_gRPC_PROTO_GENS_DIR}</%text>
              --cpp_out=<%text>${_gRPC_PROTO_GENS_DIR}</%text>
              --plugin=protoc-gen-grpc=$<TARGET_FILE:grpc_cpp_plugin>
              <%text>${_protobuf_include_path}</%text>
              <%text>${REL_FIL}</%text>
         DEPENDS <%text>${ABS_FIL}</%text> <%text>${_gRPC_PROTOBUF_PROTOC}</%text> grpc_cpp_plugin
-        WORKING_DIRECTORY <%text>${CMAKE_SOURCE_DIR}</%text>
+        WORKING_DIRECTORY <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>
         COMMENT "Running gRPC C++ protocol buffer compiler on <%text>${FIL}</%text>"
         VERBATIM)
-        
-        <%text>set_source_files_properties("${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h" PROPERTIES GENERATED TRUE)</%text>
+
+        <%text>set_source_files_properties("${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h"  "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}_mock.grpc.pb.h" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h" PROPERTIES GENERATED TRUE)</%text>
     endforeach()
   endfunction()
-  
+
   add_custom_target(plugins
     DEPENDS
   % for tgt in targets:
@@ -350,7 +387,7 @@
   % endif
   % endfor
   )
-  
+
   add_custom_target(tools_c
     DEPENDS
   % for tgt in targets:
@@ -359,7 +396,7 @@
   % endif
   % endfor
   )
-  
+
   add_custom_target(tools_cxx
     DEPENDS
   % for tgt in targets:
@@ -368,10 +405,10 @@
   % endif
   % endfor
   )
-  
+
   add_custom_target(tools
     DEPENDS tools_c tools_cxx)
-  
+
   if (gRPC_BUILD_TESTS)
   add_custom_target(buildtests_c)
   % for tgt in targets:
@@ -381,7 +418,7 @@
   ${get_platforms_condition_end(tgt.platforms)}\
   % endif
   % endfor
-  
+
   add_custom_target(buildtests_cxx)
   % for tgt in targets:
   % if tgt.build == 'test' and tgt.language == 'c++' and not tgt.get('external_deps', None) and not tgt.boringssl:
@@ -390,11 +427,11 @@
   ${get_platforms_condition_end(tgt.platforms)}\
   % endif
   % endfor
-  
+
   add_custom_target(buildtests
     DEPENDS buildtests_c buildtests_cxx)
   endif (gRPC_BUILD_TESTS)
-  
+
   % for lib in libs:
   % if lib.build in ["all", "protoc", "tool", "test", "private"] and not lib.boringssl:
   % if not lib.get('build_system', []) or 'cmake' in lib.get('build_system', []):
@@ -439,6 +476,9 @@
     ${proto_replace_ext(src, '.grpc.pb.cc')}
     ${proto_replace_ext(src, '.pb.h')}
     ${proto_replace_ext(src, '.grpc.pb.h')}
+    % if src in ["src/proto/grpc/testing/compiler_test.proto", "src/proto/grpc/testing/echo.proto"]:
+    ${proto_replace_ext(src, '_mock.grpc.pb.h')}
+    % endif
   % endif
   % endfor
   )
@@ -470,10 +510,16 @@
     PRIVATE <%text>${ZLIB_INCLUDE_DIR}</%text>
     PRIVATE <%text>${BENCHMARK}</%text>/include
     PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/zlib
+    PRIVATE <%text>${CARES_BUILD_INCLUDE_DIR}</%text>
+    PRIVATE <%text>${CARES_INCLUDE_DIR}</%text>
+    PRIVATE <%text>${CARES_PLATFORM_INCLUDE_DIR}</%text>
+    PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/cares/cares
     PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/gflags/include
   % if lib.build in ['test', 'private'] and lib.language == 'c++':
-    PRIVATE third_party/googletest/include
-    PRIVATE third_party/googletest
+    PRIVATE third_party/googletest/googletest/include
+    PRIVATE third_party/googletest/googletest
+    PRIVATE third_party/googletest/googlemock/include
+    PRIVATE third_party/googletest/googlemock
   % endif
   % if lib.language == 'c++':
     PRIVATE <%text>${_gRPC_PROTO_GENS_DIR}</%text>
@@ -516,10 +562,11 @@
   % endif
   % endfor
   % if tgt.build == 'test' and tgt.language == 'c++':
-    third_party/googletest/src/gtest-all.cc
+    third_party/googletest/googletest/src/gtest-all.cc
+    third_party/googletest/googlemock/src/gmock-all.cc
   % endif
   )
-  
+
   % for src in tgt.src:
   % if proto_re.match(src):
   protobuf_generate_grpc_cpp(
@@ -536,10 +583,16 @@
     PRIVATE <%text>${BENCHMARK_ROOT_DIR}</%text>/include
     PRIVATE <%text>${ZLIB_ROOT_DIR}</%text>
     PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/zlib
+    PRIVATE <%text>${CARES_BUILD_INCLUDE_DIR}</%text>
+    PRIVATE <%text>${CARES_INCLUDE_DIR}</%text>
+    PRIVATE <%text>${CARES_PLATFORM_INCLUDE_DIR}</%text>
+    PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/cares/cares
     PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/gflags/include
   % if tgt.build in ['test', 'private'] and tgt.language == 'c++':
-    PRIVATE third_party/googletest/include
-    PRIVATE third_party/googletest
+    PRIVATE third_party/googletest/googletest/include
+    PRIVATE third_party/googletest/googletest
+    PRIVATE third_party/googletest/googlemock/include
+    PRIVATE third_party/googletest/googlemock
   % endif
   % if tgt.language == 'c++':
     PRIVATE <%text>${_gRPC_PROTO_GENS_DIR}</%text>
diff --git a/templates/Makefile.template b/templates/Makefile.template
index f81d64399136940fea355eabcc2ad6a77fd623e6..5ce606f8280145c3c1832777d628d78af89e4504 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -311,7 +311,7 @@
   USE_BUILT_PROTOC = false
   endif
 
-  GTEST_LIB = -Ithird_party/googletest/include -Ithird_party/googletest third_party/googletest/src/gtest-all.cc
+  GTEST_LIB = -Ithird_party/googletest/googletest/include -Ithird_party/googletest/googletest third_party/googletest/googletest/src/gtest-all.cc -Ithird_party/googletest/googlemock/include -Ithird_party/googletest/googlemock third_party/googletest/googlemock/src/gmock-all.cc
   GTEST_LIB += -lgflags
   ifeq ($(V),1)
   E = @:
@@ -405,7 +405,7 @@
   SHARED_VERSION_CPP = -${settings.cpp_version.major}
   SHARED_VERSION_CSHARP = -${settings.csharp_version.major}
   else ifeq ($(SYSTEM),Darwin)
-  EXECUTABLE_SUFFIX = 
+  EXECUTABLE_SUFFIX =
   SHARED_EXT_CORE = dylib
   SHARED_EXT_CPP = dylib
   SHARED_EXT_CSHARP = dylib
@@ -414,7 +414,7 @@
   SHARED_VERSION_CPP =
   SHARED_VERSION_CSHARP =
   else
-  EXECUTABLE_SUFFIX = 
+  EXECUTABLE_SUFFIX =
   SHARED_EXT_CORE = so.$(CORE_VERSION)
   SHARED_EXT_CPP = so.$(CPP_VERSION)
   SHARED_EXT_CSHARP = so.$(CSHARP_VERSION)
@@ -435,6 +435,7 @@
   OPENSSL_NPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.1 openssl
   ZLIB_CHECK_CMD = $(PKG_CONFIG) --exists zlib
   PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.0.0 protobuf
+  CARES_CHECK_CMD = $(PKG_CONFIG) --exists libcares
   else # HAS_PKG_CONFIG
 
   ifeq ($(SYSTEM),MINGW32)
@@ -448,6 +449,7 @@
   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)
+  CARES_CHECK_CMD = $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $(TMPOUT) test/build/c-ares.c -lcares $(LDFLAGS)
 
   endif # HAS_PKG_CONFIG
 
@@ -487,12 +489,17 @@
   ifeq ($(HAS_SYSTEM_PROTOBUF),true)
   CACHE_MK += HAS_SYSTEM_PROTOBUF = true,
   endif
+  HAS_SYSTEM_CARES ?=  $(shell $(CARES_CHECK_CMD) 2> /dev/null && echo true || echo false)
+  ifeq ($(HAS_SYSTEM_CARES),true)
+  CACHE_MK += HAS_SYSTEM_CARES = true,
+  endif
   else
   # override system libraries if the config requires a custom compiled library
   HAS_SYSTEM_OPENSSL_ALPN = false
   HAS_SYSTEM_OPENSSL_NPN = false
   HAS_SYSTEM_ZLIB = false
   HAS_SYSTEM_PROTOBUF = false
+  HAS_SYSTEM_CARES = false
   endif
 
   HAS_PROTOC ?= $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false)
@@ -551,6 +558,12 @@
   HAS_EMBEDDED_PROTOBUF = true
   endif
 
+  ifeq ($(wildcard third_party/cares/cares/ares.h),)
+  HAS_EMBEDDED_CARES = false
+  else
+  HAS_EMBEDDED_CARES = true
+  endif
+
   PC_REQUIRES_GRPC =
   PC_LIBS_GRPC =
 
@@ -583,6 +596,37 @@
   endif
   endif
 
+  CARES_PKG_CONFIG = false
+
+  ifeq ($(HAS_SYSTEM_CARES),false)
+  ifeq ($(HAS_EMBEDDED_CARES), true)
+  EMBED_CARES ?= true
+  else
+  DEP_MISSING += cares
+  EMBED_CARES ?= broken
+  endif
+  else
+  EMBED_CARES ?= false
+  endif
+
+  ifeq ($(EMBED_CARES),true)
+  CARES_DEP = $(LIBDIR)/$(CONFIG)/libares.a
+  CARES_MERGE_OBJS = $(LIBARES_OBJS)
+  CARES_MERGE_LIBS = $(LIBDIR)/$(CONFIG)/libares.a
+  CPPFLAGS := -Ithird_party/cares -Ithird_party/cares/cares $(CPPFLAGS)
+  LDFLAGS := -L$(LIBDIR)/$(CONFIG)/c-ares $(LDFLAGS)
+  else
+  ifeq ($(HAS_PKG_CONFIG),true)
+  PC_REQUIRES_GRPC += libcares
+  CPPFLAGS += $(shell $(PKG_CONFIG) --cflags libcares)
+  LDFLAGS += $(shell $(PKG_CONFIG) --libs-only-L libcares)
+  LIBS += $(patsubst -l%,%,$(shell $(PKG_CONFIG) --libs-only-l libcares))
+  else
+  PC_LIBS_GRPC += -lcares
+  LIBS += cares
+  endif
+  endif
+
   OPENSSL_PKG_CONFIG = false
 
   PC_REQUIRES_SECURE =
@@ -672,7 +716,7 @@
   PC_REQUIRES_GRPCXX =
   PC_LIBS_GRPCXX =
 
-  CPPFLAGS := -Ithird_party/googletest/include $(CPPFLAGS)
+  CPPFLAGS := -Ithird_party/googletest/googletest/include -Ithird_party/googletest/googlemock/include $(CPPFLAGS)
 
   PROTOC_PLUGINS_ALL =\
   % for tgt in targets:
@@ -864,6 +908,7 @@
   	$(PERFTOOLS_CHECK_CMD) || true
   	$(PROTOBUF_CHECK_CMD) || true
   	$(PROTOC_CHECK_VERSION_CMD) || true
+  	$(CARES_CHECK_CMD) || true
 
   third_party/protobuf/configure:
   	$(E) "[AUTOGEN] Preparing protobuf"
@@ -1195,6 +1240,14 @@
   $(GENDIR)/${p}.pb.cc: protoc_dep_error
   $(GENDIR)/${p}.grpc.pb.cc: protoc_dep_error
   else
+  <%
+    pluginflags=""
+  %>
+  % if p in ["src/proto/grpc/testing/compiler_test", "src/proto/grpc/testing/echo"]:
+  <%
+    pluginflags="generate_mock_code=true:"
+  %>
+  % endif
   $(GENDIR)/${p}.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) ${' '.join('$(GENDIR)/%s.pb.cc' % q for q in proto_deps.get(p, []))}
   	$(E) "[PROTOC]  Generating protobuf CC file from $<"
   	$(Q) mkdir -p `dirname $@`
@@ -1203,7 +1256,7 @@
   $(GENDIR)/${p}.grpc.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) ${' '.join('$(GENDIR)/%s.pb.cc $(GENDIR)/%s.grpc.pb.cc' % (q,q) for q in proto_deps.get(p, []))}
   	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
   	$(Q) mkdir -p `dirname $@`
-  	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
+  	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=${pluginflags}$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
   endif
 
   % endfor
@@ -1432,7 +1485,7 @@
   else
   % endif
 
-  $(LIBDIR)/$(CONFIG)/lib${lib.name}.a: $(ZLIB_DEP) $(OPENSSL_DEP)\
+  $(LIBDIR)/$(CONFIG)/lib${lib.name}.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP)\
   ## The else here corresponds to the if secure earlier.
   % else:
   % if lib.language == 'c++':
@@ -1453,6 +1506,9 @@
   % if lib.name != 'z':
   $(ZLIB_DEP) \
   % endif
+  % if lib.name != 'ares':
+  $(CARES_DEP) \
+  % endif
   % endif
   % if lib.language == 'c++':
    $(PROTOBUF_DEP)\
@@ -1461,6 +1517,7 @@
   % if lib.get('baselib', False):
    $(LIBGPR_OBJS) \
    $(ZLIB_MERGE_OBJS) \
+   $(CARES_MERGE_OBJS) \
   % if lib.get('secure', 'check') == True:
    $(OPENSSL_MERGE_OBJS) \
   % endif
@@ -1473,6 +1530,7 @@
   % if lib.get('baselib', False):
    $(LIBGPR_OBJS) \
    $(ZLIB_MERGE_OBJS) \
+   $(CARES_MERGE_OBJS) \
   % if lib.get('secure', 'check') == True:
    $(OPENSSL_MERGE_OBJS) \
   % endif
@@ -1495,9 +1553,9 @@
     common = '$(LIB' + lib.name.upper() + '_OBJS)'
 
     link_libs = ''
-    lib_deps = ' $(ZLIB_DEP)'
+    lib_deps = ' $(ZLIB_DEP) $(CARES_DEP)'
     mingw_libs = ''
-    mingw_lib_deps = ' $(ZLIB_DEP)'
+    mingw_lib_deps = ' $(ZLIB_DEP) $(CARES_DEP)'
     if lib.language == 'c++':
       lib_deps += ' $(PROTOBUF_DEP)'
       mingw_lib_deps += ' $(PROTOBUF_DEP)'
@@ -1522,7 +1580,7 @@
     security = lib.get('secure', 'check')
     if security == True:
       common = common + ' $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE)'
-    common = common + ' $(ZLIB_MERGE_LIBS)'
+    common = common + ' $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS)'
 
     if security in [True, 'check']:
       for src in lib.src:
@@ -1559,7 +1617,7 @@
   ifeq ($(SYSTEM),Darwin)
   	$(Q) ${ld} ${ldflags} -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) -dynamiclib -o ${out_libbase}.$(SHARED_EXT_${lang_to_var[lib.language]}) ${common}${link_libs}
   else
-  	$(Q) ${ld} ${ldflags} -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,lib${lib.name}.so.${settings.core_version.major} -o ${out_libbase}.$(SHARED_EXT_${lang_to_var[lib.language]}) ${common}${link_libs}
+  	$(Q) ${ld} ${ldflags} -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,lib${lib.name}.so.${settings.get(lang_to_var[lib.language].lower() + '_version').major} -o ${out_libbase}.$(SHARED_EXT_${lang_to_var[lib.language]}) ${common}${link_libs}
   	$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) ${out_libbase}.so.${settings.get(lang_to_var[lib.language].lower() + '_version').major}
   	$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) ${out_libbase}.so
   endif
@@ -1723,6 +1781,11 @@
   endif
   % endif
 
+  % if tgt.get('defaults', None):
+  %  for name, value in defaults.get(tgt.defaults).iteritems():
+  $(${tgt.name.upper()}_OBJS): ${name} += ${value}
+  %  endfor
+  % endif
   % for src in tgt.src:
   $(OBJDIR)/$(CONFIG)/${os.path.splitext(src)[0]}.o: \
   % for dep in tgt.deps:
diff --git a/templates/binding.gyp.template b/templates/binding.gyp.template
index 2290411d54124319b8596ded3628d55aede6f6ed..933174ab6edb6b12565ad3bd7ec6e7a02177e682 100644
--- a/templates/binding.gyp.template
+++ b/templates/binding.gyp.template
@@ -41,24 +41,68 @@
   {
     'variables': {
       'runtime%': 'node',
-      # UV integration in C core is disabled by default while bugs are ironed
-      # out. It can be re-enabled for one build by setting the npm config
-      # variable grpc_uv to true, and it can be re-enabled permanently by
-      # setting it to true here.
-      'grpc_uv%': 'false'
+      # Some Node installations use the system installation of OpenSSL, and on
+      # some systems, the system OpenSSL still does not have ALPN support. This
+      # will let users recompile gRPC to work without ALPN.
+      'grpc_alpn%': 'true',
+      # Indicates that the library should be built with gcov.
+      'grpc_gcov%': 'false',
+      # Indicates that the library should be built with compatibility for musl
+      # libc, so that it can run on Alpine Linux. This is only necessary if not
+      # building on Alpine Linux
+      'grpc_alpine%': 'false'
     },
     'target_defaults': {
+      'configurations': {
+        % for name, args in configs.iteritems():
+        %  if name in ['dbg', 'opt']:
+        '${{'dbg':'Debug', 'opt': 'Release'}[name]}': {
+          % for arg, prop in [('CPPFLAGS', 'cflags'), ('DEFINES', 'defines')]:
+          %  if args.get(arg, None) is not None:
+          '${prop}': [
+            % for item in args.get(arg).split():
+              '${item}',
+            % endfor
+          ],
+          %  endif
+          % endfor
+        },
+        %  endif
+        % endfor
+      },
+      % for arg, prop in [('CPPFLAGS', 'cflags'), ('LDFLAGS', 'ldflags')]:
+      %  if defaults['global'].get(arg, None) is not None:
+      '${prop}': [
+        % for item in defaults['global'].get(arg).split():
+          '${item}',
+        % endfor
+      ],
+      %  endif
+      % endfor
       'include_dirs': [
         '.',
         'include'
       ],
       'defines': [
-        'GPR_BACKWARDS_COMPATIBILITY_MODE'
+        'GPR_BACKWARDS_COMPATIBILITY_MODE',
+        'GRPC_ARES=0',
+        'GRPC_UV'
       ],
       'conditions': [
-        ['grpc_uv=="true"', {
+        ['grpc_gcov=="true"', {
+          % for arg, prop in [('CPPFLAGS', 'cflags'), ('DEFINES', 'defines'), ('LDFLAGS', 'ldflags')]:
+          %  if configs['gcov'].get(arg, None) is not None:
+          '${prop}': [
+            % for item in configs['gcov'].get(arg).split():
+              '${item}',
+            % endfor
+          ],
+          %  endif
+          % endfor
+        }],
+        ['grpc_alpine=="true"', {
           'defines': [
-            'GRPC_UV'
+            'GPR_MUSL_LIBC_COMPAT'
           ]
         }],
         ['OS!="win" and runtime=="electron"', {
@@ -75,10 +119,16 @@
             'OPENSSL_NO_ASM'
           ]
         }, {
-          # As of the beginning of 2017, we only support versions of Node with
-          # embedded versions of OpenSSL that support ALPN
-          'defines': [
-            'TSI_OPENSSL_ALPN_SUPPORT=1'
+          'conditions': [
+            ['grpc_alpn=="true"', {
+              'defines': [
+                'TSI_OPENSSL_ALPN_SUPPORT=1'
+              ],
+            }, {
+              'defines': [
+                'TSI_OPENSSL_ALPN_SUPPORT=0'
+              ],
+            }]
           ],
           'include_dirs': [
             '<(node_root_dir)/deps/openssl/openssl/include',
@@ -97,7 +147,8 @@
         }],
         ['OS == "win"', {
           "include_dirs": [
-            "third_party/zlib"
+            "third_party/zlib",
+            "third_party/cares/cares"
           ],
           "defines": [
             '_WIN32_WINNT=0x0600',
@@ -116,25 +167,9 @@
             "ws2_32"
           ]
         }, { # OS != "win"
-          'variables': {
-            'config': '<!(echo $CONFIG)',
-          },
           'include_dirs': [
-            '<(node_root_dir)/deps/zlib'
-          ],
-          'conditions': [
-            ['config=="gcov"', {
-              'cflags': [
-                '-ftest-coverage',
-                '-fprofile-arcs',
-                '-O0'
-              ],
-              'ldflags': [
-                '-ftest-coverage',
-                '-fprofile-arcs'
-              ]
-            }
-           ]
+            '<(node_root_dir)/deps/zlib',
+            '<(node_root_dir)/deps/cares/include'
           ]
         }]
       ]
@@ -170,7 +205,7 @@
           % endfor
         ]
       }],
-      ['OS == "win"', {
+      ['OS == "win" and runtime!="electron"', {
         'targets': [
           {
             # IMPORTANT WINDOWS BUILD INFORMATION
@@ -181,10 +216,13 @@
             # when including the Node headers. The remedy for this is to remove
             # the OpenSSL headers, from the downloaded Node development package,
             # which is typically located in `.node-gyp` in your home directory.
+            #
+            # This is not true of Electron, which does not have OpenSSL headers.
             'target_name': 'WINDOWS_BUILD_WARNING',
-            'actions': [
+            'rules': [
               {
-                'action_name': 'WINDOWS_BUILD_WARNING',
+                'rule_name': 'WINDOWS_BUILD_WARNING',
+                'extension': 'S',
                 'inputs': [
                   'package.json'
                 ],
@@ -195,6 +233,10 @@
               }
             ]
           },
+        ]
+      }],
+      ['OS == "win"', {
+        'targets': [
           # Only want to compile zlib under Windows
           % for module in node_modules:
           % for lib in libs:
@@ -264,16 +306,10 @@
         ],
         'cflags': [
           '-std=c++11',
-          '-Wall',
           '-pthread',
-          '-g',
           '-zdefs',
-          '-Werror',
           '-Wno-error=deprecated-declarations'
         ],
-        'ldflags': [
-          '-g'
-        ],
         "conditions": [
           ['OS=="win" or runtime=="electron"', {
             'dependencies': [
diff --git a/templates/config.m4.template b/templates/config.m4.template
index f5f1d23088dadeaedff737fc148349a366a6d484..13ff7389e6857c21a50f22172917faa99866f479 100644
--- a/templates/config.m4.template
+++ b/templates/config.m4.template
@@ -10,6 +10,8 @@
     PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/include)
     PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/src/php/ext/grpc)
     PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/boringssl/include)
+    PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/cares)
+    PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/cares/cares)
 
     LIBS="-lpthread $LIBS"
 
@@ -20,8 +22,11 @@
     PHP_ADD_LIBRARY(dl)
 
     case $host in
-      *darwin*) ;;
+      *darwin*)
+        PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/cares/config_darwin)
+        ;;
       *)
+        PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/cares/config_linux)
         PHP_ADD_LIBRARY(rt,,GRPC_SHARED_LIBADD)
         PHP_ADD_LIBRARY(rt)
         ;;
diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template
index 9ed32e31cffc6bb99202f48b13d109d807fb1317..cbebc5d005c1f9f81e2e6b14c4b6a9511523c5fd 100644
--- a/templates/gRPC-Core.podspec.template
+++ b/templates/gRPC-Core.podspec.template
@@ -78,7 +78,7 @@
       :submodules => true,
     }
 
-    s.ios.deployment_target = '7.1'
+    s.ios.deployment_target = '7.0'
     s.osx.deployment_target = '10.9'
     s.requires_arc = false
 
@@ -131,6 +131,7 @@
     }
 
     s.default_subspecs = 'Interface', 'Implementation'
+    s.compiler_flags = '-DGRPC_ARES=0'
 
     # Like many other C libraries, gRPC-Core has its public headers under `include/<libname>/` and its
     # sources and private headers in other directories outside `include/`. Cocoapods' linter doesn't
@@ -161,8 +162,7 @@
 
     s.subspec 'Cronet-Interface' do |ss|
       ss.header_mappings_dir = 'include/grpc'
-      ss.source_files = 'include/grpc/grpc_cronet.h',
-                        'src/core/ext/transport/cronet/transport/cronet_transport.h'
+      ss.source_files = 'include/grpc/grpc_cronet.h'
     end
 
     s.subspec 'Cronet-Implementation' do |ss|
@@ -173,7 +173,7 @@
       ss.dependency "#{s.name}/Cronet-Interface", version
 
       ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c',
-                        'src/core/ext/transport/cronet/transport/cronet_transport.c',
+                        'src/core/ext/transport/cronet/transport/cronet_transport.{c,h}',
                         'third_party/objective_c/Cronet/bidirectional_stream_c.h'
     end
 
@@ -188,7 +188,7 @@
                         'test/core/end2end/end2end_test_utils.c',
                         'test/core/end2end/tests/*.{c,h}',
                         'test/core/end2end/data/*.{c,h}',
-                        'test/core/util/debugger_macros.c',
+                        'test/core/util/debugger_macros.{c,h}',
                         'test/core/util/test_config.{c,h}',
                         'test/core/util/port.h',
                         'test/core/util/port.c',
diff --git a/templates/gRPC-ProtoRPC.podspec.template b/templates/gRPC-ProtoRPC.podspec.template
index 5d7d90d2318c31b1f1122d2648feccdd5ec65c2b..47b22dd2a52febb3c223ff0ce8a34cf5afcc5b3c 100644
--- a/templates/gRPC-ProtoRPC.podspec.template
+++ b/templates/gRPC-ProtoRPC.podspec.template
@@ -50,7 +50,7 @@
       :tag => "v#{version}",
     }
 
-    s.ios.deployment_target = '7.1'
+    s.ios.deployment_target = '7.0'
     s.osx.deployment_target = '10.9'
 
     name = 'ProtoRPC'
diff --git a/templates/gRPC-RxLibrary.podspec.template b/templates/gRPC-RxLibrary.podspec.template
index 35a06c8a856332fdbe86e72392cf9eece1dffae9..48f0df8f9e64af3ca7cb322f9154d75ce748e4d1 100644
--- a/templates/gRPC-RxLibrary.podspec.template
+++ b/templates/gRPC-RxLibrary.podspec.template
@@ -50,7 +50,7 @@
       :tag => "v#{version}",
     }
 
-    s.ios.deployment_target = '7.1'
+    s.ios.deployment_target = '7.0'
     s.osx.deployment_target = '10.9'
 
     name = 'RxLibrary'
diff --git a/templates/gRPC.podspec.template b/templates/gRPC.podspec.template
index d33ce277dc33e1fc44b4fbf15752bbb209ac7b5e..ce473608dd8996e72f08b02fe0e0c20308d192da 100644
--- a/templates/gRPC.podspec.template
+++ b/templates/gRPC.podspec.template
@@ -49,7 +49,7 @@
       :tag => "v#{version}",
     }
 
-    s.ios.deployment_target = '7.1'
+    s.ios.deployment_target = '7.0'
     s.osx.deployment_target = '10.9'
 
     name = 'GRPCClient'
diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template
index 462ea52614069e651fab784b922a44c764d7019d..80ce643d8026201a51db87690a7d35058dda3ee0 100644
--- a/templates/grpc.gemspec.template
+++ b/templates/grpc.gemspec.template
@@ -26,7 +26,7 @@
     s.files += Dir.glob('include/grpc/**/*')
     s.test_files = Dir.glob('src/ruby/spec/**/*')
     s.bindir = 'src/ruby/bin'
-    s.require_paths = %w( src/ruby/bin src/ruby/lib src/ruby/pb )
+    s.require_paths = %w( src/ruby/lib src/ruby/bin src/ruby/pb )
     s.platform      = Gem::Platform::RUBY
 
     s.add_dependency 'google-protobuf', '~> 3.1'
diff --git a/templates/package.json.template b/templates/package.json.template
index 316c28e478efeaf4239dd5778851885459e35d78..3bae8fde430a130dd1f7a459e3d56912f15c2b52 100644
--- a/templates/package.json.template
+++ b/templates/package.json.template
@@ -26,7 +26,7 @@
       "electron-build": "./node_modules/.bin/node-pre-gyp configure build --runtime=electron --disturl=https://atom.io/download/atom-shell",
       "gen_docs": "./node_modules/.bin/jsdoc -c src/node/jsdoc_conf.json",
       "coverage": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha src/node/test",
-      "install": "./node_modules/.bin/node-pre-gyp install --fallback-to-build"
+      "install": "./node_modules/.bin/node-pre-gyp install --fallback-to-build --library=static_library"
     },
     "bundledDependencies": [
       "node-pre-gyp"
@@ -36,7 +36,7 @@
       "lodash": "^4.15.0",
       "nan": "^2.0.0",
       "node-pre-gyp": "^0.6.0",
-      "protobufjs": "^5.0.0"
+      "protobufjs": "^6.7.0"
     },
     "devDependencies": {
       "async": "^2.0.1",
@@ -54,7 +54,7 @@
       "poisson-process": "^0.2.1"
     },
     "engines": {
-      "node": ">=1.1.0"
+      "node": ">=4"
     },
     "binary": {
       "module_name": "grpc_node",
diff --git a/templates/src/csharp/Grpc.Auth/project.json.template b/templates/src/csharp/Grpc.Auth/project.json.template
deleted file mode 100644
index 8bcac1ac74092fe2b2d71dfcd487259ae8899301..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.Auth/project.json.template
+++ /dev/null
@@ -1,37 +0,0 @@
-%YAML 1.2
---- |
-  {
-    "version": "${settings.csharp_version}",
-    "title": "gRPC C# Auth",
-    "authors": [ "Google Inc." ],
-    "copyright": "Copyright 2015, Google Inc.",
-    "packOptions": {
-      "summary": "Auth library for C# implementation of gRPC - an RPC library and framework",
-      "description": "Auth library for C# implementation of gRPC - an RPC library and framework. See project site for more info.",
-      "owners": [ "grpc-packages" ],
-      "licenseUrl": "https://github.com/grpc/grpc/blob/master/LICENSE",
-      "projectUrl": "https://github.com/grpc/grpc",
-      "requireLicenseAcceptance": false,
-      "tags": [ "gRPC RPC Protocol HTTP/2 Auth OAuth2" ],
-    },
-    "buildOptions": {
-      "define": [ "SIGNED" ],
-      "keyFile": "../keys/Grpc.snk",
-      "xmlDoc": true,
-      "compile": {
-        "includeFiles": [ "../Grpc.Core/Version.cs" ]
-      }
-    },
-    "dependencies": {
-      "Grpc.Core": "${settings.csharp_version}",
-      "Google.Apis.Auth": "1.16.0"
-    },
-    "frameworks": {
-      "net45": { },
-      "netstandard1.5": {
-        "dependencies": {
-          "NETStandard.Library": "1.6.0"
-        }
-      }
-    }
-  }
diff --git a/templates/src/csharp/Grpc.Core.Testing/project.json.template b/templates/src/csharp/Grpc.Core.Testing/project.json.template
deleted file mode 100644
index 7aff9911455467a5132edbb3dd7dc77fae71ffe5..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.Core.Testing/project.json.template
+++ /dev/null
@@ -1,41 +0,0 @@
-%YAML 1.2
---- |
-  {
-    "version": "${settings.csharp_version}",
-    "title": "gRPC C# Core Testing",
-    "authors": [ "Google Inc." ],
-    "copyright": "Copyright 2017, Google Inc.",
-    "packOptions": {
-      "summary": "Testing support for gRPC C#",
-      "description": "Useful when testing code that uses gRPC.",
-      "owners": [ "grpc-packages" ],
-      "licenseUrl": "https://github.com/grpc/grpc/blob/master/LICENSE",
-      "projectUrl": "https://github.com/grpc/grpc",
-      "requireLicenseAcceptance": false,
-      "tags": [ "gRPC test testing" ]
-    },
-    "buildOptions": {
-      "define": [ "SIGNED" ],
-      "keyFile": "../keys/Grpc.snk",
-      "xmlDoc": true,
-      "compile": {
-        "includeFiles": [ "../Grpc.Core/Version.cs" ]
-      }
-    },
-    "dependencies": {
-      "Grpc.Core": "${settings.csharp_version}"
-    },
-    "frameworks": {
-      "net45": {
-        "frameworkAssemblies": {
-          "System.Runtime": "",
-          "System.IO": ""
-        }
-      },
-      "netstandard1.5": {
-        "dependencies": {
-          "NETStandard.Library": "1.6.0"
-        }
-      }
-    }
-  }
diff --git a/templates/src/csharp/Grpc.Core.Tests/project.json.template b/templates/src/csharp/Grpc.Core.Tests/project.json.template
deleted file mode 100644
index 8a3e0755ffb379144a95c386f9e14a3d9f5b930c..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.Core.Tests/project.json.template
+++ /dev/null
@@ -1,30 +0,0 @@
-%YAML 1.2
---- |
-  {
-    <%include file="../build_options.include" args="executable=True"/>
-    "dependencies": {
-      "Grpc.Core": {
-        "target": "project"
-      },
-      "Newtonsoft.Json": "8.0.3",
-      "NUnit": "3.2.0",
-      "NUnitLite": "3.2.0-*",
-      "NUnit.ConsoleRunner": "3.2.0",
-      "OpenCover": "4.6.519",
-      "ReportGenerator": "2.4.4.0"
-    },
-    "frameworks": {
-      "net45": { },
-      "netcoreapp1.0": {
-        "imports": [
-          "portable-net45"
-        ],
-        "dependencies": {
-          "Microsoft.NETCore.App": {
-            "type": "platform",
-            "version": "1.0.0"
-          }
-        }
-      }
-    },
-  }
diff --git a/templates/src/csharp/Grpc.Core/Version.csproj.include.template b/templates/src/csharp/Grpc.Core/Version.csproj.include.template
new file mode 100755
index 0000000000000000000000000000000000000000..30b8d26375bfc369a238ecd84b70ded67dd1f0f9
--- /dev/null
+++ b/templates/src/csharp/Grpc.Core/Version.csproj.include.template
@@ -0,0 +1,9 @@
+%YAML 1.2
+--- |
+  <!-- This file is generated -->
+  <Project>
+    <PropertyGroup>
+      <GrpcCsharpVersion>${settings.csharp_version}</GrpcCsharpVersion>
+      <GoogleProtobufVersion>3.2.0</GoogleProtobufVersion>
+    </PropertyGroup>
+  </Project>
diff --git a/templates/src/csharp/Grpc.Core/project.json.template b/templates/src/csharp/Grpc.Core/project.json.template
deleted file mode 100644
index 120a9943e30e543a709dbe37e0702279b1653572..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.Core/project.json.template
+++ /dev/null
@@ -1,47 +0,0 @@
-%YAML 1.2
---- |
-  {
-    "version": "${settings.csharp_version}",
-    "title": "gRPC C# Core",
-    "authors": [ "Google Inc." ],
-    "copyright": "Copyright 2015, Google Inc.",
-    "packOptions": {
-      "summary": "Core C# implementation of gRPC - an RPC library and framework",
-      "description": "Core C# implementation of gRPC - an RPC library and framework. See project site for more info.",
-      "owners": [ "grpc-packages" ],
-      "licenseUrl": "https://github.com/grpc/grpc/blob/master/LICENSE",
-      "projectUrl": "https://github.com/grpc/grpc",
-      "requireLicenseAcceptance": false,
-      "tags": [ "gRPC RPC Protocol HTTP/2" ],
-      "files": {
-        "mappings": {
-          "build/net45/": "Grpc.Core.targets",
-          "runtimes/win/native/grpc_csharp_ext.x86.dll": "../nativelibs/windows_x86/grpc_csharp_ext.dll",
-          "runtimes/win/native/grpc_csharp_ext.x64.dll": "../nativelibs/windows_x64/grpc_csharp_ext.dll",
-          "runtimes/linux/native/libgrpc_csharp_ext.x86.so": "../nativelibs/linux_x86/libgrpc_csharp_ext.so",
-          "runtimes/linux/native/libgrpc_csharp_ext.x64.so": "../nativelibs/linux_x64/libgrpc_csharp_ext.so",
-          "runtimes/osx/native/libgrpc_csharp_ext.x86.dylib": "../nativelibs/macosx_x86/libgrpc_csharp_ext.dylib",
-          "runtimes/osx/native/libgrpc_csharp_ext.x64.dylib": "../nativelibs/macosx_x64/libgrpc_csharp_ext.dylib"
-        }
-      }
-    },
-    "buildOptions": {
-      "embed": [ "../../../etc/roots.pem" ],
-      "define": [ "SIGNED" ],
-      "keyFile": "../keys/Grpc.snk",
-      "xmlDoc": true
-    },
-    "dependencies": {
-      "System.Interactive.Async": "3.1.1"
-    },
-    "frameworks": {
-      "net45": { },
-      "netstandard1.5": {
-        "dependencies": {
-          "NETStandard.Library": "1.6.0",
-          "System.Runtime.Loader": "4.0.0",
-          "System.Threading.Thread": "4.0.0"
-        }
-      }
-    }
-  }
diff --git a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template
deleted file mode 100644
index ae4ea2aaac77cb70891680217e67a97737b31700..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template
+++ /dev/null
@@ -1,21 +0,0 @@
-%YAML 1.2
---- |
-  {
-    <%include file="../build_options.include" args="executable=True"/>
-    "dependencies": {
-      "Grpc.Examples": {
-        "target": "project"
-      }
-    },
-    "frameworks": {
-      "net45": { },
-      "netcoreapp1.0": {
-        "dependencies": {
-          "Microsoft.NETCore.App": {
-            "type": "platform",
-            "version": "1.0.0"
-          }
-        }
-      }
-    }
-  }
diff --git a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template
deleted file mode 100644
index ae4ea2aaac77cb70891680217e67a97737b31700..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template
+++ /dev/null
@@ -1,21 +0,0 @@
-%YAML 1.2
---- |
-  {
-    <%include file="../build_options.include" args="executable=True"/>
-    "dependencies": {
-      "Grpc.Examples": {
-        "target": "project"
-      }
-    },
-    "frameworks": {
-      "net45": { },
-      "netcoreapp1.0": {
-        "dependencies": {
-          "Microsoft.NETCore.App": {
-            "type": "platform",
-            "version": "1.0.0"
-          }
-        }
-      }
-    }
-  }
diff --git a/templates/src/csharp/Grpc.Examples.Tests/project.json.template b/templates/src/csharp/Grpc.Examples.Tests/project.json.template
deleted file mode 100644
index 0a9eb7c74d3db14514156e0d70ad15b8ea1d5932..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.Examples.Tests/project.json.template
+++ /dev/null
@@ -1,26 +0,0 @@
-%YAML 1.2
---- |
-  {
-    <%include file="../build_options.include" args="executable=True"/>
-    "dependencies": {
-      "Grpc.Examples": {
-        "target": "project"
-      },
-      "NUnit": "3.2.0",
-      "NUnitLite": "3.2.0-*"
-    },
-    "frameworks": {
-      "net45": { },
-      "netcoreapp1.0": {
-        "imports": [
-          "portable-net45"
-        ],
-        "dependencies": {
-          "Microsoft.NETCore.App": {
-            "type": "platform",
-            "version": "1.0.0"
-          }
-        }
-      }
-    }
-  }
diff --git a/templates/src/csharp/Grpc.Examples/project.json.template b/templates/src/csharp/Grpc.Examples/project.json.template
deleted file mode 100644
index b8a8314de177ab7376c669d02f970c476e78c9f2..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.Examples/project.json.template
+++ /dev/null
@@ -1,27 +0,0 @@
-%YAML 1.2
---- |
-  {
-    <%include file="../build_options.include" args="executable=False"/>
-    "dependencies": {
-      "Grpc.Core": {
-        "target": "project"
-      },
-      "Google.Protobuf": "3.0.0"
-    },
-    "frameworks": {
-      "net45": {
-        "frameworkAssemblies": {
-          "System.Runtime": "",
-          "System.IO": ""
-        }
-      },
-      "netcoreapp1.0": {
-        "dependencies": {
-          "Microsoft.NETCore.App": {
-            "type": "platform",
-            "version": "1.0.0"
-          }
-        }
-      }
-    }
-  }
diff --git a/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template b/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template
deleted file mode 100644
index c63da96db75aa13d5fe268584ca5a35d267de3b8..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template
+++ /dev/null
@@ -1,26 +0,0 @@
-%YAML 1.2
---- |
-  {
-    <%include file="../build_options.include" args="executable=True"/>
-    "dependencies": {
-      "Grpc.HealthCheck": {
-        "target": "project"
-      },
-      "NUnit": "3.2.0",
-      "NUnitLite": "3.2.0-*"
-    },
-    "frameworks": {
-      "net45": { },
-      "netcoreapp1.0": {
-        "imports": [
-          "portable-net45"
-        ],
-        "dependencies": {
-          "Microsoft.NETCore.App": {
-            "type": "platform",
-            "version": "1.0.0"
-          }
-        }
-      }
-    }
-  }
diff --git a/templates/src/csharp/Grpc.HealthCheck/project.json.template b/templates/src/csharp/Grpc.HealthCheck/project.json.template
deleted file mode 100644
index cba68940153c16270f5bb02612c4e8db6fea0876..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.HealthCheck/project.json.template
+++ /dev/null
@@ -1,42 +0,0 @@
-%YAML 1.2
---- |
-  {
-    "version": "${settings.csharp_version}",
-    "title": "gRPC C# Healthchecking",
-    "authors": [ "Google Inc." ],
-    "copyright": "Copyright 2015, Google Inc.",
-    "packOptions": {
-      "summary": "Implementation of gRPC health service",
-      "description": "Example implementation of grpc.health.v1 service that can be used for health-checking.",
-      "owners": [ "grpc-packages" ],
-      "licenseUrl": "https://github.com/grpc/grpc/blob/master/LICENSE",
-      "projectUrl": "https://github.com/grpc/grpc",
-      "requireLicenseAcceptance": false,
-      "tags": [ "gRPC health check" ]
-    },
-    "buildOptions": {
-      "define": [ "SIGNED" ],
-      "keyFile": "../keys/Grpc.snk",
-      "xmlDoc": true,
-      "compile": {
-        "includeFiles": [ "../Grpc.Core/Version.cs" ]
-      }
-    },
-    "dependencies": {
-      "Grpc.Core": "${settings.csharp_version}",
-      "Google.Protobuf": "3.0.0"
-    },
-    "frameworks": {
-      "net45": {
-        "frameworkAssemblies": {
-          "System.Runtime": "",
-          "System.IO": ""
-        }
-      },
-      "netstandard1.5": {
-        "dependencies": {
-          "NETStandard.Library": "1.6.0"
-        }
-      }
-    }
-  }
diff --git a/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template
deleted file mode 100644
index 83b8a9befa366dc047160eca6ecf7487ba51addd..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template
+++ /dev/null
@@ -1,24 +0,0 @@
-%YAML 1.2
---- |
-  {
-    <%include file="../build_options.include" args="executable=True,includeData=True"/>
-    "dependencies": {
-      "Grpc.IntegrationTesting": {
-        "target": "project"
-      }
-    },
-    "frameworks": {
-      "net45": { },
-      "netcoreapp1.0": {
-        "imports": [
-          "portable-net45"
-        ],
-        "dependencies": {
-          "Microsoft.NETCore.App": {
-            "type": "platform",
-            "version": "1.0.0"
-          }
-        }
-      }
-    }
-  }
diff --git a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template
deleted file mode 100644
index 8304d20f2ec41a42a3402339dcc01f6a27de2d3b..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template
+++ /dev/null
@@ -1,29 +0,0 @@
-%YAML 1.2
---- |
-  {
-    <%include file="../build_options.include" args="executable=True,includeData=True"/>
-    "dependencies": {
-      "Grpc.IntegrationTesting": {
-        "target": "project"
-      }
-    },
-    "frameworks": {
-      "net45": { },
-      "netcoreapp1.0": {
-        "imports": [
-          "portable-net45"
-        ],
-        "dependencies": {
-          "Microsoft.NETCore.App": {
-            "type": "platform",
-            "version": "1.0.0"
-          }
-        }
-      }
-    },
-    "runtimeOptions": {
-      "configProperties": {
-        "System.GC.Server": true
-      }
-    }
-  }
diff --git a/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template
deleted file mode 100644
index 83b8a9befa366dc047160eca6ecf7487ba51addd..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template
+++ /dev/null
@@ -1,24 +0,0 @@
-%YAML 1.2
---- |
-  {
-    <%include file="../build_options.include" args="executable=True,includeData=True"/>
-    "dependencies": {
-      "Grpc.IntegrationTesting": {
-        "target": "project"
-      }
-    },
-    "frameworks": {
-      "net45": { },
-      "netcoreapp1.0": {
-        "imports": [
-          "portable-net45"
-        ],
-        "dependencies": {
-          "Microsoft.NETCore.App": {
-            "type": "platform",
-            "version": "1.0.0"
-          }
-        }
-      }
-    }
-  }
diff --git a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template
deleted file mode 100644
index 83b8a9befa366dc047160eca6ecf7487ba51addd..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template
+++ /dev/null
@@ -1,24 +0,0 @@
-%YAML 1.2
---- |
-  {
-    <%include file="../build_options.include" args="executable=True,includeData=True"/>
-    "dependencies": {
-      "Grpc.IntegrationTesting": {
-        "target": "project"
-      }
-    },
-    "frameworks": {
-      "net45": { },
-      "netcoreapp1.0": {
-        "imports": [
-          "portable-net45"
-        ],
-        "dependencies": {
-          "Microsoft.NETCore.App": {
-            "type": "platform",
-            "version": "1.0.0"
-          }
-        }
-      }
-    }
-  }
diff --git a/templates/src/csharp/Grpc.IntegrationTesting/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting/project.json.template
deleted file mode 100644
index 3ce94e58387db8ba8c0f1d58e889230a13b457de..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.IntegrationTesting/project.json.template
+++ /dev/null
@@ -1,38 +0,0 @@
-%YAML 1.2
---- |
-  {
-    <%include file="../build_options.include" args="executable=True,includeData=True"/>
-    "dependencies": {
-      "Grpc.Auth": {
-        "target": "project"
-      },
-      "Grpc.Core": {
-        "target": "project"
-      },
-      "Google.Protobuf": "3.0.0",
-      "CommandLineParser.Unofficial": "2.0.275",
-      "Moq": "4.6.38-alpha",
-      "NUnit": "3.2.0",
-      "NUnitLite": "3.2.0-*"
-    },
-    "frameworks": {
-      "net45": {
-        "frameworkAssemblies": {
-          "System.Runtime": "",
-          "System.IO": ""
-        }
-      },
-      "netcoreapp1.0": {
-        "imports": [
-          "portable-net45"
-        ],
-        "dependencies": {
-          "Microsoft.NETCore.App": {
-            "type": "platform",
-            "version": "1.0.0"
-          },
-          "System.Linq.Expressions": "4.1.0"
-        }
-      }
-    }
-  }
diff --git a/templates/src/csharp/Grpc.Reflection.Tests/project.json.template b/templates/src/csharp/Grpc.Reflection.Tests/project.json.template
deleted file mode 100644
index 2869609138b3c7d3ffeb635dd485089c80fc3469..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.Reflection.Tests/project.json.template
+++ /dev/null
@@ -1,26 +0,0 @@
-%YAML 1.2
---- |
-  {
-    <%include file="../build_options.include" args="executable=True"/>
-    "dependencies": {
-      "Grpc.Reflection": {
-        "target": "project"
-      },
-      "NUnit": "3.2.0",
-      "NUnitLite": "3.2.0-*"
-    },
-    "frameworks": {
-      "net45": { },
-      "netcoreapp1.0": {
-        "imports": [
-          "portable-net45"
-        ],
-        "dependencies": {
-          "Microsoft.NETCore.App": {
-            "type": "platform",
-            "version": "1.0.0"
-          }
-        }
-      }
-    }
-  }
diff --git a/templates/src/csharp/Grpc.Reflection/project.json.template b/templates/src/csharp/Grpc.Reflection/project.json.template
deleted file mode 100644
index 8a33e1ccc97750b690052a1d05a375323c1ea87f..0000000000000000000000000000000000000000
--- a/templates/src/csharp/Grpc.Reflection/project.json.template
+++ /dev/null
@@ -1,42 +0,0 @@
-%YAML 1.2
---- |
-  {
-    "version": "${settings.csharp_version}",
-    "title": "gRPC C# Reflection",
-    "authors": [ "Google Inc." ],
-    "copyright": "Copyright 2016, Google Inc.",
-    "packOptions": {
-      "summary": "Implementation of gRPC reflection service",
-      "description": "Provides information about services running on a gRPC C# server.",
-      "owners": [ "grpc-packages" ],
-      "licenseUrl": "https://github.com/grpc/grpc/blob/master/LICENSE",
-      "projectUrl": "https://github.com/grpc/grpc",
-      "requireLicenseAcceptance": false,
-      "tags": [ "gRPC reflection" ]
-    },
-    "buildOptions": {
-      "define": [ "SIGNED" ],
-      "keyFile": "../keys/Grpc.snk",
-      "xmlDoc": true,
-      "compile": {
-        "includeFiles": [ "../Grpc.Core/Version.cs" ]
-      }
-    },
-    "dependencies": {
-      "Grpc.Core": "${settings.csharp_version}",
-      "Google.Protobuf": "3.0.0"
-    },
-    "frameworks": {
-      "net45": {
-        "frameworkAssemblies": {
-          "System.Runtime": "",
-          "System.IO": ""
-        }
-      },
-      "netstandard1.5": {
-        "dependencies": {
-          "NETStandard.Library": "1.6.0"
-        }
-      }
-    }
-  }
diff --git a/templates/src/csharp/build_options.include b/templates/src/csharp/build_options.include
deleted file mode 100644
index db4cc198039cc30ee666086e422d7fd4739d4fb3..0000000000000000000000000000000000000000
--- a/templates/src/csharp/build_options.include
+++ /dev/null
@@ -1,56 +0,0 @@
-<%page args="executable=False,includeData=False"/>\
-"buildOptions": {
-  % if executable:
-    "emitEntryPoint": true
-  % endif
-  },
-  % if executable:
-  "configurations": {
-    "Debug": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            % if includeData:
-            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
-            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
-            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            % endif
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    },
-    "Release": {
-      "buildOptions": {
-        "define": [ "SIGNED" ],
-        "keyFile": "../keys/Grpc.snk",
-        "xmlDoc": true,
-        "compile": {
-          "includeFiles": [ "../Grpc.Core/Version.cs" ]
-        },
-        "copyToOutput": {
-          "mappings": {
-            % if includeData:
-            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
-            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
-            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            % endif
-            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
-            "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
-            "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
-          }
-        }
-      }
-    }
-  },
-  %endif
diff --git a/templates/src/csharp/build_packages_dotnetcli.bat.template b/templates/src/csharp/build_packages_dotnetcli.bat.template
index 2f91d485ec401945a1d3beb2e2cff2a7586f941f..91808e0d266875fdeab67de019873c24f975e400 100755
--- a/templates/src/csharp/build_packages_dotnetcli.bat.template
+++ b/templates/src/csharp/build_packages_dotnetcli.bat.template
@@ -31,11 +31,10 @@
   
   @rem Current package versions
   set VERSION=${settings.csharp_version}
-  set PROTOBUF_VERSION=3.0.0
   
   @rem Adjust the location of nuget.exe
   set NUGET=C:\nuget\nuget.exe
-  set DOTNET=C:\dotnet\dotnet.exe
+  set DOTNET=dotnet
   
   set -ex
   
@@ -58,13 +57,16 @@
   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${"\\"}
   
-  %%DOTNET% restore . || goto :error
+  %%DOTNET% restore Grpc.sln || goto :error
   
-  %%DOTNET% pack --configuration Release Grpc.Core\project.json --output ..\..\artifacts || goto :error
-  %%DOTNET% pack --configuration Release Grpc.Core.Testing\project.json --output ..\..\artifacts || goto :error
-  %%DOTNET% pack --configuration Release Grpc.Auth\project.json --output ..\..\artifacts || goto :error
-  %%DOTNET% pack --configuration Release Grpc.HealthCheck\project.json --output ..\..\artifacts || goto :error
-  %%DOTNET% pack --configuration Release Grpc.Reflection\project.json --output ..\..\artifacts || goto :error
+  @rem To be able to build, we also need to put grpc_csharp_ext to its normal location
+  xcopy /Y /I nativelibs\windows_x64\grpc_csharp_ext.dll ..\..\cmake\build\x64\Release${"\\"}
+  
+  %%DOTNET% pack --configuration Release Grpc.Core --output ..\..\..\artifacts || goto :error
+  %%DOTNET% pack --configuration Release Grpc.Core.Testing --output ..\..\..\artifacts || goto :error
+  %%DOTNET% pack --configuration Release Grpc.Auth --output ..\..\..\artifacts || goto :error
+  %%DOTNET% pack --configuration Release Grpc.HealthCheck --output ..\..\..\artifacts || goto :error
+  %%DOTNET% pack --configuration Release Grpc.Reflection --output ..\..\..\artifacts || goto :error
   
   %%NUGET% pack Grpc.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts || goto :error
   %%NUGET% pack Grpc.Tools.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts
diff --git a/templates/src/csharp/build_packages_dotnetcli.sh.template b/templates/src/csharp/build_packages_dotnetcli.sh.template
index c5364377b99d6d22d0f7a49c02564f87dfc8e0e5..374b236f93cf49dd9da52fcbdac684f073e86541 100755
--- a/templates/src/csharp/build_packages_dotnetcli.sh.template
+++ b/templates/src/csharp/build_packages_dotnetcli.sh.template
@@ -60,13 +60,17 @@
   cp $EXTERNAL_GIT_ROOT/architecture=x86,language=protoc,platform=macos/artifacts/* protoc_plugins/macosx_x86 || true
   cp $EXTERNAL_GIT_ROOT/architecture=x64,language=protoc,platform=macos/artifacts/* protoc_plugins/macosx_x64 || true
   
-  dotnet restore .
+  dotnet restore Grpc.sln
   
-  dotnet pack --configuration Release Grpc.Core/project.json --output ../../artifacts
-  dotnet pack --configuration Release Grpc.Core.Testing/project.json --output ../../artifacts
-  dotnet pack --configuration Release Grpc.Auth/project.json --output ../../artifacts
-  dotnet pack --configuration Release Grpc.HealthCheck/project.json --output ../../artifacts
-  dotnet pack --configuration Release Grpc.Reflection/project.json --output ../../artifacts
+  # To be able to build, we also need to put grpc_csharp_ext to its normal location
+  mkdir -p ../../libs/opt
+  cp nativelibs/linux_x64/libgrpc_csharp_ext.so ../../libs/opt
+  
+  dotnet pack --configuration Release Grpc.Core --output ../../../artifacts
+  dotnet pack --configuration Release Grpc.Core.Testing --output ../../../artifacts
+  dotnet pack --configuration Release Grpc.Auth --output ../../../artifacts
+  dotnet pack --configuration Release Grpc.HealthCheck --output ../../../artifacts
+  dotnet pack --configuration Release Grpc.Reflection --output ../../../artifacts
   
   nuget pack Grpc.nuspec -Version "${settings.csharp_version}" -OutputDirectory ../../artifacts
   nuget pack Grpc.Tools.nuspec -Version "${settings.csharp_version}" -OutputDirectory ../../artifacts
diff --git a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template
index 3a10cfab3cca31e21c5e0ad2e572bd80c7a5cecd..d7d84f3c774442378e8f3776d8c1251a46df9997 100644
--- a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template
+++ b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template
@@ -103,9 +103,9 @@
     s.preserve_paths = plugin
 
     # Restrict the protoc version to the one supported by this plugin.
-    s.dependency '!ProtoCompiler', '3.1.0'
+    s.dependency '!ProtoCompiler', '3.2.0'
     # For the Protobuf dependency not to complain:
-    s.ios.deployment_target = '7.1'
+    s.ios.deployment_target = '7.0'
     s.osx.deployment_target = '10.9'
     # Restrict the gRPC runtime version to the one supported by this plugin.
     s.dependency 'gRPC-ProtoRPC', v
diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template b/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template
similarity index 81%
rename from templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template
rename to templates/src/python/grpcio/grpc/_grpcio_metadata.py.template
index 092f04dac6c991f902c80847b3064bce65bfcf97..3d325b4d3d8e7e71664bdc258b4c015c2dcab6d4 100644
--- a/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template
+++ b/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template
@@ -1,6 +1,6 @@
 %YAML 1.2
 --- |
-  # Copyright 2015, Google Inc.
+  # Copyright 2017, Google Inc.
   # All rights reserved.
   #
   # Redistribution and use in source and binary forms, with or without
@@ -28,14 +28,7 @@
   # 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:jessie
-  
-  <%include file="../../apt_get_basic.include"/>
-  <%include file="../../python_deps.include"/>
-  <%include file="../../csharp_deps.include"/>
-  <%include file="../../csharp_dotnetcli_deps.include"/>
-  <%include file="../../run_tests_addons.include"/>
-  # Define the default command.
-  CMD ["bash"]
-  
+
+  # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!!
+
+  __version__ = """${settings.python_version.pep440()}"""
diff --git a/templates/tools/dockerfile/apt_get_pyenv.include b/templates/tools/dockerfile/apt_get_pyenv.include
index 816b27904f603f63b30eef53d96e74779f9a3722..ef0964e597535baeff50dfe55d29a287e20a9b05 100644
--- a/templates/tools/dockerfile/apt_get_pyenv.include
+++ b/templates/tools/dockerfile/apt_get_pyenv.include
@@ -12,6 +12,9 @@ RUN apt-get update && apt-get install -y ${'\\'}
 
 # Install Pyenv and dev Python versions 3.5 and 3.6
 RUN curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash
+ENV PATH /root/.pyenv/bin:$PATH
+RUN eval "$(pyenv init -)"
+RUN eval "$(pyenv virtualenv-init -)"
 RUN pyenv update
 RUN pyenv install 3.5-dev
 RUN pyenv install 3.6-dev
diff --git a/templates/tools/dockerfile/csharp_deps.include b/templates/tools/dockerfile/csharp_deps.include
index 7e89dec2cc2ed5e42fce4ed833713dd372eb5279..612b119e1c9d1a33bf3e057e659aeeb47ed55637 100644
--- a/templates/tools/dockerfile/csharp_deps.include
+++ b/templates/tools/dockerfile/csharp_deps.include
@@ -6,7 +6,6 @@ RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
 
 # Install dependencies
 RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y ${'\\'}
diff --git a/templates/tools/dockerfile/csharp_dotnetcli_deps.include b/templates/tools/dockerfile/csharp_dotnetcli_deps.include
index 430f3fa3f22e24e21549b2fdbd46f4cb32c2cd2d..bc88d2bfa39ca4a70ba294cae3d4874917b4735e 100644
--- a/templates/tools/dockerfile/csharp_dotnetcli_deps.include
+++ b/templates/tools/dockerfile/csharp_dotnetcli_deps.include
@@ -1,7 +1,11 @@
 # Install dotnet SDK based on https://www.microsoft.com/net/core#debian
 RUN apt-get update && apt-get install -y curl libunwind8 gettext
-RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130
-RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet
+# dotnet-dev-1.0.0-preview2-003131
+RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530
+RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet
+# dotnet-dev-1.0.1
+RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453
+RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet
 RUN ln -s /opt/dotnet/dotnet /usr/local/bin
 
 # Trigger the population of the local package cache
diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template
index da0c70aee0cd616b281ebbdaef8cf2143374780e..092f04dac6c991f902c80847b3064bce65bfcf97 100644
--- a/templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template
+++ b/templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template
@@ -34,6 +34,7 @@
   <%include file="../../apt_get_basic.include"/>
   <%include file="../../python_deps.include"/>
   <%include file="../../csharp_deps.include"/>
+  <%include file="../../csharp_dotnetcli_deps.include"/>
   <%include file="../../run_tests_addons.include"/>
   # Define the default command.
   CMD ["bash"]
diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_go/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_go/Dockerfile.template
index 38a5ca725daf2636935f92135ff9da000f94a498..bf025d8037188cd92f24ae6415e79ecec6dcad32 100644
--- a/templates/tools/dockerfile/interoptest/grpc_interop_go/Dockerfile.template
+++ b/templates/tools/dockerfile/interoptest/grpc_interop_go/Dockerfile.template
@@ -29,7 +29,7 @@
   # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
-  FROM golang:1.5
+  FROM golang:latest
   
   <%include file="../../go_path.include"/>
   <%include file="../../python_deps.include"/>
diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile.template
index 6204c3e2cb297ff84fb3cb455c6f633c070f4740..b517921f08724fbc6f753b241052083f30f16b39 100644
--- a/templates/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile.template
+++ b/templates/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile.template
@@ -29,11 +29,11 @@
   # (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 golang:1.5
+  FROM golang:latest
   
   <%include file="../../go_path.include"/>
   <%include file="../../python_deps.include"/>
-  RUN pip install twisted h2
+  RUN pip install twisted h2==2.6.1 hyper
 
   # Define the default command.
   CMD ["bash"]
diff --git a/templates/tools/dockerfile/python_deps.include b/templates/tools/dockerfile/python_deps.include
index 26c91f495d546ff460af292606edb8950133c95b..2c129814184b1826e5f835f6df6098931713d6d3 100644
--- a/templates/tools/dockerfile/python_deps.include
+++ b/templates/tools/dockerfile/python_deps.include
@@ -11,4 +11,4 @@ RUN apt-get update && apt-get install -y ${'\\'}
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
diff --git a/templates/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile.template b/templates/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile.template
index e02254cd53567b51dfbda412e73d3b1d266812d0..ad8ad71b5fab2ea955b43efcc4fccd0da08b3b1e 100644
--- a/templates/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile.template
+++ b/templates/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile.template
@@ -29,7 +29,7 @@
   # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
-  FROM golang:1.5
+  FROM golang:latest
   
   <%include file="../../gcp_api_libraries.include"/>
   <%include file="../../python_deps.include"/>
diff --git a/templates/tools/dockerfile/test/bazel/Dockerfile.template b/templates/tools/dockerfile/test/bazel/Dockerfile.template
deleted file mode 100644
index 82f90bef68153074618c64516ee187421a0095db..0000000000000000000000000000000000000000
--- a/templates/tools/dockerfile/test/bazel/Dockerfile.template
+++ /dev/null
@@ -1,48 +0,0 @@
-%YAML 1.2
---- |
-  # 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.
-  
-  FROM ubuntu:15.10
-  
-  <%include file="../../apt_get_basic.include"/>
-
-  #========================
-  # Bazel installation
-  RUN apt-get install -y software-properties-common g++
-  RUN echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" > /etc/apt/sources.list.d/bazel.list
-  RUN curl https://bazel.build/bazel-release.pub.gpg | apt-key add -
-  RUN apt-get -y update
-  RUN apt-get -y install bazel
-
-  RUN mkdir -p /var/local/jenkins
-  
-  # Define the default command.
-  CMD ["bash"]
-  
diff --git a/templates/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile.template b/templates/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile.template
deleted file mode 100644
index 092f04dac6c991f902c80847b3064bce65bfcf97..0000000000000000000000000000000000000000
--- a/templates/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile.template
+++ /dev/null
@@ -1,41 +0,0 @@
-%YAML 1.2
---- |
-  # 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.
-  
-  FROM debian:jessie
-  
-  <%include file="../../apt_get_basic.include"/>
-  <%include file="../../python_deps.include"/>
-  <%include file="../../csharp_deps.include"/>
-  <%include file="../../csharp_dotnetcli_deps.include"/>
-  <%include file="../../run_tests_addons.include"/>
-  # Define the default command.
-  CMD ["bash"]
-  
diff --git a/templates/tools/dockerfile/test/csharp_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/csharp_jessie_x64/Dockerfile.template
index da0c70aee0cd616b281ebbdaef8cf2143374780e..092f04dac6c991f902c80847b3064bce65bfcf97 100644
--- a/templates/tools/dockerfile/test/csharp_jessie_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/csharp_jessie_x64/Dockerfile.template
@@ -34,6 +34,7 @@
   <%include file="../../apt_get_basic.include"/>
   <%include file="../../python_deps.include"/>
   <%include file="../../csharp_deps.include"/>
+  <%include file="../../csharp_dotnetcli_deps.include"/>
   <%include file="../../run_tests_addons.include"/>
   # Define the default command.
   CMD ["bash"]
diff --git a/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template
index fdf44312ec31845d88f83301eb739153a8605684..93d26b559453a99c04bf74451654fc3bd5cd0848 100644
--- a/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template
@@ -38,6 +38,10 @@
   <%include file="../../php_deps.include"/>
   <%include file="../../ruby_deps.include"/>
   <%include file="../../python_deps.include"/>
+  # Install coverage for Python test coverage reporting
+  RUN pip install coverage
+  ENV PATH ~/.local/bin:$PATH
+
   <%include file="../../run_tests_addons.include"/>
   # Define the default command.
   CMD ["bash"]
diff --git a/templates/tools/run_tests/generated/sources_and_headers.json.template b/templates/tools/run_tests/generated/sources_and_headers.json.template
index 1c5c9747d65ce7a69190c78135d26faaf00bd65c..c7dc3c837d14f8542bb288bfc5e1c2f7cc436821 100644
--- a/templates/tools/run_tests/generated/sources_and_headers.json.template
+++ b/templates/tools/run_tests/generated/sources_and_headers.json.template
@@ -9,7 +9,7 @@
     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'])
+        out.extend(fmt % name for fmt in ['%s.grpc.pb.h', '%s.pb.h', '%s_mock.grpc.pb.h'])
     return out
 
   def all_targets(targets, libs, filegroups):
diff --git a/src/core/ext/client_channel/default_initial_connect_string.c b/test/build/c-ares.c
similarity index 85%
rename from src/core/ext/client_channel/default_initial_connect_string.c
rename to test/build/c-ares.c
index 6db82d84ef15a3ded8e816726efcc7a7da88be0e..c954e9397f8ac50d25fa137556b58fd0c61b192f 100644
--- a/src/core/ext/client_channel/default_initial_connect_string.c
+++ b/test/build/c-ares.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,8 +31,13 @@
  *
  */
 
-#include <grpc/slice.h>
-#include "src/core/lib/iomgr/resolve_address.h"
+#include <ares.h>
 
-void grpc_set_default_initial_connect_string(grpc_resolved_address **addr,
-                                             grpc_slice *initial_str) {}
+int main(void) {
+  ares_channel channelptr;
+
+  ares_init(&channelptr);
+  ares_destroy(channelptr);
+
+  return 0;
+}
diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c
index fdedfe284e2edcc6a355f5f995eac1afbafd7d49..8dbc5aa861294a3a797717a222e4f462cf4650be 100644
--- a/test/core/bad_client/bad_client.c
+++ b/test/core/bad_client/bad_client.c
@@ -40,9 +40,9 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 
+#include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/channel_stack.h"
-#include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/iomgr/endpoint_pair.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/murmur_hash.h"
@@ -104,6 +104,7 @@ void grpc_run_bad_client_test(
   grpc_slice_buffer outgoing;
   grpc_closure done_write_closure;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_completion_queue *shutdown_cq;
 
   hex = gpr_dump(client_payload, client_payload_length,
                  GPR_DUMP_HEX | GPR_DUMP_ASCII);
@@ -117,14 +118,11 @@ void grpc_run_bad_client_test(
   grpc_init();
 
   /* Create endpoints */
-  grpc_resource_quota *resource_quota =
-      grpc_resource_quota_create("bad_client_test");
-  sfd = grpc_iomgr_create_endpoint_pair("fixture", resource_quota, 65536);
-  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
+  sfd = grpc_iomgr_create_endpoint_pair("fixture", NULL);
 
   /* Create server, completion events */
   a.server = grpc_server_create(NULL, NULL);
-  a.cq = grpc_completion_queue_create(NULL);
+  a.cq = grpc_completion_queue_create_for_next(NULL);
   gpr_event_init(&a.done_thd);
   gpr_event_init(&a.done_write);
   a.validator = server_validator;
@@ -163,8 +161,9 @@ void grpc_run_bad_client_test(
       gpr_event_wait(&a.done_write, grpc_timeout_seconds_to_deadline(5)));
 
   if (flags & GRPC_BAD_CLIENT_DISCONNECT) {
-    grpc_endpoint_shutdown(&exec_ctx, sfd.client,
-                           GRPC_ERROR_CREATE("Forced Disconnect"));
+    grpc_endpoint_shutdown(
+        &exec_ctx, sfd.client,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Disconnect"));
     grpc_endpoint_destroy(&exec_ctx, sfd.client);
     grpc_exec_ctx_finish(&exec_ctx);
     sfd.client = NULL;
@@ -190,15 +189,19 @@ void grpc_run_bad_client_test(
       grpc_slice_buffer_destroy_internal(&exec_ctx, &args.incoming);
     }
     // Shutdown.
-    grpc_endpoint_shutdown(&exec_ctx, sfd.client,
-                           GRPC_ERROR_CREATE("Test Shutdown"));
+    grpc_endpoint_shutdown(
+        &exec_ctx, sfd.client,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown"));
     grpc_endpoint_destroy(&exec_ctx, sfd.client);
     grpc_exec_ctx_finish(&exec_ctx);
   }
-  grpc_server_shutdown_and_notify(a.server, a.cq, NULL);
+
+  shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
+  grpc_server_shutdown_and_notify(a.server, shutdown_cq, NULL);
   GPR_ASSERT(grpc_completion_queue_pluck(
-                 a.cq, NULL, grpc_timeout_seconds_to_deadline(1), NULL)
+                 shutdown_cq, NULL, grpc_timeout_seconds_to_deadline(1), NULL)
                  .type == GRPC_OP_COMPLETE);
+  grpc_completion_queue_destroy(shutdown_cq);
   grpc_server_destroy(a.server);
   grpc_completion_queue_destroy(a.cq);
   grpc_slice_buffer_destroy_internal(&exec_ctx, &outgoing);
diff --git a/test/core/bad_client/tests/head_of_line_blocking.c b/test/core/bad_client/tests/head_of_line_blocking.c
index 64cb79d82f2dfd32bac273ab00df0f97a438d28a..b0d788bf2287a977c4955b17c5dac390458675d7 100644
--- a/test/core/bad_client/tests/head_of_line_blocking.c
+++ b/test/core/bad_client/tests/head_of_line_blocking.c
@@ -103,7 +103,7 @@ static void verifier(grpc_server *server, grpc_completion_queue *cq,
   GPR_ASSERT(payload != NULL);
 
   grpc_metadata_array_destroy(&request_metadata_recv);
-  grpc_call_destroy(s);
+  grpc_call_unref(s);
   grpc_byte_buffer_destroy(payload);
   cq_verifier_destroy(cqv);
 }
diff --git a/test/core/bad_client/tests/large_metadata.c b/test/core/bad_client/tests/large_metadata.c
index f672776a9fb1b62bfb95679f798ec0ff01318e00..d7a3ce9461c98f39f0ae6e3d53176989483b903b 100644
--- a/test/core/bad_client/tests/large_metadata.c
+++ b/test/core/bad_client/tests/large_metadata.c
@@ -131,7 +131,7 @@ static void server_verifier(grpc_server *server, grpc_completion_queue *cq,
 
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
-  grpc_call_destroy(s);
+  grpc_call_unref(s);
   cq_verifier_destroy(cqv);
 }
 
@@ -177,7 +177,7 @@ static void server_verifier_sends_too_much_metadata(grpc_server *server,
   grpc_slice_unref(meta.value);
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
-  grpc_call_destroy(s);
+  grpc_call_unref(s);
   cq_verifier_destroy(cqv);
 }
 
diff --git a/test/core/bad_client/tests/server_registered_method.c b/test/core/bad_client/tests/server_registered_method.c
index e174af5931ac6ebd069c43ba5a0dd0f031cf2cfb..c5af0bae767333bf0a32b63b16c162b652164fee 100644
--- a/test/core/bad_client/tests/server_registered_method.c
+++ b/test/core/bad_client/tests/server_registered_method.c
@@ -76,7 +76,7 @@ static void verifier_succeeds(grpc_server *server, grpc_completion_queue *cq,
   GPR_ASSERT(payload != NULL);
 
   grpc_metadata_array_destroy(&request_metadata_recv);
-  grpc_call_destroy(s);
+  grpc_call_unref(s);
   grpc_byte_buffer_destroy(payload);
   cq_verifier_destroy(cqv);
 }
@@ -102,7 +102,7 @@ static void verifier_fails(grpc_server *server, grpc_completion_queue *cq,
   GPR_ASSERT(payload == NULL);
 
   grpc_metadata_array_destroy(&request_metadata_recv);
-  grpc_call_destroy(s);
+  grpc_call_unref(s);
   cq_verifier_destroy(cqv);
 }
 
diff --git a/test/core/bad_client/tests/simple_request.c b/test/core/bad_client/tests/simple_request.c
index 608b849d4154b2a82bc146833acfc0c55a1eb971..fb342f08815f2fa4c185577eb3becc4b2ef87eaf 100644
--- a/test/core/bad_client/tests/simple_request.c
+++ b/test/core/bad_client/tests/simple_request.c
@@ -122,7 +122,7 @@ static void verifier(grpc_server *server, grpc_completion_queue *cq,
 
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
-  grpc_call_destroy(s);
+  grpc_call_unref(s);
   cq_verifier_destroy(cqv);
 }
 
diff --git a/test/core/bad_ssl/bad_ssl_test.c b/test/core/bad_ssl/bad_ssl_test.c
index bd8558570662df8b2f64d7d10f7338bb8f2aada0..ba5b52aa54d0e4d7775d5085bb31b8fd5da824fb 100644
--- a/test/core/bad_ssl/bad_ssl_test.c
+++ b/test/core/bad_ssl/bad_ssl_test.c
@@ -61,7 +61,7 @@ static void run_test(const char *target, size_t nops) {
   grpc_status_code status;
   grpc_call_error error;
   gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
-  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+  grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
   cq_verifier *cqv = cq_verifier_create(cq);
 
   grpc_op ops[6];
@@ -115,7 +115,7 @@ static void run_test(const char *target, size_t nops) {
 
   GPR_ASSERT(status != GRPC_STATUS_OK);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
   grpc_slice_unref(details);
   grpc_metadata_array_destroy(&initial_metadata_recv);
   grpc_metadata_array_destroy(&trailing_metadata_recv);
diff --git a/test/core/bad_ssl/server_common.c b/test/core/bad_ssl/server_common.c
index 6a4313eafd68c3e7e2c23a1667d98417b6bef613..0ec14676c669fc8c96d299463866524605999d9d 100644
--- a/test/core/bad_ssl/server_common.c
+++ b/test/core/bad_ssl/server_common.c
@@ -66,7 +66,9 @@ void bad_ssl_run(grpc_server *server) {
   grpc_call *s = NULL;
   grpc_call_details call_details;
   grpc_metadata_array request_metadata_recv;
-  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+
+  grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
+  grpc_completion_queue *shutdown_cq;
 
   grpc_call_details_init(&call_details);
   grpc_metadata_array_init(&request_metadata_recv);
@@ -82,10 +84,13 @@ void bad_ssl_run(grpc_server *server) {
   while (!shutdown_finished) {
     if (got_sigint && !shutdown_started) {
       gpr_log(GPR_INFO, "Shutting down due to SIGINT");
-      grpc_server_shutdown_and_notify(server, cq, NULL);
-      GPR_ASSERT(grpc_completion_queue_pluck(
-                     cq, NULL, grpc_timeout_seconds_to_deadline(5), NULL)
-                     .type == GRPC_OP_COMPLETE);
+      shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
+      grpc_server_shutdown_and_notify(server, shutdown_cq, NULL);
+      GPR_ASSERT(
+          grpc_completion_queue_pluck(shutdown_cq, NULL,
+                                      grpc_timeout_seconds_to_deadline(5), NULL)
+              .type == GRPC_OP_COMPLETE);
+      grpc_completion_queue_destroy(shutdown_cq);
       grpc_completion_queue_shutdown(cq);
       shutdown_started = 1;
     }
diff --git a/test/core/bad_ssl/servers/cert.c b/test/core/bad_ssl/servers/cert.c
index 9aadf452e2c32beb20971eef39f27af9f0f07cf6..2b014b23431544ebb739190f43782ad6467373ef 100644
--- a/test/core/bad_ssl/servers/cert.c
+++ b/test/core/bad_ssl/servers/cert.c
@@ -56,11 +56,11 @@ int main(int argc, char **argv) {
   grpc_init();
 
   GPR_ASSERT(GRPC_LOG_IF_ERROR(
-      "load_file", grpc_load_file("src/core/lib/tsi/test_creds/badserver.pem",
-                                  1, &cert_slice)));
+      "load_file",
+      grpc_load_file("src/core/tsi/test_creds/badserver.pem", 1, &cert_slice)));
   GPR_ASSERT(GRPC_LOG_IF_ERROR(
-      "load_file", grpc_load_file("src/core/lib/tsi/test_creds/badserver.key",
-                                  1, &key_slice)));
+      "load_file",
+      grpc_load_file("src/core/tsi/test_creds/badserver.key", 1, &key_slice)));
   pem_key_cert_pair.private_key = (const char *)GRPC_SLICE_START_PTR(key_slice);
   pem_key_cert_pair.cert_chain = (const char *)GRPC_SLICE_START_PTR(cert_slice);
 
diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c
index 76bb57346c0ad9eb27cde4493c952a932c23edbd..4be89c78b57acb6e6c0503824d6dfc208a245c05 100644
--- a/test/core/channel/channel_stack_test.c
+++ b/test/core/channel/channel_stack_test.c
@@ -68,12 +68,12 @@ static void channel_destroy_func(grpc_exec_ctx *exec_ctx,
 
 static void call_destroy_func(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
-                              void *ignored) {
+                              grpc_closure *ignored) {
   ++*(int *)(elem->channel_data);
 }
 
 static void call_func(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                      grpc_transport_stream_op *op) {
+                      grpc_transport_stream_op_batch *op) {
   ++*(int *)(elem->call_data);
 }
 
@@ -139,10 +139,16 @@ static void test_create_channel_stack(void) {
   GPR_ASSERT(*channel_data == 0);
 
   call_stack = gpr_malloc(channel_stack->call_stack_size);
-  grpc_error *error =
-      grpc_call_stack_init(&exec_ctx, channel_stack, 1, free_call, call_stack,
-                           NULL, NULL, path, gpr_now(GPR_CLOCK_MONOTONIC),
-                           gpr_inf_future(GPR_CLOCK_MONOTONIC), call_stack);
+  const grpc_call_element_args args = {
+      .call_stack = call_stack,
+      .server_transport_data = NULL,
+      .context = NULL,
+      .path = path,
+      .start_time = gpr_now(GPR_CLOCK_MONOTONIC),
+      .deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC),
+      .arena = NULL};
+  grpc_error *error = grpc_call_stack_init(&exec_ctx, channel_stack, 1,
+                                           free_call, call_stack, &args);
   GPR_ASSERT(error == GRPC_ERROR_NONE);
   GPR_ASSERT(call_stack->count == 1);
   call_elem = grpc_call_stack_element(call_stack, 0);
diff --git a/test/core/channel/minimal_stack_is_minimal_test.c b/test/core/channel/minimal_stack_is_minimal_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..bac94cbd6459a7d775dc5d23d98d54708ac7277f
--- /dev/null
+++ b/test/core/channel/minimal_stack_is_minimal_test.c
@@ -0,0 +1,232 @@
+/*
+ *
+ * Copyright 2017, 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 test verifies that various stack configurations result in the set of
+ * filters that we expect.
+ *
+ * This is akin to a golden-file test, and suffers the same disadvantages and
+ * advantages: it reflects that the code as written has not been modified - and
+ * valid code modifications WILL break this test and it will need updating.
+ *
+ * The intent therefore is to allow code reviewers to more easily catch changes
+ * that perturb the generated list of channel filters in different
+ * configurations and assess whether such a change is correct and desirable.
+ */
+
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/string_util.h>
+#include <string.h>
+
+#include "src/core/lib/channel/channel_stack_builder.h"
+#include "src/core/lib/support/string.h"
+#include "src/core/lib/surface/channel_init.h"
+#include "src/core/lib/surface/channel_stack_type.h"
+#include "src/core/lib/transport/transport_impl.h"
+#include "test/core/util/test_config.h"
+
+// use CHECK_STACK instead
+static int check_stack(const char *file, int line, const char *transport_name,
+                       grpc_channel_args *init_args,
+                       grpc_channel_stack_type channel_stack_type, ...);
+
+// arguments: const char *transport_name   - the name of the transport type to
+//                                           simulate
+//            grpc_channel_args *init_args - channel args to pass down
+//            grpc_channel_stack_type channel_stack_type - the archetype of
+//                                           channel stack to create
+//            variadic arguments - the (in-order) expected list of channel
+//                                 filters to instantiate, terminated with NULL
+#define CHECK_STACK(...) check_stack(__FILE__, __LINE__, __VA_ARGS__)
+
+int main(int argc, char **argv) {
+  grpc_test_init(argc, argv);
+  grpc_init();
+  int errors = 0;
+
+  // tests with a minimal stack
+  grpc_arg minimal_stack_arg = {.type = GRPC_ARG_INTEGER,
+                                .key = GRPC_ARG_MINIMAL_STACK,
+                                .value.integer = 1};
+  grpc_channel_args minimal_stack_args = {.num_args = 1,
+                                          .args = &minimal_stack_arg};
+  errors += CHECK_STACK("unknown", &minimal_stack_args,
+                        GRPC_CLIENT_DIRECT_CHANNEL, "connected", NULL);
+  errors += CHECK_STACK("unknown", &minimal_stack_args, GRPC_CLIENT_SUBCHANNEL,
+                        "connected", NULL);
+  errors += CHECK_STACK("unknown", &minimal_stack_args, GRPC_SERVER_CHANNEL,
+                        "server", "connected", NULL);
+  errors +=
+      CHECK_STACK("chttp2", &minimal_stack_args, GRPC_CLIENT_DIRECT_CHANNEL,
+                  "http-client", "connected", NULL);
+  errors += CHECK_STACK("chttp2", &minimal_stack_args, GRPC_CLIENT_SUBCHANNEL,
+                        "http-client", "connected", NULL);
+  errors += CHECK_STACK("chttp2", &minimal_stack_args, GRPC_SERVER_CHANNEL,
+                        "server", "http-server", "connected", NULL);
+  errors += CHECK_STACK(NULL, &minimal_stack_args, GRPC_CLIENT_CHANNEL,
+                        "client-channel", NULL);
+
+  // tests with a default stack
+  errors += CHECK_STACK("unknown", NULL, GRPC_CLIENT_DIRECT_CHANNEL,
+                        "message_size", "deadline", "connected", NULL);
+  errors += CHECK_STACK("unknown", NULL, GRPC_CLIENT_SUBCHANNEL, "message_size",
+                        "connected", NULL);
+  errors += CHECK_STACK("unknown", NULL, GRPC_SERVER_CHANNEL, "server",
+                        "message_size", "deadline", "connected", NULL);
+  errors +=
+      CHECK_STACK("chttp2", NULL, GRPC_CLIENT_DIRECT_CHANNEL, "message_size",
+                  "deadline", "http-client", "compress", "connected", NULL);
+  errors += CHECK_STACK("chttp2", NULL, GRPC_CLIENT_SUBCHANNEL, "message_size",
+                        "http-client", "compress", "connected", NULL);
+  errors +=
+      CHECK_STACK("chttp2", NULL, GRPC_SERVER_CHANNEL, "server", "message_size",
+                  "deadline", "http-server", "compress", "connected", NULL);
+  errors +=
+      CHECK_STACK(NULL, NULL, GRPC_CLIENT_CHANNEL, "client-channel", NULL);
+
+  GPR_ASSERT(errors == 0);
+  grpc_shutdown();
+  return 0;
+}
+
+/*******************************************************************************
+ * End of tests definitions, start of test infrastructure
+ */
+
+static int check_stack(const char *file, int line, const char *transport_name,
+                       grpc_channel_args *init_args,
+                       grpc_channel_stack_type channel_stack_type, ...) {
+  // create dummy channel stack
+  grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create();
+  grpc_transport_vtable fake_transport_vtable = {.name = transport_name};
+  grpc_transport fake_transport = {.vtable = &fake_transport_vtable};
+  grpc_channel_stack_builder_set_target(builder, "foo.test.google.fr");
+  grpc_channel_args *channel_args = grpc_channel_args_copy(init_args);
+  if (transport_name != NULL) {
+    grpc_channel_stack_builder_set_transport(builder, &fake_transport);
+  }
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_stack_builder_set_channel_arguments(&exec_ctx, builder,
+                                                     channel_args);
+    GPR_ASSERT(
+        grpc_channel_init_create_stack(&exec_ctx, builder, channel_stack_type));
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
+
+  // build up our expectation list
+  gpr_strvec v;
+  gpr_strvec_init(&v);
+  va_list args;
+  va_start(args, channel_stack_type);
+  for (;;) {
+    char *a = va_arg(args, char *);
+    if (a == NULL) break;
+    if (v.count != 0) gpr_strvec_add(&v, gpr_strdup(", "));
+    gpr_strvec_add(&v, gpr_strdup(a));
+  }
+  va_end(args);
+  char *expect = gpr_strvec_flatten(&v, NULL);
+  gpr_strvec_destroy(&v);
+
+  // build up our "got" list
+  gpr_strvec_init(&v);
+  grpc_channel_stack_builder_iterator *it =
+      grpc_channel_stack_builder_create_iterator_at_first(builder);
+  while (grpc_channel_stack_builder_move_next(it)) {
+    const char *name = grpc_channel_stack_builder_iterator_filter_name(it);
+    if (name == NULL) continue;
+    if (v.count != 0) gpr_strvec_add(&v, gpr_strdup(", "));
+    gpr_strvec_add(&v, gpr_strdup(name));
+  }
+  char *got = gpr_strvec_flatten(&v, NULL);
+  gpr_strvec_destroy(&v);
+  grpc_channel_stack_builder_iterator_destroy(it);
+
+  // figure out result, log if there's an error
+  int result = 0;
+  if (0 != strcmp(got, expect)) {
+    gpr_strvec_init(&v);
+    gpr_strvec_add(&v, gpr_strdup("{"));
+    for (size_t i = 0; i < channel_args->num_args; i++) {
+      if (i > 0) gpr_strvec_add(&v, gpr_strdup(", "));
+      gpr_strvec_add(&v, gpr_strdup(channel_args->args[i].key));
+      gpr_strvec_add(&v, gpr_strdup("="));
+      switch (channel_args->args[i].type) {
+        case GRPC_ARG_INTEGER: {
+          char *tmp;
+          gpr_asprintf(&tmp, "%d", channel_args->args[i].value.integer);
+          gpr_strvec_add(&v, tmp);
+          break;
+        }
+        case GRPC_ARG_STRING:
+          gpr_strvec_add(&v, gpr_strdup(channel_args->args[i].value.string));
+          break;
+        case GRPC_ARG_POINTER: {
+          char *tmp;
+          gpr_asprintf(&tmp, "%p", channel_args->args[i].value.pointer.p);
+          gpr_strvec_add(&v, tmp);
+          break;
+        }
+      }
+    }
+    gpr_strvec_add(&v, gpr_strdup("}"));
+    char *args_str = gpr_strvec_flatten(&v, NULL);
+    gpr_strvec_destroy(&v);
+
+    gpr_log(file, line, GPR_LOG_SEVERITY_ERROR,
+            "**************************************************");
+    gpr_log(file, line, GPR_LOG_SEVERITY_ERROR,
+            "FAILED transport=%s; stack_type=%s; channel_args=%s:",
+            transport_name, grpc_channel_stack_type_string(channel_stack_type),
+            args_str);
+    gpr_log(file, line, GPR_LOG_SEVERITY_ERROR, "EXPECTED: %s", expect);
+    gpr_log(file, line, GPR_LOG_SEVERITY_ERROR, "GOT:      %s", got);
+    result = 1;
+
+    gpr_free(args_str);
+  }
+
+  gpr_free(got);
+  gpr_free(expect);
+
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_stack_builder_destroy(&exec_ctx, builder);
+    grpc_channel_args_destroy(&exec_ctx, channel_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
+
+  return result;
+}
diff --git a/test/core/client_channel/BUILD b/test/core/client_channel/BUILD
index a29e9aca4e64e0dc52c64985bb0edd0602568686..55a74c6d01935e93ec21ec0bd80ee8d0b568cf58 100644
--- a/test/core/client_channel/BUILD
+++ b/test/core/client_channel/BUILD
@@ -45,10 +45,3 @@ cc_test(
     deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util", "//test/core/end2end:cq_verifier"],
     copts = ['-std=c99']
 )
-
-cc_test(
-    name = "set_initial_connect_string_test",
-    srcs = ["set_initial_connect_string_test.c"],
-    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
-    copts = ['-std=c99']
-)
diff --git a/test/core/client_channel/lb_policies_test.c b/test/core/client_channel/lb_policies_test.c
index 057b90ec84f57659acdec5d781bd69301b70dce3..4492e6f594bd9abdb0449f5e9027b0763e8bd029 100644
--- a/test/core/client_channel/lb_policies_test.c
+++ b/test/core/client_channel/lb_policies_test.c
@@ -41,8 +41,8 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
 
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/support/string.h"
@@ -59,6 +59,7 @@ typedef struct servers_fixture {
   grpc_server **servers;
   grpc_call **server_calls;
   grpc_completion_queue *cq;
+  grpc_completion_queue *shutdown_cq;
   char **servers_hostports;
   grpc_metadata_array *request_metadata_recv;
 } servers_fixture;
@@ -146,10 +147,10 @@ static void drain_cq(grpc_completion_queue *cq) {
 static void kill_server(const servers_fixture *f, size_t i) {
   gpr_log(GPR_INFO, "KILLING SERVER %" PRIuPTR, i);
   GPR_ASSERT(f->servers[i] != NULL);
-  grpc_server_shutdown_and_notify(f->servers[i], f->cq, tag(10000));
-  GPR_ASSERT(
-      grpc_completion_queue_pluck(f->cq, tag(10000), n_millis_time(5000), NULL)
-          .type == GRPC_OP_COMPLETE);
+  grpc_server_shutdown_and_notify(f->servers[i], f->shutdown_cq, tag(10000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(10000),
+                                         n_millis_time(5000), NULL)
+                 .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->servers[i]);
   f->servers[i] = NULL;
 }
@@ -196,7 +197,8 @@ static servers_fixture *setup_servers(const char *server_host,
   /* Create servers. */
   f->servers = gpr_malloc(sizeof(grpc_server *) * num_servers);
   f->servers_hostports = gpr_malloc(sizeof(char *) * num_servers);
-  f->cq = grpc_completion_queue_create(NULL);
+  f->cq = grpc_completion_queue_create_for_next(NULL);
+  f->shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
   for (i = 0; i < num_servers; i++) {
     grpc_metadata_array_init(&f->request_metadata_recv[i]);
     gpr_join_host_port(&f->servers_hostports[i], server_host,
@@ -212,8 +214,8 @@ static void teardown_servers(servers_fixture *f) {
   /* Destroy server. */
   for (i = 0; i < f->num_servers; i++) {
     if (f->servers[i] == NULL) continue;
-    grpc_server_shutdown_and_notify(f->servers[i], f->cq, tag(10000));
-    GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(10000),
+    grpc_server_shutdown_and_notify(f->servers[i], f->shutdown_cq, tag(10000));
+    GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(10000),
                                            n_millis_time(5000), NULL)
                    .type == GRPC_OP_COMPLETE);
     grpc_server_destroy(f->servers[i]);
@@ -221,6 +223,7 @@ static void teardown_servers(servers_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 
   gpr_free(f->servers);
 
@@ -391,7 +394,7 @@ static request_sequences perform_request(servers_fixture *f,
                                          "foo.test.google.fr"));
       GPR_ASSERT(was_cancelled == 1);
 
-      grpc_call_destroy(f->server_calls[s_idx]);
+      grpc_call_unref(f->server_calls[s_idx]);
 
       /* ask for the next request on this server */
       GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(
@@ -417,7 +420,7 @@ static request_sequences perform_request(servers_fixture *f,
 
     cq_verifier_destroy(cqv);
 
-    grpc_call_destroy(c);
+    grpc_call_unref(c);
 
     for (i = 0; i < f->num_servers; i++) {
       grpc_call_details_destroy(&rdata->call_details[i]);
@@ -613,7 +616,7 @@ static void test_pending_calls(size_t concurrent_calls) {
   /* destroy the calls after the channel so that they are still around for the
    * LB's shutdown func to process */
   for (i = 0; i < concurrent_calls; i++) {
-    grpc_call_destroy(calls[i]);
+    grpc_call_unref(calls[i]);
   }
   gpr_free(calls);
   teardown_servers(f);
diff --git a/test/core/client_channel/parse_address_test.c b/test/core/client_channel/parse_address_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..802e41e5dee86f36d9b3fd6d213270c224f0b5fa
--- /dev/null
+++ b/test/core/client_channel/parse_address_test.c
@@ -0,0 +1,116 @@
+/*
+ *
+ * Copyright 2017, 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/ext/filters/client_channel/parse_address.h"
+#include "src/core/lib/iomgr/sockaddr.h"
+
+#include <string.h>
+#ifdef GRPC_HAVE_UNIX_SOCKET
+#include <sys/un.h>
+#endif
+
+#include <grpc/support/log.h>
+
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/iomgr/socket_utils.h"
+#include "test/core/util/test_config.h"
+
+#ifdef GRPC_HAVE_UNIX_SOCKET
+
+static void test_grpc_parse_unix(const char *uri_text, const char *pathname) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0);
+  grpc_resolved_address addr;
+
+  GPR_ASSERT(1 == grpc_parse_unix(uri, &addr));
+  struct sockaddr_un *addr_un = (struct sockaddr_un *)addr.addr;
+  GPR_ASSERT(AF_UNIX == addr_un->sun_family);
+  GPR_ASSERT(0 == strcmp(addr_un->sun_path, pathname));
+
+  grpc_uri_destroy(uri);
+  grpc_exec_ctx_finish(&exec_ctx);
+}
+
+#else /* GRPC_HAVE_UNIX_SOCKET */
+
+static void test_grpc_parse_unix(const char *uri_text, const char *pathname) {}
+
+#endif /* GRPC_HAVE_UNIX_SOCKET */
+
+static void test_grpc_parse_ipv4(const char *uri_text, const char *host,
+                                 unsigned short port) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0);
+  grpc_resolved_address addr;
+  char ntop_buf[INET_ADDRSTRLEN];
+
+  GPR_ASSERT(1 == grpc_parse_ipv4(uri, &addr));
+  struct sockaddr_in *addr_in = (struct sockaddr_in *)addr.addr;
+  GPR_ASSERT(AF_INET == addr_in->sin_family);
+  GPR_ASSERT(NULL != grpc_inet_ntop(AF_INET, &addr_in->sin_addr, ntop_buf,
+                                    sizeof(ntop_buf)));
+  GPR_ASSERT(0 == strcmp(ntop_buf, host));
+  GPR_ASSERT(ntohs(addr_in->sin_port) == port);
+
+  grpc_uri_destroy(uri);
+  grpc_exec_ctx_finish(&exec_ctx);
+}
+
+static void test_grpc_parse_ipv6(const char *uri_text, const char *host,
+                                 unsigned short port, uint32_t scope_id) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0);
+  grpc_resolved_address addr;
+  char ntop_buf[INET6_ADDRSTRLEN];
+
+  GPR_ASSERT(1 == grpc_parse_ipv6(uri, &addr));
+  struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr.addr;
+  GPR_ASSERT(AF_INET6 == addr_in6->sin6_family);
+  GPR_ASSERT(NULL != grpc_inet_ntop(AF_INET6, &addr_in6->sin6_addr, ntop_buf,
+                                    sizeof(ntop_buf)));
+  GPR_ASSERT(0 == strcmp(ntop_buf, host));
+  GPR_ASSERT(ntohs(addr_in6->sin6_port) == port);
+  GPR_ASSERT(addr_in6->sin6_scope_id == scope_id);
+
+  grpc_uri_destroy(uri);
+  grpc_exec_ctx_finish(&exec_ctx);
+}
+
+int main(int argc, char **argv) {
+  grpc_test_init(argc, argv);
+
+  test_grpc_parse_unix("unix:/path/name", "/path/name");
+  test_grpc_parse_ipv4("ipv4:192.0.2.1:12345", "192.0.2.1", 12345);
+  test_grpc_parse_ipv6("ipv6:[2001:db8::1]:12345", "2001:db8::1", 12345, 0);
+  test_grpc_parse_ipv6("ipv6:[2001:db8::1%252]:12345", "2001:db8::1", 12345, 2);
+}
diff --git a/test/core/client_channel/resolvers/BUILD b/test/core/client_channel/resolvers/BUILD
index af37072e3a4288d1a64c5e8c39ee2139b53d40ff..e8361cdef63d2299dc99f08b74b9cf1842510d05 100644
--- a/test/core/client_channel/resolvers/BUILD
+++ b/test/core/client_channel/resolvers/BUILD
@@ -32,20 +32,48 @@ licenses(["notice"])  # 3-clause BSD
 cc_test(
     name = "dns_resolver_connectivity_test",
     srcs = ["dns_resolver_connectivity_test.c"],
-    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
-    copts = ['-std=c99']
+    copts = ["-std=c99"],
+    deps = [
+        "//:gpr",
+        "//:grpc",
+        "//test/core/util:gpr_test_util",
+        "//test/core/util:grpc_test_util",
+    ],
 )
 
 cc_test(
     name = "dns_resolver_test",
     srcs = ["dns_resolver_test.c"],
-    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
-    copts = ['-std=c99']
+    copts = ["-std=c99"],
+    deps = [
+        "//:gpr",
+        "//:grpc",
+        "//test/core/util:gpr_test_util",
+        "//test/core/util:grpc_test_util",
+    ],
 )
 
 cc_test(
     name = "sockaddr_resolver_test",
     srcs = ["sockaddr_resolver_test.c"],
-    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
-    copts = ['-std=c99']
+    copts = ["-std=c99"],
+    deps = [
+        "//:gpr",
+        "//:grpc",
+        "//test/core/util:gpr_test_util",
+        "//test/core/util:grpc_test_util",
+    ],
+)
+
+cc_test(
+    name = "fake_resolver_test",
+    srcs = ["fake_resolver_test.c"],
+    copts = ["-std=c99"],
+    deps = [
+        "//:gpr",
+        "//:grpc",
+        "//test/core/end2end:fake_resolver",
+        "//test/core/util:gpr_test_util",
+        "//test/core/util:grpc_test_util",
+    ],
 )
diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
index 3e3401165cde87d030d4f58e35b482766bc62212..8e15faa1dd8d0e1ea09a7b7fc714e3ff73e9f5db 100644
--- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
@@ -36,8 +36,8 @@
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 
-#include "src/core/ext/client_channel/resolver.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/resolver.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/combiner.h"
 #include "src/core/lib/iomgr/resolve_address.h"
@@ -48,28 +48,32 @@ static gpr_mu g_mu;
 static bool g_fail_resolution = true;
 static grpc_combiner *g_combiner;
 
-static grpc_error *my_resolve_address(const char *name, const char *addr,
-                                      grpc_resolved_addresses **addrs) {
+static void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr,
+                               const char *default_port,
+                               grpc_pollset_set *interested_parties,
+                               grpc_closure *on_done,
+                               grpc_resolved_addresses **addrs) {
   gpr_mu_lock(&g_mu);
-  GPR_ASSERT(0 == strcmp("test", name));
+  GPR_ASSERT(0 == strcmp("test", addr));
+  grpc_error *error = GRPC_ERROR_NONE;
   if (g_fail_resolution) {
     g_fail_resolution = false;
     gpr_mu_unlock(&g_mu);
-    return GRPC_ERROR_CREATE("Forced Failure");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure");
   } else {
     gpr_mu_unlock(&g_mu);
     *addrs = gpr_malloc(sizeof(**addrs));
     (*addrs)->naddrs = 1;
     (*addrs)->addrs = gpr_malloc(sizeof(*(*addrs)->addrs));
     (*addrs)->addrs[0].len = 123;
-    return GRPC_ERROR_NONE;
   }
+  grpc_closure_sched(exec_ctx, on_done, error);
 }
 
 static grpc_resolver *create_resolver(grpc_exec_ctx *exec_ctx,
                                       const char *name) {
   grpc_resolver_factory *factory = grpc_resolver_factory_lookup("dns");
-  grpc_uri *uri = grpc_uri_parse(name, 0);
+  grpc_uri *uri = grpc_uri_parse(exec_ctx, name, 0);
   GPR_ASSERT(uri);
   grpc_resolver_args args;
   memset(&args, 0, sizeof(args));
@@ -135,7 +139,7 @@ int main(int argc, char **argv) {
   grpc_init();
   gpr_mu_init(&g_mu);
   g_combiner = grpc_combiner_create(NULL);
-  grpc_blocking_resolve_address = my_resolve_address;
+  grpc_resolve_address = my_resolve_address;
   grpc_channel_args *result = (grpc_channel_args *)1;
 
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
diff --git a/test/core/client_channel/resolvers/dns_resolver_test.c b/test/core/client_channel/resolvers/dns_resolver_test.c
index 9dd5aed0919ba2b9b9df6471927872a73cf7ca32..fa7857d41809ffeea2b2e428426e795286a9eb92 100644
--- a/test/core/client_channel/resolvers/dns_resolver_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_test.c
@@ -35,7 +35,7 @@
 
 #include <grpc/support/log.h>
 
-#include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/lib/iomgr/combiner.h"
 #include "test/core/util/test_config.h"
 
@@ -43,7 +43,7 @@ static grpc_combiner *g_combiner;
 
 static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_uri *uri = grpc_uri_parse(string, 0);
+  grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0);
   grpc_resolver_args args;
   grpc_resolver *resolver;
   gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string,
@@ -61,7 +61,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
 
 static void test_fails(grpc_resolver_factory *factory, const char *string) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_uri *uri = grpc_uri_parse(string, 0);
+  grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0);
   grpc_resolver_args args;
   grpc_resolver *resolver;
   gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string,
diff --git a/test/core/client_channel/resolvers/fake_resolver_test.c b/test/core/client_channel/resolvers/fake_resolver_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..861918fbd65c3d8d5f102081ecc73c673c2d1e41
--- /dev/null
+++ b/test/core/client_channel/resolvers/fake_resolver_test.c
@@ -0,0 +1,187 @@
+/*
+ *
+ * Copyright 2017, 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 <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/ext/filters/client_channel/parse_address.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/iomgr/combiner.h"
+#include "src/core/lib/security/credentials/fake/fake_credentials.h"
+
+#include "test/core/end2end/fake_resolver.h"
+#include "test/core/util/test_config.h"
+
+static grpc_resolver *build_fake_resolver(
+    grpc_exec_ctx *exec_ctx, grpc_combiner *combiner,
+    grpc_fake_resolver_response_generator *response_generator) {
+  grpc_resolver_factory *factory = grpc_resolver_factory_lookup("test");
+  grpc_arg generator_arg =
+      grpc_fake_resolver_response_generator_arg(response_generator);
+  grpc_resolver_args args;
+  memset(&args, 0, sizeof(args));
+  grpc_channel_args channel_args = {1, &generator_arg};
+  args.args = &channel_args;
+  args.combiner = combiner;
+  grpc_resolver *resolver =
+      grpc_resolver_factory_create_resolver(exec_ctx, factory, &args);
+  grpc_resolver_factory_unref(factory);
+  return resolver;
+}
+
+typedef struct on_resolution_arg {
+  grpc_channel_args *resolver_result;
+  grpc_channel_args *expected_resolver_result;
+  bool was_called;
+} on_resolution_arg;
+
+void on_resolution_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+  on_resolution_arg *res = arg;
+  res->was_called = true;
+  // We only check the addresses channel arg because that's the only one
+  // explicitly set by the test via
+  // grpc_fake_resolver_response_generator_set_response.
+  const grpc_lb_addresses *actual_lb_addresses =
+      grpc_lb_addresses_find_channel_arg(res->resolver_result);
+  const grpc_lb_addresses *expected_lb_addresses =
+      grpc_lb_addresses_find_channel_arg(res->expected_resolver_result);
+  GPR_ASSERT(
+      grpc_lb_addresses_cmp(actual_lb_addresses, expected_lb_addresses) == 0);
+  grpc_channel_args_destroy(exec_ctx, res->resolver_result);
+  grpc_channel_args_destroy(exec_ctx, res->expected_resolver_result);
+}
+
+static void test_fake_resolver() {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_combiner *combiner = grpc_combiner_create(NULL);
+  // Create resolver.
+  grpc_fake_resolver_response_generator *response_generator =
+      grpc_fake_resolver_response_generator_create();
+  grpc_resolver *resolver =
+      build_fake_resolver(&exec_ctx, combiner, response_generator);
+  GPR_ASSERT(resolver != NULL);
+
+  // Setup expectations.
+  grpc_uri *uris[] = {grpc_uri_parse(&exec_ctx, "ipv4:10.2.1.1:1234", true),
+                      grpc_uri_parse(&exec_ctx, "ipv4:127.0.0.1:4321", true)};
+  char *balancer_names[] = {"name1", "name2"};
+  const bool is_balancer[] = {true, false};
+  grpc_lb_addresses *addresses = grpc_lb_addresses_create(3, NULL);
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(uris); ++i) {
+    grpc_lb_addresses_set_address_from_uri(
+        addresses, i, uris[i], is_balancer[i], balancer_names[i], NULL);
+    grpc_uri_destroy(uris[i]);
+  }
+  const grpc_arg addresses_arg =
+      grpc_lb_addresses_create_channel_arg(addresses);
+  grpc_channel_args *results =
+      grpc_channel_args_copy_and_add(NULL, &addresses_arg, 1);
+  grpc_lb_addresses_destroy(&exec_ctx, addresses);
+  on_resolution_arg on_res_arg;
+  memset(&on_res_arg, 0, sizeof(on_res_arg));
+  on_res_arg.expected_resolver_result = results;
+  grpc_closure *on_resolution = grpc_closure_create(
+      on_resolution_cb, &on_res_arg, grpc_combiner_scheduler(combiner, false));
+
+  // Set resolver results and trigger first resolution. on_resolution_cb
+  // performs the checks.
+  grpc_fake_resolver_response_generator_set_response(
+      &exec_ctx, response_generator, results);
+  grpc_resolver_next_locked(&exec_ctx, resolver, &on_res_arg.resolver_result,
+                            on_resolution);
+  grpc_exec_ctx_flush(&exec_ctx);
+  GPR_ASSERT(on_res_arg.was_called);
+
+  // Setup update.
+  grpc_uri *uris_update[] = {
+      grpc_uri_parse(&exec_ctx, "ipv4:192.168.1.0:31416", true)};
+  char *balancer_names_update[] = {"name3"};
+  const bool is_balancer_update[] = {false};
+  grpc_lb_addresses *addresses_update = grpc_lb_addresses_create(1, NULL);
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(uris_update); ++i) {
+    grpc_lb_addresses_set_address_from_uri(addresses_update, i, uris_update[i],
+                                           is_balancer_update[i],
+                                           balancer_names_update[i], NULL);
+    grpc_uri_destroy(uris_update[i]);
+  }
+
+  grpc_arg addresses_update_arg =
+      grpc_lb_addresses_create_channel_arg(addresses_update);
+  grpc_channel_args *results_update =
+      grpc_channel_args_copy_and_add(NULL, &addresses_update_arg, 1);
+  grpc_lb_addresses_destroy(&exec_ctx, addresses_update);
+
+  // Setup expectations for the update.
+  on_resolution_arg on_res_arg_update;
+  memset(&on_res_arg_update, 0, sizeof(on_res_arg_update));
+  on_res_arg_update.expected_resolver_result = results_update;
+  on_resolution = grpc_closure_create(on_resolution_cb, &on_res_arg_update,
+                                      grpc_combiner_scheduler(combiner, false));
+
+  // Set updated resolver results and trigger a second resolution.
+  grpc_fake_resolver_response_generator_set_response(
+      &exec_ctx, response_generator, results_update);
+  grpc_resolver_next_locked(&exec_ctx, resolver,
+                            &on_res_arg_update.resolver_result, on_resolution);
+  grpc_exec_ctx_flush(&exec_ctx);
+  GPR_ASSERT(on_res_arg.was_called);
+
+  // Requesting a new resolution without re-senting the response shouldn't
+  // trigger the resolution callback.
+  memset(&on_res_arg, 0, sizeof(on_res_arg));
+  grpc_resolver_next_locked(&exec_ctx, resolver, &on_res_arg.resolver_result,
+                            on_resolution);
+  grpc_exec_ctx_flush(&exec_ctx);
+  GPR_ASSERT(!on_res_arg.was_called);
+
+  GRPC_COMBINER_UNREF(&exec_ctx, combiner, "test_fake_resolver");
+  GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_fake_resolver");
+  grpc_exec_ctx_finish(&exec_ctx);
+  grpc_fake_resolver_response_generator_unref(response_generator);
+}
+
+int main(int argc, char **argv) {
+  grpc_test_init(argc, argv);
+  grpc_fake_resolver_init();  // Registers the "test" scheme.
+  grpc_init();
+
+  test_fake_resolver();
+
+  grpc_shutdown();
+  return 0;
+}
diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.c b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
index 68831ab7c79f59145beef1d129954ca32d601368..847eabae3be73333f8956e8552998cc6a14b9639 100644
--- a/test/core/client_channel/resolvers/sockaddr_resolver_test.c
+++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
@@ -37,7 +37,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/combiner.h"
 
@@ -57,7 +57,7 @@ void on_resolution_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
 
 static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_uri *uri = grpc_uri_parse(string, 0);
+  grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0);
   grpc_resolver_args args;
   grpc_resolver *resolver;
   gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string,
@@ -84,7 +84,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
 
 static void test_fails(grpc_resolver_factory *factory, const char *string) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_uri *uri = grpc_uri_parse(string, 0);
+  grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0);
   grpc_resolver_args args;
   grpc_resolver *resolver;
   gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string,
diff --git a/test/core/client_channel/set_initial_connect_string_test.c b/test/core/client_channel/set_initial_connect_string_test.c
deleted file mode 100644
index a0a33667cc879c4651fcd8183aaeae88c9931bb4..0000000000000000000000000000000000000000
--- a/test/core/client_channel/set_initial_connect_string_test.c
+++ /dev/null
@@ -1,268 +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.
- *
- */
-
-/* With the addition of a libuv endpoint, sockaddr.h now includes uv.h when
-   using that endpoint. Because of various transitive includes in uv.h,
-   including windows.h on Windows, uv.h must be included before other system
-   headers. Therefore, sockaddr.h must always be included first */
-#include "src/core/lib/iomgr/sockaddr.h"
-
-#include <string.h>
-
-#include <grpc/grpc.h>
-#include <grpc/slice.h>
-#include <grpc/support/alloc.h>
-#include <grpc/support/host_port.h>
-#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
-
-#include "src/core/ext/client_channel/initial_connect_string.h"
-#include "src/core/lib/iomgr/sockaddr.h"
-#include "src/core/lib/security/credentials/fake/fake_credentials.h"
-#include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
-#include "test/core/util/port.h"
-#include "test/core/util/test_config.h"
-#include "test/core/util/test_tcp_server.h"
-
-struct rpc_state {
-  char *target;
-  grpc_channel_credentials *creds;
-  grpc_completion_queue *cq;
-  grpc_channel *channel;
-  grpc_call *call;
-  grpc_op op;
-  grpc_slice_buffer incoming_buffer;
-  grpc_slice_buffer temp_incoming_buffer;
-  grpc_endpoint *tcp;
-  gpr_atm done_atm;
-};
-
-static const char *magic_connect_string = "magic initial string";
-static int server_port;
-static struct rpc_state state;
-static grpc_closure on_read;
-
-static void handle_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
-  GPR_ASSERT(error == GRPC_ERROR_NONE);
-  grpc_slice_buffer_move_into(&state.temp_incoming_buffer,
-                              &state.incoming_buffer);
-  gpr_log(GPR_DEBUG, "got %" PRIuPTR " bytes, magic is %" PRIuPTR " bytes",
-          state.incoming_buffer.length, strlen(magic_connect_string));
-  if (state.incoming_buffer.length > strlen(magic_connect_string)) {
-    gpr_atm_rel_store(&state.done_atm, 1);
-    grpc_endpoint_shutdown(
-        exec_ctx, state.tcp,
-        GRPC_ERROR_CREATE("Incoming buffer longer than magic_connect_string"));
-    grpc_endpoint_destroy(exec_ctx, state.tcp);
-  } else {
-    grpc_endpoint_read(exec_ctx, state.tcp, &state.temp_incoming_buffer,
-                       &on_read);
-  }
-}
-
-static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
-                       grpc_pollset *accepting_pollset,
-                       grpc_tcp_server_acceptor *acceptor) {
-  gpr_free(acceptor);
-  test_tcp_server *server = arg;
-  grpc_closure_init(&on_read, handle_read, NULL, grpc_schedule_on_exec_ctx);
-  grpc_slice_buffer_init(&state.incoming_buffer);
-  grpc_slice_buffer_init(&state.temp_incoming_buffer);
-  state.tcp = tcp;
-  grpc_endpoint_add_to_pollset(exec_ctx, tcp, server->pollset);
-  grpc_endpoint_read(exec_ctx, tcp, &state.temp_incoming_buffer, &on_read);
-}
-
-static void set_magic_initial_string(grpc_resolved_address **addr,
-                                     grpc_slice *connect_string) {
-  GPR_ASSERT(addr);
-  GPR_ASSERT((*addr)->len);
-  *connect_string = grpc_slice_from_copied_string(magic_connect_string);
-}
-
-static void reset_addr_and_set_magic_string(grpc_resolved_address **addr,
-                                            grpc_slice *connect_string) {
-  struct sockaddr_in target;
-  *connect_string = grpc_slice_from_copied_string(magic_connect_string);
-  gpr_free(*addr);
-  target.sin_family = AF_INET;
-  target.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-  target.sin_port = htons((uint16_t)server_port);
-  *addr = (grpc_resolved_address *)gpr_malloc(sizeof(grpc_resolved_address));
-  (*addr)->len = sizeof(target);
-  memcpy((*addr)->addr, &target, sizeof(target));
-}
-
-static gpr_timespec n_sec_deadline(int seconds) {
-  return gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
-                      gpr_time_from_seconds(seconds, GPR_TIMESPAN));
-}
-
-static void start_rpc(int use_creds, int target_port) {
-  state.cq = grpc_completion_queue_create(NULL);
-  if (use_creds) {
-    state.creds = grpc_fake_transport_security_credentials_create();
-  } else {
-    state.creds = NULL;
-  }
-  gpr_join_host_port(&state.target, "127.0.0.1", target_port);
-  if (use_creds) {
-    state.channel =
-        grpc_secure_channel_create(state.creds, state.target, NULL, NULL);
-  } else {
-    state.channel = grpc_insecure_channel_create(state.target, NULL, NULL);
-  }
-  grpc_slice host = grpc_slice_from_static_string("localhost");
-  state.call = grpc_channel_create_call(
-      state.channel, NULL, GRPC_PROPAGATE_DEFAULTS, state.cq,
-      grpc_slice_from_static_string("/Service/Method"), &host,
-      gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
-  memset(&state.op, 0, sizeof(state.op));
-  state.op.op = GRPC_OP_SEND_INITIAL_METADATA;
-  state.op.data.send_initial_metadata.count = 0;
-  state.op.flags = 0;
-  state.op.reserved = NULL;
-  GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(state.call, &state.op,
-                                                   (size_t)(1), NULL, NULL));
-  grpc_completion_queue_next(state.cq, n_sec_deadline(5), NULL);
-}
-
-static void cleanup_rpc(void) {
-  grpc_event ev;
-  grpc_slice_buffer_destroy(&state.incoming_buffer);
-  grpc_slice_buffer_destroy(&state.temp_incoming_buffer);
-  grpc_channel_credentials_release(state.creds);
-  grpc_call_destroy(state.call);
-  grpc_completion_queue_shutdown(state.cq);
-  do {
-    ev = grpc_completion_queue_next(state.cq, n_sec_deadline(1), NULL);
-  } while (ev.type != GRPC_QUEUE_SHUTDOWN);
-  grpc_completion_queue_destroy(state.cq);
-  grpc_channel_destroy(state.channel);
-  gpr_free(state.target);
-}
-
-typedef struct {
-  test_tcp_server *server;
-  gpr_event *signal_when_done;
-} poll_args;
-
-static void actually_poll_server(void *arg) {
-  poll_args *pa = arg;
-  gpr_timespec deadline = n_sec_deadline(10);
-  while (true) {
-    bool done = gpr_atm_acq_load(&state.done_atm) != 0;
-    gpr_timespec time_left =
-        gpr_time_sub(deadline, gpr_now(GPR_CLOCK_REALTIME));
-    gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64 ".%09" PRId32, done,
-            time_left.tv_sec, time_left.tv_nsec);
-    if (done || gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) < 0) {
-      break;
-    }
-    test_tcp_server_poll(pa->server, 1);
-  }
-  gpr_event_set(pa->signal_when_done, (void *)1);
-  gpr_free(pa);
-}
-
-static void poll_server_until_read_done(test_tcp_server *server,
-                                        gpr_event *signal_when_done) {
-  gpr_atm_rel_store(&state.done_atm, 0);
-  gpr_thd_id id;
-  poll_args *pa = gpr_malloc(sizeof(*pa));
-  pa->server = server;
-  pa->signal_when_done = signal_when_done;
-  gpr_thd_new(&id, actually_poll_server, pa, NULL);
-}
-
-static void match_initial_magic_string(grpc_slice_buffer *buffer) {
-  size_t i, j, cmp_length;
-  size_t magic_length = strlen(magic_connect_string);
-  GPR_ASSERT(buffer->length >= magic_length);
-  for (i = 0, j = 0; i < state.incoming_buffer.count && j < magic_length; i++) {
-    char *dump = grpc_slice_to_c_string(state.incoming_buffer.slices[i]);
-    cmp_length = GPR_MIN(strlen(dump), magic_length - j);
-    GPR_ASSERT(strncmp(dump, magic_connect_string + j, cmp_length) == 0);
-    j += cmp_length;
-    gpr_free(dump);
-  }
-}
-
-static void test_initial_string(test_tcp_server *server, int secure) {
-  gpr_event ev;
-  gpr_event_init(&ev);
-  grpc_test_set_initial_connect_string_function(set_magic_initial_string);
-  poll_server_until_read_done(server, &ev);
-  start_rpc(secure, server_port);
-  gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME));
-  match_initial_magic_string(&state.incoming_buffer);
-  cleanup_rpc();
-}
-
-static void test_initial_string_with_redirect(test_tcp_server *server,
-                                              int secure) {
-  gpr_event ev;
-  gpr_event_init(&ev);
-  int another_port = grpc_pick_unused_port_or_die();
-  grpc_test_set_initial_connect_string_function(
-      reset_addr_and_set_magic_string);
-  poll_server_until_read_done(server, &ev);
-  start_rpc(secure, another_port);
-  gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME));
-  match_initial_magic_string(&state.incoming_buffer);
-  cleanup_rpc();
-}
-
-static void run_test(void (*test)(test_tcp_server *server, int secure),
-                     int secure) {
-  test_tcp_server test_server;
-  server_port = grpc_pick_unused_port_or_die();
-  test_tcp_server_init(&test_server, on_connect, &test_server);
-  test_tcp_server_start(&test_server, server_port);
-  test(&test_server, secure);
-  test_tcp_server_destroy(&test_server);
-}
-
-int main(int argc, char **argv) {
-  grpc_test_init(argc, argv);
-  grpc_init();
-
-  run_test(test_initial_string, 0);
-  run_test(test_initial_string, 1);
-  run_test(test_initial_string_with_redirect, 0);
-  run_test(test_initial_string_with_redirect, 1);
-
-  grpc_shutdown();
-  return 0;
-}
diff --git a/test/core/client_channel/uri_fuzzer_test.c b/test/core/client_channel/uri_fuzzer_test.c
index d2e3fb40eacce5c804c3fb3f2aea9287d7ecc0a8..51da7f9988844b24e2f1bb5231ce4d4f58a99277 100644
--- a/test/core/client_channel/uri_fuzzer_test.c
+++ b/test/core/client_channel/uri_fuzzer_test.c
@@ -37,7 +37,8 @@
 
 #include <grpc/support/alloc.h>
 
-#include "src/core/ext/client_channel/uri_parser.h"
+#include "src/core/ext/filters/client_channel/uri_parser.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
 
 bool squelch = true;
 bool leak_check = true;
@@ -47,10 +48,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   memcpy(s, data, size);
   s[size] = 0;
 
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_uri *x;
-  if ((x = grpc_uri_parse(s, 1))) {
+  if ((x = grpc_uri_parse(&exec_ctx, s, 1))) {
     grpc_uri_destroy(x);
   }
+  grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(s);
   return 0;
 }
diff --git a/test/core/client_channel/uri_parser_test.c b/test/core/client_channel/uri_parser_test.c
index 5f32d3270c1ac6e61aabcb1f016cf908d9a05d36..9fd0dd07f0422ea2bfc57727daea3d7931bb02cf 100644
--- a/test/core/client_channel/uri_parser_test.c
+++ b/test/core/client_channel/uri_parser_test.c
@@ -31,35 +31,41 @@
  *
  */
 
-#include "src/core/ext/client_channel/uri_parser.h"
+#include "src/core/ext/filters/client_channel/uri_parser.h"
 
 #include <string.h>
 
 #include <grpc/support/log.h>
 
+#include "src/core/lib/iomgr/exec_ctx.h"
 #include "test/core/util/test_config.h"
 
 static void test_succeeds(const char *uri_text, const char *scheme,
                           const char *authority, const char *path,
                           const char *query, const char *fragment) {
-  grpc_uri *uri = grpc_uri_parse(uri_text, 0);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0);
   GPR_ASSERT(uri);
   GPR_ASSERT(0 == strcmp(scheme, uri->scheme));
   GPR_ASSERT(0 == strcmp(authority, uri->authority));
   GPR_ASSERT(0 == strcmp(path, uri->path));
   GPR_ASSERT(0 == strcmp(query, uri->query));
   GPR_ASSERT(0 == strcmp(fragment, uri->fragment));
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_uri_destroy(uri);
 }
 
 static void test_fails(const char *uri_text) {
-  GPR_ASSERT(NULL == grpc_uri_parse(uri_text, 0));
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  GPR_ASSERT(NULL == grpc_uri_parse(&exec_ctx, uri_text, 0));
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_query_parts() {
   {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     const char *uri_text = "http://foo/path?a&b=B&c=&#frag";
-    grpc_uri *uri = grpc_uri_parse(uri_text, 0);
+    grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0);
     GPR_ASSERT(uri);
 
     GPR_ASSERT(0 == strcmp("http", uri->scheme));
@@ -86,12 +92,14 @@ static void test_query_parts() {
     GPR_ASSERT(NULL == grpc_uri_get_query_arg(uri, ""));
 
     GPR_ASSERT(0 == strcmp("frag", uri->fragment));
+    grpc_exec_ctx_finish(&exec_ctx);
     grpc_uri_destroy(uri);
   }
   {
     /* test the current behavior of multiple query part values */
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     const char *uri_text = "http://auth/path?foo=bar=baz&foobar==";
-    grpc_uri *uri = grpc_uri_parse(uri_text, 0);
+    grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0);
     GPR_ASSERT(uri);
 
     GPR_ASSERT(0 == strcmp("http", uri->scheme));
@@ -103,12 +111,14 @@ static void test_query_parts() {
     GPR_ASSERT(0 == strcmp("bar", grpc_uri_get_query_arg(uri, "foo")));
     GPR_ASSERT(0 == strcmp("", grpc_uri_get_query_arg(uri, "foobar")));
 
+    grpc_exec_ctx_finish(&exec_ctx);
     grpc_uri_destroy(uri);
   }
   {
     /* empty query */
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     const char *uri_text = "http://foo/path";
-    grpc_uri *uri = grpc_uri_parse(uri_text, 0);
+    grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0);
     GPR_ASSERT(uri);
 
     GPR_ASSERT(0 == strcmp("http", uri->scheme));
@@ -119,6 +129,7 @@ static void test_query_parts() {
     GPR_ASSERT(NULL == uri->query_parts);
     GPR_ASSERT(NULL == uri->query_parts_values);
     GPR_ASSERT(0 == strcmp("", uri->fragment));
+    grpc_exec_ctx_finish(&exec_ctx);
     grpc_uri_destroy(uri);
   }
 }
@@ -142,6 +153,8 @@ int main(int argc, char **argv) {
   test_succeeds("http:?legit#twice", "http", "", "", "legit", "twice");
   test_succeeds("http://foo?bar#lol?", "http", "foo", "", "bar", "lol?");
   test_succeeds("http://foo?bar#lol?/", "http", "foo", "", "bar", "lol?/");
+  test_succeeds("ipv6:[2001:db8::1%252]:12345", "ipv6", "",
+                "[2001:db8::1%2]:12345", "", "");
 
   test_fails("xyz");
   test_fails("http:?dangling-pct-%0");
diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD
index a40fb8e083f9664a63f352c1e325ed03b7dd7d14..ffea1cc4e8ebcfc9f0a71b481b769021e4150b04 100644
--- a/test/core/end2end/BUILD
+++ b/test/core/end2end/BUILD
@@ -32,49 +32,66 @@ licenses(["notice"])  # 3-clause BSD
 load(":generate_tests.bzl", "grpc_end2end_tests")
 
 cc_library(
-  name = 'cq_verifier',
-  srcs = ['cq_verifier.c'],
-  hdrs = ['cq_verifier.h'],
-  deps = ['//:gpr', '//:grpc', '//test/core/util:grpc_test_util'],
-  copts = ['-std=c99'],
-  visibility = ["//test:__subpackages__"],
+    name = "cq_verifier",
+    srcs = ["cq_verifier.c"],
+    hdrs = ["cq_verifier.h"],
+    copts = ["-std=c99"],
+    visibility = ["//test:__subpackages__"],
+    deps = [
+        "//:gpr",
+        "//:grpc",
+        "//test/core/util:grpc_test_util",
+    ],
 )
 
 cc_library(
-  name = 'ssl_test_data',
-  visibility = ["//test:__subpackages__"],
-  hdrs = ['data/ssl_test_data.h'],
-  copts = ['-std=c99'],
-  srcs = [
-    "data/client_certs.c",
-    "data/server1_cert.c",
-    "data/server1_key.c",
-    "data/test_root_cert.c",
-  ]
+    name = "ssl_test_data",
+    srcs = [
+        "data/client_certs.c",
+        "data/server1_cert.c",
+        "data/server1_key.c",
+        "data/test_root_cert.c",
+    ],
+    hdrs = ["data/ssl_test_data.h"],
+    copts = ["-std=c99"],
+    visibility = ["//test:__subpackages__"],
 )
 
 cc_library(
-  name = 'fake_resolver',
-  hdrs = ['fake_resolver.h'],
-  srcs = ['fake_resolver.c'],
-  copts = ['-std=c99'],
-  deps = ['//:gpr', '//:grpc', '//test/core/util:grpc_test_util']
+    name = "fake_resolver",
+    srcs = ["fake_resolver.c"],
+    hdrs = ["fake_resolver.h"],
+    copts = ["-std=c99"],
+    visibility = ["//test:__subpackages__"],
+    deps = [
+        "//:gpr",
+        "//:grpc",
+        "//test/core/util:grpc_test_util",
+    ],
 )
 
 cc_library(
-  name = 'http_proxy',
-  hdrs = ['fixtures/http_proxy.h'],
-  srcs = ['fixtures/http_proxy.c'],
-  copts = ['-std=c99'],
-  deps = ['//:gpr', '//:grpc', '//test/core/util:grpc_test_util']
+    name = "http_proxy",
+    srcs = ["fixtures/http_proxy_fixture.c"],
+    hdrs = ["fixtures/http_proxy_fixture.h"],
+    copts = ["-std=c99"],
+    deps = [
+        "//:gpr",
+        "//:grpc",
+        "//test/core/util:grpc_test_util",
+    ],
 )
 
 cc_library(
-  name = 'proxy',
-  hdrs = ['fixtures/proxy.h'],
-  srcs = ['fixtures/proxy.c'],
-  copts = ['-std=c99'],
-  deps = ['//:gpr', '//:grpc', '//test/core/util:grpc_test_util']
+    name = "proxy",
+    srcs = ["fixtures/proxy.c"],
+    hdrs = ["fixtures/proxy.h"],
+    copts = ["-std=c99"],
+    deps = [
+        "//:gpr",
+        "//:grpc",
+        "//test/core/util:grpc_test_util",
+    ],
 )
 
 grpc_end2end_tests()
diff --git a/test/core/end2end/bad_server_response_test.c b/test/core/end2end/bad_server_response_test.c
index 39a98e84ca9a759dbdfc0cf15fa7156b70dc5d03..fe7e674d17c7a3c66ce588e65a45449dae42cf0b 100644
--- a/test/core/end2end/bad_server_response_test.c
+++ b/test/core/end2end/bad_server_response_test.c
@@ -178,7 +178,7 @@ static void start_rpc(int target_port, grpc_status_code expected_status,
   cq_verifier *cqv;
   grpc_slice details;
 
-  state.cq = grpc_completion_queue_create(NULL);
+  state.cq = grpc_completion_queue_create_for_next(NULL);
   cqv = cq_verifier_create(state.cq);
   gpr_join_host_port(&state.target, "127.0.0.1", target_port);
   state.channel = grpc_insecure_channel_create(state.target, NULL, NULL);
@@ -236,7 +236,7 @@ static void cleanup_rpc(grpc_exec_ctx *exec_ctx) {
   grpc_event ev;
   grpc_slice_buffer_destroy_internal(exec_ctx, &state.temp_incoming_buffer);
   grpc_slice_buffer_destroy_internal(exec_ctx, &state.outgoing_buffer);
-  grpc_call_destroy(state.call);
+  grpc_call_unref(state.call);
   grpc_completion_queue_shutdown(state.cq);
   do {
     ev = grpc_completion_queue_next(state.cq, n_sec_deadline(1), NULL);
@@ -303,7 +303,7 @@ static void run_test(const char *response_payload,
 
   /* clean up */
   grpc_endpoint_shutdown(&exec_ctx, state.tcp,
-                         GRPC_ERROR_CREATE("Test Shutdown"));
+                         GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown"));
   grpc_endpoint_destroy(&exec_ctx, state.tcp);
   cleanup_rpc(&exec_ctx);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/end2end/connection_refused_test.c b/test/core/end2end/connection_refused_test.c
index 16a3005539b8224bbc37d0d74ac2a82dd029b8ad..db7a6c0a8ec1e7a7a0416550f27e7106b45927c4 100644
--- a/test/core/end2end/connection_refused_test.c
+++ b/test/core/end2end/connection_refused_test.c
@@ -53,7 +53,6 @@ static void *tag(intptr_t i) { return (void *)i; }
 static void run_test(bool wait_for_ready, bool use_service_config) {
   grpc_channel *chan;
   grpc_call *call;
-  gpr_timespec deadline = grpc_timeout_seconds_to_deadline(2);
   grpc_completion_queue *cq;
   cq_verifier *cqv;
   grpc_op ops[6];
@@ -69,7 +68,7 @@ static void run_test(bool wait_for_ready, bool use_service_config) {
 
   grpc_metadata_array_init(&trailing_metadata_recv);
 
-  cq = grpc_completion_queue_create(NULL);
+  cq = grpc_completion_queue_create_for_next(NULL);
   cqv = cq_verifier_create(cq);
 
   /* if using service config, create channel args */
@@ -98,6 +97,7 @@ static void run_test(bool wait_for_ready, bool use_service_config) {
   gpr_log(GPR_INFO, "server: %s", addr);
   chan = grpc_insecure_channel_create(addr, args, NULL);
   grpc_slice host = grpc_slice_from_static_string("nonexistant");
+  gpr_timespec deadline = grpc_timeout_seconds_to_deadline(2);
   call = grpc_channel_create_call(
       chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
       grpc_slice_from_static_string("/service/method"), &host, deadline, NULL);
@@ -138,7 +138,7 @@ static void run_test(bool wait_for_ready, bool use_service_config) {
           .type != GRPC_QUEUE_SHUTDOWN)
     ;
   grpc_completion_queue_destroy(cq);
-  grpc_call_destroy(call);
+  grpc_call_unref(call);
   grpc_channel_destroy(chan);
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c
index 9b0106ec84c3daef8bbf62412b8fdcb8ab12de73..5eea5d43fe052111af55d4933596df834a725001 100644
--- a/test/core/end2end/cq_verifier.c
+++ b/test/core/end2end/cq_verifier.c
@@ -189,23 +189,6 @@ int byte_buffer_eq_string(grpc_byte_buffer *bb, const char *str) {
   return res;
 }
 
-static void verify_matches(expectation *e, grpc_event *ev) {
-  GPR_ASSERT(e->type == ev->type);
-  switch (e->type) {
-    case GRPC_QUEUE_SHUTDOWN:
-      gpr_log(GPR_ERROR, "premature queue shutdown");
-      abort();
-      break;
-    case GRPC_OP_COMPLETE:
-      GPR_ASSERT(e->success == ev->success);
-      break;
-    case GRPC_QUEUE_TIMEOUT:
-      gpr_log(GPR_ERROR, "not implemented");
-      abort();
-      break;
-  }
-}
-
 static void expectation_to_strvec(gpr_strvec *buf, expectation *e) {
   char *tmp;
 
@@ -214,7 +197,7 @@ static void expectation_to_strvec(gpr_strvec *buf, expectation *e) {
 
   switch (e->type) {
     case GRPC_OP_COMPLETE:
-      gpr_asprintf(&tmp, "GRPC_OP_COMPLETE result=%d %s:%d", e->success,
+      gpr_asprintf(&tmp, "GRPC_OP_COMPLETE success=%d %s:%d", e->success,
                    e->file, e->line);
       gpr_strvec_add(buf, tmp);
       break;
@@ -248,6 +231,32 @@ static void fail_no_event_received(cq_verifier *v) {
   abort();
 }
 
+static void verify_matches(expectation *e, grpc_event *ev) {
+  GPR_ASSERT(e->type == ev->type);
+  switch (e->type) {
+    case GRPC_OP_COMPLETE:
+      if (e->success != ev->success) {
+        gpr_strvec expected;
+        gpr_strvec_init(&expected);
+        expectation_to_strvec(&expected, e);
+        char *s = gpr_strvec_flatten(&expected, NULL);
+        gpr_strvec_destroy(&expected);
+        gpr_log(GPR_ERROR, "actual success does not match expected: %s", s);
+        gpr_free(s);
+        abort();
+      }
+      break;
+    case GRPC_QUEUE_SHUTDOWN:
+      gpr_log(GPR_ERROR, "premature queue shutdown");
+      abort();
+      break;
+    case GRPC_QUEUE_TIMEOUT:
+      gpr_log(GPR_ERROR, "not implemented");
+      abort();
+      break;
+  }
+}
+
 void cq_verify(cq_verifier *v) {
   const gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10);
   while (v->first_expectation != NULL) {
diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c
index 3623bd7be8b627661422a65ec6b30656f26467b1..caf782869197ee27a1b603704ce2440b652487c3 100644
--- a/test/core/end2end/dualstack_socket_test.c
+++ b/test/core/end2end/dualstack_socket_test.c
@@ -76,6 +76,7 @@ void test_connect(const char *server_host, const char *client_host, int port,
   grpc_channel *client;
   grpc_server *server;
   grpc_completion_queue *cq;
+  grpc_completion_queue *shutdown_cq;
   grpc_call *c;
   grpc_call *s;
   cq_verifier *cqv;
@@ -107,7 +108,7 @@ void test_connect(const char *server_host, const char *client_host, int port,
   grpc_call_details_init(&call_details);
 
   /* Create server. */
-  cq = grpc_completion_queue_create(NULL);
+  cq = grpc_completion_queue_create_for_next(NULL);
   server = grpc_server_create(NULL, NULL);
   grpc_server_register_completion_queue(server, cq, NULL);
   GPR_ASSERT((got_port = grpc_server_add_insecure_http2_port(
@@ -242,7 +243,7 @@ void test_connect(const char *server_host, const char *client_host, int port,
                grpc_slice_str_cmp(call_details.host, "foo.test.google.fr"));
     GPR_ASSERT(was_cancelled == 1);
 
-    grpc_call_destroy(s);
+    grpc_call_unref(s);
   } else {
     /* Check for a failed connection. */
     CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
@@ -251,7 +252,7 @@ void test_connect(const char *server_host, const char *client_host, int port,
     GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
   }
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
 
   cq_verifier_destroy(cqv);
 
@@ -259,11 +260,14 @@ void test_connect(const char *server_host, const char *client_host, int port,
   grpc_channel_destroy(client);
 
   /* Destroy server. */
-  grpc_server_shutdown_and_notify(server, cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
+  grpc_server_shutdown_and_notify(server, shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(server);
+  grpc_completion_queue_destroy(shutdown_cq);
   grpc_completion_queue_shutdown(cq);
   drain_cq(cq);
   grpc_completion_queue_destroy(cq);
diff --git a/test/core/end2end/end2end_nosec_tests.c b/test/core/end2end/end2end_nosec_tests.c
index b351bdee27734f7a5b6d632983e57c2322354f0a..1187e59e6cc73228bdb048b5c348f865bb2b0228 100644
--- a/test/core/end2end/end2end_nosec_tests.c
+++ b/test/core/end2end/end2end_nosec_tests.c
@@ -49,6 +49,8 @@ extern void authority_not_supported(grpc_end2end_test_config config);
 extern void authority_not_supported_pre_init(void);
 extern void bad_hostname(grpc_end2end_test_config config);
 extern void bad_hostname_pre_init(void);
+extern void bad_ping(grpc_end2end_test_config config);
+extern void bad_ping_pre_init(void);
 extern void binary_metadata(grpc_end2end_test_config config);
 extern void binary_metadata_pre_init(void);
 extern void cancel_after_accept(grpc_end2end_test_config config);
@@ -97,6 +99,10 @@ extern void load_reporting_hook(grpc_end2end_test_config config);
 extern void load_reporting_hook_pre_init(void);
 extern void max_concurrent_streams(grpc_end2end_test_config config);
 extern void max_concurrent_streams_pre_init(void);
+extern void max_connection_age(grpc_end2end_test_config config);
+extern void max_connection_age_pre_init(void);
+extern void max_connection_idle(grpc_end2end_test_config config);
+extern void max_connection_idle_pre_init(void);
 extern void max_message_length(grpc_end2end_test_config config);
 extern void max_message_length_pre_init(void);
 extern void negative_deadline(grpc_end2end_test_config config);
@@ -150,6 +156,7 @@ void grpc_end2end_tests_pre_init(void) {
   grpc_summon_debugger_macros();
   authority_not_supported_pre_init();
   bad_hostname_pre_init();
+  bad_ping_pre_init();
   binary_metadata_pre_init();
   cancel_after_accept_pre_init();
   cancel_after_client_done_pre_init();
@@ -174,6 +181,8 @@ void grpc_end2end_tests_pre_init(void) {
   large_metadata_pre_init();
   load_reporting_hook_pre_init();
   max_concurrent_streams_pre_init();
+  max_connection_age_pre_init();
+  max_connection_idle_pre_init();
   max_message_length_pre_init();
   negative_deadline_pre_init();
   network_status_change_pre_init();
@@ -208,6 +217,7 @@ void grpc_end2end_tests(int argc, char **argv,
   if (argc <= 1) {
     authority_not_supported(config);
     bad_hostname(config);
+    bad_ping(config);
     binary_metadata(config);
     cancel_after_accept(config);
     cancel_after_client_done(config);
@@ -232,6 +242,8 @@ void grpc_end2end_tests(int argc, char **argv,
     large_metadata(config);
     load_reporting_hook(config);
     max_concurrent_streams(config);
+    max_connection_age(config);
+    max_connection_idle(config);
     max_message_length(config);
     negative_deadline(config);
     network_status_change(config);
@@ -267,6 +279,10 @@ void grpc_end2end_tests(int argc, char **argv,
       bad_hostname(config);
       continue;
     }
+    if (0 == strcmp("bad_ping", argv[i])) {
+      bad_ping(config);
+      continue;
+    }
     if (0 == strcmp("binary_metadata", argv[i])) {
       binary_metadata(config);
       continue;
@@ -363,6 +379,14 @@ void grpc_end2end_tests(int argc, char **argv,
       max_concurrent_streams(config);
       continue;
     }
+    if (0 == strcmp("max_connection_age", argv[i])) {
+      max_connection_age(config);
+      continue;
+    }
+    if (0 == strcmp("max_connection_idle", argv[i])) {
+      max_connection_idle(config);
+      continue;
+    }
     if (0 == strcmp("max_message_length", argv[i])) {
       max_message_length(config);
       continue;
diff --git a/test/core/end2end/end2end_tests.c b/test/core/end2end/end2end_tests.c
index 199c09ec96ad8cc58ccc2e422ea727b311ba689a..966031af6571a4bc8f87bfb5e7acd1024fc8133f 100644
--- a/test/core/end2end/end2end_tests.c
+++ b/test/core/end2end/end2end_tests.c
@@ -49,6 +49,8 @@ extern void authority_not_supported(grpc_end2end_test_config config);
 extern void authority_not_supported_pre_init(void);
 extern void bad_hostname(grpc_end2end_test_config config);
 extern void bad_hostname_pre_init(void);
+extern void bad_ping(grpc_end2end_test_config config);
+extern void bad_ping_pre_init(void);
 extern void binary_metadata(grpc_end2end_test_config config);
 extern void binary_metadata_pre_init(void);
 extern void call_creds(grpc_end2end_test_config config);
@@ -99,6 +101,10 @@ extern void load_reporting_hook(grpc_end2end_test_config config);
 extern void load_reporting_hook_pre_init(void);
 extern void max_concurrent_streams(grpc_end2end_test_config config);
 extern void max_concurrent_streams_pre_init(void);
+extern void max_connection_age(grpc_end2end_test_config config);
+extern void max_connection_age_pre_init(void);
+extern void max_connection_idle(grpc_end2end_test_config config);
+extern void max_connection_idle_pre_init(void);
 extern void max_message_length(grpc_end2end_test_config config);
 extern void max_message_length_pre_init(void);
 extern void negative_deadline(grpc_end2end_test_config config);
@@ -152,6 +158,7 @@ void grpc_end2end_tests_pre_init(void) {
   grpc_summon_debugger_macros();
   authority_not_supported_pre_init();
   bad_hostname_pre_init();
+  bad_ping_pre_init();
   binary_metadata_pre_init();
   call_creds_pre_init();
   cancel_after_accept_pre_init();
@@ -177,6 +184,8 @@ void grpc_end2end_tests_pre_init(void) {
   large_metadata_pre_init();
   load_reporting_hook_pre_init();
   max_concurrent_streams_pre_init();
+  max_connection_age_pre_init();
+  max_connection_idle_pre_init();
   max_message_length_pre_init();
   negative_deadline_pre_init();
   network_status_change_pre_init();
@@ -211,6 +220,7 @@ void grpc_end2end_tests(int argc, char **argv,
   if (argc <= 1) {
     authority_not_supported(config);
     bad_hostname(config);
+    bad_ping(config);
     binary_metadata(config);
     call_creds(config);
     cancel_after_accept(config);
@@ -236,6 +246,8 @@ void grpc_end2end_tests(int argc, char **argv,
     large_metadata(config);
     load_reporting_hook(config);
     max_concurrent_streams(config);
+    max_connection_age(config);
+    max_connection_idle(config);
     max_message_length(config);
     negative_deadline(config);
     network_status_change(config);
@@ -271,6 +283,10 @@ void grpc_end2end_tests(int argc, char **argv,
       bad_hostname(config);
       continue;
     }
+    if (0 == strcmp("bad_ping", argv[i])) {
+      bad_ping(config);
+      continue;
+    }
     if (0 == strcmp("binary_metadata", argv[i])) {
       binary_metadata(config);
       continue;
@@ -371,6 +387,14 @@ void grpc_end2end_tests(int argc, char **argv,
       max_concurrent_streams(config);
       continue;
     }
+    if (0 == strcmp("max_connection_age", argv[i])) {
+      max_connection_age(config);
+      continue;
+    }
+    if (0 == strcmp("max_connection_idle", argv[i])) {
+      max_connection_idle(config);
+      continue;
+    }
     if (0 == strcmp("max_message_length", argv[i])) {
       max_message_length(config);
       continue;
diff --git a/test/core/end2end/end2end_tests.h b/test/core/end2end/end2end_tests.h
index cb0afd9cd99b8399fb798280642e2b167bd52f2a..4d98bddbd8348f41363204b45d29a85c2761b25a 100644
--- a/test/core/end2end/end2end_tests.h
+++ b/test/core/end2end/end2end_tests.h
@@ -39,25 +39,33 @@
 typedef struct grpc_end2end_test_fixture grpc_end2end_test_fixture;
 typedef struct grpc_end2end_test_config grpc_end2end_test_config;
 
+/* Test feature flags. */
 #define FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION 1
 #define FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION 2
 #define FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS 4
 #define FEATURE_MASK_SUPPORTS_REQUEST_PROXYING 8
 #define FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL 16
 #define FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER 32
+#define FEATURE_MASK_DOES_NOT_SUPPORT_RESOURCE_QUOTA_SERVER 64
+#define FEATURE_MASK_DOES_NOT_SUPPORT_NETWORK_STATUS_CHANGE 128
 
 #define FAIL_AUTH_CHECK_SERVER_ARG_NAME "fail_auth_check"
 
 struct grpc_end2end_test_fixture {
   grpc_completion_queue *cq;
+  grpc_completion_queue *shutdown_cq;
   grpc_server *server;
   grpc_channel *client;
   void *fixture_data;
 };
 
 struct grpc_end2end_test_config {
+  /* A descriptive name for this test fixture. */
   const char *name;
+
+  /* Which features are supported by this fixture. See feature flags above. */
   uint32_t feature_mask;
+
   grpc_end2end_test_fixture (*create_fixture)(grpc_channel_args *client_args,
                                               grpc_channel_args *server_args);
   void (*init_client)(grpc_end2end_test_fixture *f,
diff --git a/test/core/end2end/fake_resolver.c b/test/core/end2end/fake_resolver.c
index 8a37531449e882dd7738f94e43839eec6d41866b..df902a24bffa4bb1273681501e9ef15fc71c646e 100644
--- a/test/core/end2end/fake_resolver.c
+++ b/test/core/end2end/fake_resolver.c
@@ -32,6 +32,7 @@
 // This is similar to the sockaddr resolver, except that it supports a
 // bunch of query args that are useful for dependency injection in tests.
 
+#include <limits.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -42,16 +43,19 @@
 #include <grpc/support/port_platform.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/ext/client_channel/lb_policy_factory.h"
-#include "src/core/ext/client_channel/parse_address.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/ext/filters/client_channel/parse_address.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/iomgr/combiner.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/unix_sockets_posix.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 
+#include "test/core/end2end/fake_resolver.h"
+
 //
 // fake_resolver
 //
@@ -62,12 +66,11 @@ typedef struct {
 
   // passed-in parameters
   grpc_channel_args* channel_args;
-  grpc_lb_addresses* addresses;
 
-  // mutex guarding the rest of the state
-  gpr_mu mu;
-  // have we published?
-  bool published;
+  // If not NULL, the next set of resolution results to be returned to
+  // grpc_resolver_next_locked()'s closure.
+  grpc_channel_args* next_results;
+
   // pending next completion, or NULL
   grpc_closure* next_completion;
   // target result address for next completion
@@ -76,60 +79,137 @@ typedef struct {
 
 static void fake_resolver_destroy(grpc_exec_ctx* exec_ctx, grpc_resolver* gr) {
   fake_resolver* r = (fake_resolver*)gr;
-  gpr_mu_destroy(&r->mu);
+  grpc_channel_args_destroy(exec_ctx, r->next_results);
   grpc_channel_args_destroy(exec_ctx, r->channel_args);
-  grpc_lb_addresses_destroy(exec_ctx, r->addresses);
   gpr_free(r);
 }
 
-static void fake_resolver_shutdown(grpc_exec_ctx* exec_ctx,
-                                   grpc_resolver* resolver) {
+static void fake_resolver_shutdown_locked(grpc_exec_ctx* exec_ctx,
+                                          grpc_resolver* resolver) {
   fake_resolver* r = (fake_resolver*)resolver;
-  gpr_mu_lock(&r->mu);
   if (r->next_completion != NULL) {
     *r->target_result = NULL;
     grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
     r->next_completion = NULL;
   }
-  gpr_mu_unlock(&r->mu);
 }
 
 static void fake_resolver_maybe_finish_next_locked(grpc_exec_ctx* exec_ctx,
                                                    fake_resolver* r) {
-  if (r->next_completion != NULL && !r->published) {
-    r->published = true;
-    grpc_arg arg = grpc_lb_addresses_create_channel_arg(r->addresses);
+  if (r->next_completion != NULL && r->next_results != NULL) {
     *r->target_result =
-        grpc_channel_args_copy_and_add(r->channel_args, &arg, 1);
+        grpc_channel_args_merge(r->channel_args, r->next_results);
+    grpc_channel_args_destroy(exec_ctx, r->next_results);
     grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
     r->next_completion = NULL;
+    r->next_results = NULL;
   }
 }
 
-static void fake_resolver_channel_saw_error(grpc_exec_ctx* exec_ctx,
-                                            grpc_resolver* resolver) {
+static void fake_resolver_channel_saw_error_locked(grpc_exec_ctx* exec_ctx,
+                                                   grpc_resolver* resolver) {
   fake_resolver* r = (fake_resolver*)resolver;
-  gpr_mu_lock(&r->mu);
-  r->published = false;
   fake_resolver_maybe_finish_next_locked(exec_ctx, r);
-  gpr_mu_unlock(&r->mu);
 }
 
-static void fake_resolver_next(grpc_exec_ctx* exec_ctx, grpc_resolver* resolver,
-                               grpc_channel_args** target_result,
-                               grpc_closure* on_complete) {
+static void fake_resolver_next_locked(grpc_exec_ctx* exec_ctx,
+                                      grpc_resolver* resolver,
+                                      grpc_channel_args** target_result,
+                                      grpc_closure* on_complete) {
   fake_resolver* r = (fake_resolver*)resolver;
-  gpr_mu_lock(&r->mu);
   GPR_ASSERT(!r->next_completion);
   r->next_completion = on_complete;
   r->target_result = target_result;
   fake_resolver_maybe_finish_next_locked(exec_ctx, r);
-  gpr_mu_unlock(&r->mu);
 }
 
 static const grpc_resolver_vtable fake_resolver_vtable = {
-    fake_resolver_destroy, fake_resolver_shutdown,
-    fake_resolver_channel_saw_error, fake_resolver_next};
+    fake_resolver_destroy, fake_resolver_shutdown_locked,
+    fake_resolver_channel_saw_error_locked, fake_resolver_next_locked};
+
+struct grpc_fake_resolver_response_generator {
+  fake_resolver* resolver;  // Set by the fake_resolver constructor to itself.
+  grpc_channel_args* next_response;
+  gpr_refcount refcount;
+};
+
+grpc_fake_resolver_response_generator*
+grpc_fake_resolver_response_generator_create() {
+  grpc_fake_resolver_response_generator* generator =
+      gpr_zalloc(sizeof(*generator));
+  gpr_ref_init(&generator->refcount, 1);
+  return generator;
+}
+
+grpc_fake_resolver_response_generator*
+grpc_fake_resolver_response_generator_ref(
+    grpc_fake_resolver_response_generator* generator) {
+  gpr_ref(&generator->refcount);
+  return generator;
+}
+
+void grpc_fake_resolver_response_generator_unref(
+    grpc_fake_resolver_response_generator* generator) {
+  if (gpr_unref(&generator->refcount)) {
+    gpr_free(generator);
+  }
+}
+
+static void set_response_cb(grpc_exec_ctx* exec_ctx, void* arg,
+                            grpc_error* error) {
+  grpc_fake_resolver_response_generator* generator = arg;
+  fake_resolver* r = generator->resolver;
+  if (r->next_results != NULL) {
+    grpc_channel_args_destroy(exec_ctx, r->next_results);
+  }
+  r->next_results = generator->next_response;
+  fake_resolver_maybe_finish_next_locked(exec_ctx, r);
+}
+
+void grpc_fake_resolver_response_generator_set_response(
+    grpc_exec_ctx* exec_ctx, grpc_fake_resolver_response_generator* generator,
+    grpc_channel_args* next_response) {
+  GPR_ASSERT(generator->resolver != NULL);
+  generator->next_response = grpc_channel_args_copy(next_response);
+  grpc_closure_sched(
+      exec_ctx,
+      grpc_closure_create(
+          set_response_cb, generator,
+          grpc_combiner_scheduler(generator->resolver->base.combiner, false)),
+      GRPC_ERROR_NONE);
+}
+
+static void* response_generator_arg_copy(void* p) {
+  return grpc_fake_resolver_response_generator_ref(p);
+}
+
+static void response_generator_arg_destroy(grpc_exec_ctx* exec_ctx, void* p) {
+  grpc_fake_resolver_response_generator_unref(p);
+}
+
+static int response_generator_cmp(void* a, void* b) { return GPR_ICMP(a, b); }
+
+static const grpc_arg_pointer_vtable response_generator_arg_vtable = {
+    response_generator_arg_copy, response_generator_arg_destroy,
+    response_generator_cmp};
+
+grpc_arg grpc_fake_resolver_response_generator_arg(
+    grpc_fake_resolver_response_generator* generator) {
+  grpc_arg arg;
+  arg.type = GRPC_ARG_POINTER;
+  arg.key = GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR;
+  arg.value.pointer.p = generator;
+  arg.value.pointer.vtable = &response_generator_arg_vtable;
+  return arg;
+}
+
+grpc_fake_resolver_response_generator*
+grpc_fake_resolver_get_response_generator(const grpc_channel_args* args) {
+  const grpc_arg* arg =
+      grpc_channel_args_find(args, GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR);
+  if (arg == NULL || arg->type != GRPC_ARG_POINTER) return NULL;
+  return arg->value.pointer.p;
+}
 
 //
 // fake_resolver_factory
@@ -139,81 +219,15 @@ static void fake_resolver_factory_ref(grpc_resolver_factory* factory) {}
 
 static void fake_resolver_factory_unref(grpc_resolver_factory* factory) {}
 
-static void do_nothing(void* ignored) {}
-
 static grpc_resolver* fake_resolver_create(grpc_exec_ctx* exec_ctx,
                                            grpc_resolver_factory* factory,
                                            grpc_resolver_args* args) {
-  if (0 != strcmp(args->uri->authority, "")) {
-    gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme",
-            args->uri->scheme);
-    return NULL;
-  }
-  // Get lb_enabled arg.  Anything other than "0" is interpreted as true.
-  const char* lb_enabled_qpart =
-      grpc_uri_get_query_arg(args->uri, "lb_enabled");
-  const bool lb_enabled =
-      lb_enabled_qpart != NULL && strcmp("0", lb_enabled_qpart) != 0;
-
-  // Get the balancer's names.
-  const char* balancer_names =
-      grpc_uri_get_query_arg(args->uri, "balancer_names");
-  grpc_slice_buffer balancer_names_parts;
-  grpc_slice_buffer_init(&balancer_names_parts);
-  if (balancer_names != NULL) {
-    const grpc_slice balancer_names_slice =
-        grpc_slice_from_copied_string(balancer_names);
-    grpc_slice_split(balancer_names_slice, ",", &balancer_names_parts);
-    grpc_slice_unref(balancer_names_slice);
-  }
-
-  // Construct addresses.
-  grpc_slice path_slice =
-      grpc_slice_new(args->uri->path, strlen(args->uri->path), do_nothing);
-  grpc_slice_buffer path_parts;
-  grpc_slice_buffer_init(&path_parts);
-  grpc_slice_split(path_slice, ",", &path_parts);
-  if (balancer_names_parts.count > 0 &&
-      path_parts.count != balancer_names_parts.count) {
-    gpr_log(GPR_ERROR,
-            "Balancer names present but mismatched with number of addresses: "
-            "%lu balancer names != %lu addresses",
-            (unsigned long)balancer_names_parts.count,
-            (unsigned long)path_parts.count);
-    return NULL;
-  }
-  grpc_lb_addresses* addresses =
-      grpc_lb_addresses_create(path_parts.count, NULL /* user_data_vtable */);
-  bool errors_found = false;
-  for (size_t i = 0; i < addresses->num_addresses; i++) {
-    grpc_uri ith_uri = *args->uri;
-    char* part_str = grpc_slice_to_c_string(path_parts.slices[i]);
-    ith_uri.path = part_str;
-    if (!parse_ipv4(&ith_uri, &addresses->addresses[i].address)) {
-      errors_found = true;
-    }
-    gpr_free(part_str);
-    if (errors_found) break;
-    addresses->addresses[i].is_balancer = lb_enabled;
-    addresses->addresses[i].balancer_name =
-        balancer_names_parts.count > 0
-            ? grpc_dump_slice(balancer_names_parts.slices[i], GPR_DUMP_ASCII)
-            : NULL;
-  }
-  grpc_slice_buffer_destroy_internal(exec_ctx, &path_parts);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &balancer_names_parts);
-  grpc_slice_unref(path_slice);
-  if (errors_found) {
-    grpc_lb_addresses_destroy(exec_ctx, addresses);
-    return NULL;
-  }
-  // Instantiate resolver.
-  fake_resolver* r = gpr_malloc(sizeof(fake_resolver));
-  memset(r, 0, sizeof(*r));
+  fake_resolver* r = gpr_zalloc(sizeof(*r));
   r->channel_args = grpc_channel_args_copy(args->args);
-  r->addresses = addresses;
-  gpr_mu_init(&r->mu);
   grpc_resolver_init(&r->base, &fake_resolver_vtable, args->combiner);
+  grpc_fake_resolver_response_generator* response_generator =
+      grpc_fake_resolver_get_response_generator(args->args);
+  if (response_generator != NULL) response_generator->resolver = r;
   return &r->base;
 }
 
diff --git a/test/core/end2end/fake_resolver.h b/test/core/end2end/fake_resolver.h
index 7a30347f301d1739d2d0461e6c24590977ea39aa..d9668d0d11b88cbfd43d15a2a6da4e24001d4e90 100644
--- a/test/core/end2end/fake_resolver.h
+++ b/test/core/end2end/fake_resolver.h
@@ -32,8 +32,45 @@
 #ifndef GRPC_TEST_CORE_END2END_FAKE_RESOLVER_H
 #define GRPC_TEST_CORE_END2END_FAKE_RESOLVER_H
 
+#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/ext/filters/client_channel/uri_parser.h"
+#include "src/core/lib/channel/channel_args.h"
+
 #include "test/core/util/test_config.h"
 
+#define GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR \
+  "grpc.fake_resolver.response_generator"
+
 void grpc_fake_resolver_init();
 
+// Instances of \a grpc_fake_resolver_response_generator are passed to the
+// fake resolver in a channel argument (see \a
+// grpc_fake_resolver_response_generator_arg) in order to inject and trigger
+// custom resolutions. See also \a
+// grpc_fake_resolver_response_generator_set_response.
+typedef struct grpc_fake_resolver_response_generator
+    grpc_fake_resolver_response_generator;
+grpc_fake_resolver_response_generator*
+grpc_fake_resolver_response_generator_create();
+
+// Instruct the fake resolver associated with the \a response_generator instance
+// to trigger a new resolution for \a uri and \a args.
+void grpc_fake_resolver_response_generator_set_response(
+    grpc_exec_ctx* exec_ctx, grpc_fake_resolver_response_generator* generator,
+    grpc_channel_args* next_response);
+
+// Return a \a grpc_arg for a \a grpc_fake_resolver_response_generator instance.
+grpc_arg grpc_fake_resolver_response_generator_arg(
+    grpc_fake_resolver_response_generator* generator);
+// Return the \a grpc_fake_resolver_response_generator instance in \a args or
+// NULL.
+grpc_fake_resolver_response_generator*
+grpc_fake_resolver_get_response_generator(const grpc_channel_args* args);
+
+grpc_fake_resolver_response_generator*
+grpc_fake_resolver_response_generator_ref(
+    grpc_fake_resolver_response_generator* generator);
+void grpc_fake_resolver_response_generator_unref(
+    grpc_fake_resolver_response_generator* generator);
+
 #endif /* GRPC_TEST_CORE_END2END_FAKE_RESOLVER_H */
diff --git a/test/core/end2end/fixtures/h2_census.c b/test/core/end2end/fixtures/h2_census.c
index 8e60123ed6e5ebb5c67cb3088587e279e410c00d..e8af03a52bd95e0808420326fac9a727fedf1c74 100644
--- a/test/core/end2end/fixtures/h2_census.c
+++ b/test/core/end2end/fixtures/h2_census.c
@@ -41,11 +41,11 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/server.h"
 #include "test/core/util/port.h"
@@ -65,7 +65,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
   gpr_join_host_port(&ffd->localaddr, "localhost", port);
 
   f.fixture_data = ffd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
   return f;
 }
diff --git a/test/core/end2end/fixtures/h2_compress.c b/test/core/end2end/fixtures/h2_compress.c
index c01e45664bb3300945ec0abe75a2a21f6176cd48..49fcd9e9d30cee72eef0aaaf211555f0bf56134d 100644
--- a/test/core/end2end/fixtures/h2_compress.c
+++ b/test/core/end2end/fixtures/h2_compress.c
@@ -41,11 +41,11 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/server.h"
 #include "test/core/util/port.h"
@@ -69,7 +69,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_compression(
 
   memset(&f, 0, sizeof(f));
   f.fixture_data = ffd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
   return f;
 }
diff --git a/test/core/end2end/fixtures/h2_fakesec.c b/test/core/end2end/fixtures/h2_fakesec.c
index c9747913c2f4ea0e65aa18ef150f8034c747339e..5969b110e698345a42f434d37102e6aa7eba2865 100644
--- a/test/core/end2end/fixtures/h2_fakesec.c
+++ b/test/core/end2end/fixtures/h2_fakesec.c
@@ -60,7 +60,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
   gpr_join_host_port(&ffd->localaddr, "localhost", port);
 
   f.fixture_data = ffd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
   return f;
 }
diff --git a/test/core/end2end/fixtures/h2_fd.c b/test/core/end2end/fixtures/h2_fd.c
index 223fadc386dbfc0568370cab0a0fdf0ae7439952..53888dbc5b625e61c7f822560d7b20be7babca35 100644
--- a/test/core/end2end/fixtures/h2_fd.c
+++ b/test/core/end2end/fixtures/h2_fd.c
@@ -70,7 +70,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
   grpc_end2end_test_fixture f;
   memset(&f, 0, sizeof(f));
   f.fixture_data = fixture_data;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
   create_sockets(fixture_data->fd_pair);
 
diff --git a/test/core/end2end/fixtures/h2_full+pipe.c b/test/core/end2end/fixtures/h2_full+pipe.c
index c6013f3040048eac4c2a389d75bc3c08a7c8e3ac..cee48af66f13fe5465ee3448ee9d73a3d8f838b7 100644
--- a/test/core/end2end/fixtures/h2_full+pipe.c
+++ b/test/core/end2end/fixtures/h2_full+pipe.c
@@ -46,10 +46,10 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/iomgr/wakeup_fd_posix.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/server.h"
@@ -70,7 +70,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
   gpr_join_host_port(&ffd->localaddr, "localhost", port);
 
   f.fixture_data = ffd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
   return f;
 }
diff --git a/test/core/end2end/fixtures/h2_full+trace.c b/test/core/end2end/fixtures/h2_full+trace.c
index 01316376e03aeef7e82f39a4d5b794a4ded68380..57047bc57b9e6aa009d54b48f7bd68a6b563a845 100644
--- a/test/core/end2end/fixtures/h2_full+trace.c
+++ b/test/core/end2end/fixtures/h2_full+trace.c
@@ -46,10 +46,10 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/support/env.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/server.h"
@@ -70,7 +70,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
   gpr_join_host_port(&ffd->localaddr, "localhost", port);
 
   f.fixture_data = ffd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
   return f;
 }
diff --git a/test/core/end2end/fixtures/h2_full.c b/test/core/end2end/fixtures/h2_full.c
index 3399f1981e44600105779a5d36cb374dc1d9d068..f18d314c1f68885f8762c5e6d72a39b53934487f 100644
--- a/test/core/end2end/fixtures/h2_full.c
+++ b/test/core/end2end/fixtures/h2_full.c
@@ -41,10 +41,10 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/server.h"
 #include "test/core/util/port.h"
@@ -64,7 +64,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
   gpr_join_host_port(&ffd->localaddr, "localhost", port);
 
   f.fixture_data = ffd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
   return f;
 }
diff --git a/test/core/end2end/fixtures/h2_http_proxy.c b/test/core/end2end/fixtures/h2_http_proxy.c
index 44b223664ab42be3449f09b5d95db566a7db0c0e..aec874b1faf4477050fcfc3f35034a35b2f74acf 100644
--- a/test/core/end2end/fixtures/h2_http_proxy.c
+++ b/test/core/end2end/fixtures/h2_http_proxy.c
@@ -42,14 +42,14 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/support/env.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/server.h"
-#include "test/core/end2end/fixtures/http_proxy.h"
+#include "test/core/end2end/fixtures/http_proxy_fixture.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
@@ -69,7 +69,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
   ffd->proxy = grpc_end2end_http_proxy_create();
 
   f.fixture_data = ffd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
   return f;
 }
diff --git a/test/core/end2end/fixtures/h2_load_reporting.c b/test/core/end2end/fixtures/h2_load_reporting.c
index 38321f34db73e77145992ab5d5e805be031d0dec..8e9c885759e90cce50ed598ec09b941087005fdf 100644
--- a/test/core/end2end/fixtures/h2_load_reporting.c
+++ b/test/core/end2end/fixtures/h2_load_reporting.c
@@ -41,12 +41,12 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/load_reporting/load_reporting.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/http/server/http_server_filter.h"
+#include "src/core/ext/filters/load_reporting/load_reporting.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/server.h"
 #include "test/core/util/port.h"
@@ -67,7 +67,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_load_reporting(
   gpr_join_host_port(&ffd->localaddr, "localhost", port);
 
   f.fixture_data = ffd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
   return f;
 }
diff --git a/test/core/end2end/fixtures/h2_oauth2.c b/test/core/end2end/fixtures/h2_oauth2.c
index 33516528586837f7a79753effb4931a796d8414b..c94f1f6239cb43c3f8ba9f1ee37dd27d7110c309 100644
--- a/test/core/end2end/fixtures/h2_oauth2.c
+++ b/test/core/end2end/fixtures/h2_oauth2.c
@@ -113,7 +113,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
   gpr_join_host_port(&ffd->localaddr, "localhost", port);
 
   f.fixture_data = ffd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
   return f;
 }
diff --git a/test/core/end2end/fixtures/h2_proxy.c b/test/core/end2end/fixtures/h2_proxy.c
index 9e37ed4db34382bb891cd57b31779dcbc6e1225f..3d33d5860d9dc8fa2816bc4c02934ffa3b13d842 100644
--- a/test/core/end2end/fixtures/h2_proxy.c
+++ b/test/core/end2end/fixtures/h2_proxy.c
@@ -41,10 +41,10 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/server.h"
 #include "test/core/end2end/fixtures/proxy.h"
@@ -79,7 +79,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
   ffd->proxy = grpc_end2end_proxy_create(&proxy_def, client_args, server_args);
 
   f.fixture_data = ffd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
   return f;
 }
diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.c b/test/core/end2end/fixtures/h2_sockpair+trace.c
index edf42a407026c5146edb5c3b54b89c7026c3d6af..f3e12200f82920e9f432f5793376d5ee2133bfe9 100644
--- a/test/core/end2end/fixtures/h2_sockpair+trace.c
+++ b/test/core/end2end/fixtures/h2_sockpair+trace.c
@@ -45,12 +45,12 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/http/client/http_client_filter.h"
+#include "src/core/ext/filters/http/message_compress/message_compress_filter.h"
+#include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
-#include "src/core/lib/channel/compress_filter.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/http_client_filter.h"
-#include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/iomgr/endpoint_pair.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/support/env.h"
@@ -94,11 +94,10 @@ static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
   grpc_end2end_test_fixture f;
   memset(&f, 0, sizeof(f));
   f.fixture_data = sfd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
-  grpc_resource_quota *resource_quota = grpc_resource_quota_create("fixture");
-  *sfd = grpc_iomgr_create_endpoint_pair("fixture", resource_quota, 65536);
-  grpc_resource_quota_unref(resource_quota);
+  *sfd = grpc_iomgr_create_endpoint_pair("fixture", NULL);
 
   return f;
 }
diff --git a/test/core/end2end/fixtures/h2_sockpair.c b/test/core/end2end/fixtures/h2_sockpair.c
index 94b2623b3ea00b179b597fcebf3e643bec71327e..4e60d03a9c9c64fd327631e084fc2476c703843a 100644
--- a/test/core/end2end/fixtures/h2_sockpair.c
+++ b/test/core/end2end/fixtures/h2_sockpair.c
@@ -40,12 +40,12 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/http/client/http_client_filter.h"
+#include "src/core/ext/filters/http/message_compress/message_compress_filter.h"
+#include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
-#include "src/core/lib/channel/compress_filter.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/http_client_filter.h"
-#include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/iomgr/endpoint_pair.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/surface/channel.h"
@@ -88,11 +88,10 @@ static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
   grpc_end2end_test_fixture f;
   memset(&f, 0, sizeof(f));
   f.fixture_data = sfd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
-  grpc_resource_quota *resource_quota = grpc_resource_quota_create("fixture");
-  *sfd = grpc_iomgr_create_endpoint_pair("fixture", resource_quota, 65536);
-  grpc_resource_quota_unref(resource_quota);
+  *sfd = grpc_iomgr_create_endpoint_pair("fixture", NULL);
 
   return f;
 }
diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.c b/test/core/end2end/fixtures/h2_sockpair_1byte.c
index 6f9cf8fe26a92e36dee4e22c5db3eea06337c0c7..8714266655ccaf1e6d038e9652988ed0a81550c8 100644
--- a/test/core/end2end/fixtures/h2_sockpair_1byte.c
+++ b/test/core/end2end/fixtures/h2_sockpair_1byte.c
@@ -40,12 +40,12 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/http/client/http_client_filter.h"
+#include "src/core/ext/filters/http/message_compress/message_compress_filter.h"
+#include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
-#include "src/core/lib/channel/compress_filter.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/http_client_filter.h"
-#include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/iomgr/endpoint_pair.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/surface/channel.h"
@@ -88,11 +88,20 @@ static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
   grpc_end2end_test_fixture f;
   memset(&f, 0, sizeof(f));
   f.fixture_data = sfd;
-  f.cq = grpc_completion_queue_create(NULL);
-
-  grpc_resource_quota *resource_quota = grpc_resource_quota_create("fixture");
-  *sfd = grpc_iomgr_create_endpoint_pair("fixture", resource_quota, 1);
-  grpc_resource_quota_unref(resource_quota);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
+
+  grpc_arg a[] = {{.key = GRPC_ARG_TCP_READ_CHUNK_SIZE,
+                   .type = GRPC_ARG_INTEGER,
+                   .value.integer = 1},
+                  {.key = GRPC_ARG_TCP_MIN_READ_CHUNK_SIZE,
+                   .type = GRPC_ARG_INTEGER,
+                   .value.integer = 1},
+                  {.key = GRPC_ARG_TCP_MAX_READ_CHUNK_SIZE,
+                   .type = GRPC_ARG_INTEGER,
+                   .value.integer = 1}};
+  grpc_channel_args args = {.num_args = GPR_ARRAY_SIZE(a), .args = a};
+  *sfd = grpc_iomgr_create_endpoint_pair("fixture", &args);
 
   return f;
 }
diff --git a/test/core/end2end/fixtures/h2_ssl.c b/test/core/end2end/fixtures/h2_ssl.c
index cf44cd093c93633add39c6b77939706ff57be041..c6a1ca09f83f5d887dd92896beade57f7a5a379e 100644
--- a/test/core/end2end/fixtures/h2_ssl.c
+++ b/test/core/end2end/fixtures/h2_ssl.c
@@ -64,7 +64,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
   gpr_join_host_port(&ffd->localaddr, "localhost", port);
 
   f.fixture_data = ffd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
   return f;
 }
diff --git a/test/core/end2end/fixtures/h2_ssl_cert.c b/test/core/end2end/fixtures/h2_ssl_cert.c
index f62331eea3d671f148c29b0838ad8c1b7d79fb00..ba3956e8e3ebf2e881773cfa929c053546c4f904 100644
--- a/test/core/end2end/fixtures/h2_ssl_cert.c
+++ b/test/core/end2end/fixtures/h2_ssl_cert.c
@@ -67,7 +67,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
   gpr_join_host_port(&ffd->localaddr, "localhost", port);
 
   f.fixture_data = ffd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
   return f;
 }
@@ -289,9 +290,10 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -310,6 +312,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void simple_request_body(grpc_end2end_test_fixture f,
@@ -340,7 +343,7 @@ static void simple_request_body(grpc_end2end_test_fixture f,
   CQ_EXPECT_COMPLETION(cqv, tag(1), expected_result == SUCCESS);
   cq_verify(cqv);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
   cq_verifier_destroy(cqv);
 }
 
diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.c b/test/core/end2end/fixtures/h2_ssl_proxy.c
index 740b075bf6d32abe3296f3ed9a7318247d623ffe..9a6c9f558f127b0532087ef4738160c7ef78181f 100644
--- a/test/core/end2end/fixtures/h2_ssl_proxy.c
+++ b/test/core/end2end/fixtures/h2_ssl_proxy.c
@@ -100,7 +100,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
   ffd->proxy = grpc_end2end_proxy_create(&proxy_def, client_args, server_args);
 
   f.fixture_data = ffd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
   return f;
 }
diff --git a/test/core/end2end/fixtures/h2_uds.c b/test/core/end2end/fixtures/h2_uds.c
index bc973ea8e3c9da818d59f8611e4660d6a8244280..de1b8eb5dfda7c18ac521e783a4f076349546f0b 100644
--- a/test/core/end2end/fixtures/h2_uds.c
+++ b/test/core/end2end/fixtures/h2_uds.c
@@ -44,10 +44,10 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/server.h"
@@ -70,7 +70,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
                unique++);
 
   f.fixture_data = ffd;
-  f.cq = grpc_completion_queue_create(NULL);
+  f.cq = grpc_completion_queue_create_for_next(NULL);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
 
   return f;
 }
diff --git a/test/core/end2end/fixtures/http_proxy.c b/test/core/end2end/fixtures/http_proxy_fixture.c
similarity index 92%
rename from test/core/end2end/fixtures/http_proxy.c
rename to test/core/end2end/fixtures/http_proxy_fixture.c
index 9ccb1263ee708aa209373c6b12d2561a9d9f577c..f0d09487c62d215db91fb78748b917e2b0685e06 100644
--- a/test/core/end2end/fixtures/http_proxy.c
+++ b/test/core/end2end/fixtures/http_proxy_fixture.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "test/core/end2end/fixtures/http_proxy.h"
+#include "test/core/end2end/fixtures/http_proxy_fixture.h"
 
 #include "src/core/lib/iomgr/sockaddr.h"
 
@@ -59,6 +59,7 @@
 #include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/iomgr/tcp_client.h"
 #include "src/core/lib/iomgr/tcp_server.h"
+#include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "test/core/util/port.h"
 
@@ -69,7 +70,7 @@ struct grpc_end2end_http_proxy {
   grpc_channel_args* channel_args;
   gpr_mu* mu;
   grpc_pollset* pollset;
-  gpr_atm shutdown;
+  gpr_refcount users;
 };
 
 //
@@ -77,6 +78,8 @@ struct grpc_end2end_http_proxy {
 //
 
 typedef struct proxy_connection {
+  grpc_end2end_http_proxy* proxy;
+
   grpc_endpoint* client_endpoint;
   grpc_endpoint* server_endpoint;
 
@@ -103,13 +106,20 @@ typedef struct proxy_connection {
   grpc_http_request http_request;
 } proxy_connection;
 
+static void proxy_connection_ref(proxy_connection* conn, const char* reason) {
+  gpr_ref(&conn->refcount);
+}
+
 // Helper function to destroy the proxy connection.
 static void proxy_connection_unref(grpc_exec_ctx* exec_ctx,
-                                   proxy_connection* conn) {
+                                   proxy_connection* conn, const char* reason) {
   if (gpr_unref(&conn->refcount)) {
+    gpr_log(GPR_DEBUG, "endpoints: %p %p", conn->client_endpoint,
+            conn->server_endpoint);
     grpc_endpoint_destroy(exec_ctx, conn->client_endpoint);
-    if (conn->server_endpoint != NULL)
+    if (conn->server_endpoint != NULL) {
       grpc_endpoint_destroy(exec_ctx, conn->server_endpoint);
+    }
     grpc_pollset_set_destroy(exec_ctx, conn->pollset_set);
     grpc_slice_buffer_destroy_internal(exec_ctx, &conn->client_read_buffer);
     grpc_slice_buffer_destroy_internal(exec_ctx,
@@ -121,6 +131,7 @@ static void proxy_connection_unref(grpc_exec_ctx* exec_ctx,
     grpc_slice_buffer_destroy_internal(exec_ctx, &conn->server_write_buffer);
     grpc_http_parser_destroy(&conn->http_parser);
     grpc_http_request_destroy(&conn->http_request);
+    gpr_unref(&conn->proxy->users);
     gpr_free(conn);
   }
 }
@@ -139,7 +150,7 @@ static void proxy_connection_failed(grpc_exec_ctx* exec_ctx,
     grpc_endpoint_shutdown(exec_ctx, conn->server_endpoint,
                            GRPC_ERROR_REF(error));
   }
-  proxy_connection_unref(exec_ctx, conn);
+  proxy_connection_unref(exec_ctx, conn, "conn_failed");
 }
 
 // Callback for writing proxy data to the client.
@@ -163,7 +174,7 @@ static void on_client_write_done(grpc_exec_ctx* exec_ctx, void* arg,
                         &conn->on_client_write_done);
   } else {
     // No more writes.  Unref the connection.
-    proxy_connection_unref(exec_ctx, conn);
+    proxy_connection_unref(exec_ctx, conn, "write_done");
   }
 }
 
@@ -188,7 +199,7 @@ static void on_server_write_done(grpc_exec_ctx* exec_ctx, void* arg,
                         &conn->on_server_write_done);
   } else {
     // No more writes.  Unref the connection.
-    proxy_connection_unref(exec_ctx, conn);
+    proxy_connection_unref(exec_ctx, conn, "server_write");
   }
 }
 
@@ -214,7 +225,7 @@ static void on_client_read_done(grpc_exec_ctx* exec_ctx, void* arg,
   } else {
     grpc_slice_buffer_move_into(&conn->client_read_buffer,
                                 &conn->server_write_buffer);
-    gpr_ref(&conn->refcount);
+    proxy_connection_ref(conn, "client_read");
     grpc_endpoint_write(exec_ctx, conn->server_endpoint,
                         &conn->server_write_buffer,
                         &conn->on_server_write_done);
@@ -246,7 +257,7 @@ static void on_server_read_done(grpc_exec_ctx* exec_ctx, void* arg,
   } else {
     grpc_slice_buffer_move_into(&conn->server_read_buffer,
                                 &conn->client_write_buffer);
-    gpr_ref(&conn->refcount);
+    proxy_connection_ref(conn, "server_read");
     grpc_endpoint_write(exec_ctx, conn->client_endpoint,
                         &conn->client_write_buffer,
                         &conn->on_client_write_done);
@@ -270,7 +281,9 @@ static void on_write_response_done(grpc_exec_ctx* exec_ctx, void* arg,
   // Start reading from both client and server.  One of the read
   // requests inherits our ref to conn, but we need to take a new ref
   // for the other one.
-  gpr_ref(&conn->refcount);
+  proxy_connection_ref(conn, "client_read");
+  proxy_connection_ref(conn, "server_read");
+  proxy_connection_unref(exec_ctx, conn, "write_response");
   grpc_endpoint_read(exec_ctx, conn->client_endpoint, &conn->client_read_buffer,
                      &conn->on_client_read_done);
   grpc_endpoint_read(exec_ctx, conn->server_endpoint, &conn->server_read_buffer,
@@ -312,6 +325,8 @@ static void on_server_connect_done(grpc_exec_ctx* exec_ctx, void* arg,
 static void on_read_request_done(grpc_exec_ctx* exec_ctx, void* arg,
                                  grpc_error* error) {
   proxy_connection* conn = arg;
+  gpr_log(GPR_DEBUG, "on_read_request_done: %p %s", conn,
+          grpc_error_string(error));
   if (error != GRPC_ERROR_NONE) {
     proxy_connection_failed(exec_ctx, conn, true /* is_client */,
                             "HTTP proxy read request", error);
@@ -342,7 +357,7 @@ static void on_read_request_done(grpc_exec_ctx* exec_ctx, void* arg,
     char* msg;
     gpr_asprintf(&msg, "HTTP proxy got request method %s",
                  conn->http_request.method);
-    error = GRPC_ERROR_CREATE(msg);
+    error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     proxy_connection_failed(exec_ctx, conn, true /* is_client */,
                             "HTTP proxy read request", error);
@@ -376,12 +391,14 @@ static void on_accept(grpc_exec_ctx* exec_ctx, void* arg,
   gpr_free(acceptor);
   grpc_end2end_http_proxy* proxy = arg;
   // Instantiate proxy_connection.
-  proxy_connection* conn = gpr_malloc(sizeof(*conn));
-  memset(conn, 0, sizeof(*conn));
+  proxy_connection* conn = gpr_zalloc(sizeof(*conn));
+  gpr_ref(&proxy->users);
   conn->client_endpoint = endpoint;
+  conn->proxy = proxy;
   gpr_ref_init(&conn->refcount, 1);
   conn->pollset_set = grpc_pollset_set_create();
   grpc_pollset_set_add_pollset(exec_ctx, conn->pollset_set, proxy->pollset);
+  grpc_endpoint_add_to_pollset_set(exec_ctx, endpoint, conn->pollset_set);
   grpc_closure_init(&conn->on_read_request_done, on_read_request_done, conn,
                     grpc_schedule_on_exec_ctx);
   grpc_closure_init(&conn->on_server_connect_done, on_server_connect_done, conn,
@@ -416,6 +433,7 @@ static void thread_main(void* arg) {
   grpc_end2end_http_proxy* proxy = arg;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   do {
+    gpr_ref(&proxy->users);
     const gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
     const gpr_timespec deadline =
         gpr_time_add(now, gpr_time_from_seconds(1, GPR_TIMESPAN));
@@ -426,7 +444,7 @@ static void thread_main(void* arg) {
         grpc_pollset_work(&exec_ctx, proxy->pollset, &worker, now, deadline));
     gpr_mu_unlock(proxy->mu);
     grpc_exec_ctx_flush(&exec_ctx);
-  } while (!gpr_atm_acq_load(&proxy->shutdown));
+  } while (!gpr_unref(&proxy->users));
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
@@ -434,6 +452,7 @@ grpc_end2end_http_proxy* grpc_end2end_http_proxy_create(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_end2end_http_proxy* proxy = gpr_malloc(sizeof(*proxy));
   memset(proxy, 0, sizeof(*proxy));
+  gpr_ref_init(&proxy->users, 1);
   // Construct proxy address.
   const int proxy_port = grpc_pick_unused_port_or_die();
   gpr_join_host_port(&proxy->proxy_name, "localhost", proxy_port);
@@ -474,17 +493,16 @@ static void destroy_pollset(grpc_exec_ctx* exec_ctx, void* arg,
 }
 
 void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) {
-  gpr_atm_rel_store(&proxy->shutdown, 1);  // Signal proxy thread to shutdown.
+  gpr_unref(&proxy->users);  // Signal proxy thread to shutdown.
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   gpr_thd_join(proxy->thd);
   grpc_tcp_server_shutdown_listeners(&exec_ctx, proxy->server);
   grpc_tcp_server_unref(&exec_ctx, proxy->server);
   gpr_free(proxy->proxy_name);
   grpc_channel_args_destroy(&exec_ctx, proxy->channel_args);
-  grpc_closure destroyed;
-  grpc_closure_init(&destroyed, destroy_pollset, proxy->pollset,
-                    grpc_schedule_on_exec_ctx);
-  grpc_pollset_shutdown(&exec_ctx, proxy->pollset, &destroyed);
+  grpc_pollset_shutdown(&exec_ctx, proxy->pollset,
+                        grpc_closure_create(destroy_pollset, proxy->pollset,
+                                            grpc_schedule_on_exec_ctx));
   gpr_free(proxy);
   grpc_exec_ctx_finish(&exec_ctx);
 }
diff --git a/test/core/end2end/fixtures/http_proxy.h b/test/core/end2end/fixtures/http_proxy_fixture.h
similarity index 100%
rename from test/core/end2end/fixtures/http_proxy.h
rename to test/core/end2end/fixtures/http_proxy_fixture.h
diff --git a/test/core/end2end/fixtures/proxy.c b/test/core/end2end/fixtures/proxy.c
index cee053e8c565f7b342801330bb9d4fce194cf7b3..d660073ce6565bff89d5d54873cedad3ed1e24c6 100644
--- a/test/core/end2end/fixtures/proxy.c
+++ b/test/core/end2end/fixtures/proxy.c
@@ -104,7 +104,7 @@ grpc_end2end_proxy *grpc_end2end_proxy_create(const grpc_end2end_proxy_def *def,
   gpr_log(GPR_DEBUG, "PROXY ADDR:%s BACKEND:%s", proxy->proxy_port,
           proxy->server_port);
 
-  proxy->cq = grpc_completion_queue_create(NULL);
+  proxy->cq = grpc_completion_queue_create_for_next(NULL);
   proxy->server = def->create_server(proxy->proxy_port, server_args);
   proxy->client = def->create_client(proxy->server_port, client_args);
 
@@ -148,8 +148,8 @@ void grpc_end2end_proxy_destroy(grpc_end2end_proxy *proxy) {
 
 static void unrefpc(proxy_call *pc, const char *reason) {
   if (gpr_unref(&pc->refs)) {
-    grpc_call_destroy(pc->c2p);
-    grpc_call_destroy(pc->p2s);
+    grpc_call_unref(pc->c2p);
+    grpc_call_unref(pc->p2s);
     grpc_metadata_array_destroy(&pc->c2p_initial_metadata);
     grpc_metadata_array_destroy(&pc->p2s_initial_metadata);
     grpc_metadata_array_destroy(&pc->p2s_trailing_metadata);
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index 0de8b9459ab7a7de951d9d35da459c76ed66a02d..88a0e301da166c0b1e4bd531dae3150bbc95bdf4 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -390,9 +390,9 @@ static void finish_resolve(grpc_exec_ctx *exec_ctx, void *arg,
     *r->addrs = addrs;
     grpc_closure_sched(exec_ctx, r->on_done, GRPC_ERROR_NONE);
   } else {
-    grpc_closure_sched(
-        exec_ctx, r->on_done,
-        GRPC_ERROR_CREATE_REFERENCING("Resolution failed", &error, 1));
+    grpc_closure_sched(exec_ctx, r->on_done,
+                       GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                           "Resolution failed", &error, 1));
   }
 
   gpr_free(r->addr);
@@ -461,8 +461,8 @@ static void sched_connect(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
                           grpc_endpoint **ep, gpr_timespec deadline) {
   if (gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) < 0) {
     *ep = NULL;
-    grpc_closure_sched(exec_ctx, closure,
-                       GRPC_ERROR_CREATE("Connect deadline exceeded"));
+    grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                              "Connect deadline exceeded"));
     return;
   }
 
@@ -661,7 +661,7 @@ static void read_metadata(input_stream *inp, size_t *count,
 }
 
 static call_state *destroy_call(call_state *call) {
-  grpc_call_destroy(call->call);
+  grpc_call_unref(call->call);
   call->call = NULL;
   return maybe_delete_call_state(call);
 }
@@ -719,10 +719,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   grpc_test_only_set_slice_hash_seed(0);
   if (squelch) gpr_set_log_function(dont_log);
   input_stream inp = {data, data + size};
-  grpc_resolve_address = my_resolve_address;
   grpc_tcp_client_connect_impl = my_tcp_client_connect;
   gpr_now_impl = now_impl;
   grpc_init();
+  grpc_resolve_address = my_resolve_address;
 
   GPR_ASSERT(g_channel == NULL);
   GPR_ASSERT(g_server == NULL);
@@ -735,7 +735,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   g_active_call = new_call(NULL, ROOT);
   g_resource_quota = grpc_resource_quota_create("api_fuzzer");
 
-  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+  grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
 
   while (!is_eof(&inp) || g_channel != NULL || g_server != NULL ||
          pending_channel_watches > 0 || pending_pings > 0 ||
@@ -932,6 +932,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
         }
         uint32_t propagation_mask = read_uint32(&inp);
         grpc_slice method = read_string_like_slice(&inp);
+        if (GRPC_SLICE_LENGTH(method) == 0) {
+          ok = false;
+        }
         grpc_slice host = read_string_like_slice(&inp);
         gpr_timespec deadline =
             gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
@@ -967,7 +970,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
           break;
         }
         grpc_op *ops = gpr_malloc(sizeof(grpc_op) * num_ops);
-        memset(ops, 0, sizeof(grpc_op) * num_ops);
+        if (num_ops > 0) memset(ops, 0, sizeof(grpc_op) * num_ops);
         bool ok = true;
         size_t i;
         grpc_op *op;
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5242554383597568 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5242554383597568
new file mode 100644
index 0000000000000000000000000000000000000000..95a0b013c0d70eb7beef850d3adeb821d35f1a71
Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5242554383597568 differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5867145026076672 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5867145026076672
new file mode 100644
index 0000000000000000000000000000000000000000..3fd5427b46662d86534978f322d512466c8765af
Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5867145026076672 differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5965570207907840 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5965570207907840
new file mode 100644
index 0000000000000000000000000000000000000000..a58dc7b2442fc21b5bbdf2de959c4e2625408e6b
Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5965570207907840 differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6462055064272896 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6462055064272896
new file mode 100644
index 0000000000000000000000000000000000000000..c12128324259b3f178845e2d8672bd6bca483def
Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6462055064272896 differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6499902139924480 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6499902139924480
new file mode 100644
index 0000000000000000000000000000000000000000..139fc1cf3f1effa8c85dc2c025c7ac7912d1b029
Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6499902139924480 differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6520142139752448 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6520142139752448
new file mode 100644
index 0000000000000000000000000000000000000000..49c02c2f12303ba10ea49e020324897a6156cb2f
Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6520142139752448 differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6699208922890240 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6699208922890240
new file mode 100644
index 0000000000000000000000000000000000000000..74f189b87f72ea7e750a0490d2ce3dd2682e7697
Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6699208922890240 differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6723650944237568 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6723650944237568
new file mode 100644
index 0000000000000000000000000000000000000000..e140fdc7050e4cb92899a40a5e98b498b48a0c13
Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6723650944237568 differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-5175380371570688 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-5175380371570688
new file mode 100644
index 0000000000000000000000000000000000000000..9c7aebc63a291d2d6c3213a1a9fcbf2a56e0033d
Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-5175380371570688 differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-59a56fa18034a104fb9f16cd58071b6ff93b8756 b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-59a56fa18034a104fb9f16cd58071b6ff93b8756
new file mode 100644
index 0000000000000000000000000000000000000000..1460bc9fbf7e1b8599f2bceb0de058c9c5a36789
Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-59a56fa18034a104fb9f16cd58071b6ff93b8756 differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/poc-c726ee220e980ed6ad17809fd9efe2844ee61555ac08e4f88afd8901cc2dd53a b/test/core/end2end/fuzzers/api_fuzzer_corpus/poc-c726ee220e980ed6ad17809fd9efe2844ee61555ac08e4f88afd8901cc2dd53a
new file mode 100644
index 0000000000000000000000000000000000000000..01428693cf218bfa2fdffe03e7cf0ee1217d5ca3
Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/poc-c726ee220e980ed6ad17809fd9efe2844ee61555ac08e4f88afd8901cc2dd53a differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer.c b/test/core/end2end/fuzzers/client_fuzzer.c
index e7e7dbefd031dd5bd54a6fea30ba41dbc26d80af..6f49baffd2c4445c898250a5235e59401256c784 100644
--- a/test/core/end2end/fuzzers/client_fuzzer.c
+++ b/test/core/end2end/fuzzers/client_fuzzer.c
@@ -65,7 +65,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
       grpc_mock_endpoint_create(discard_write, resource_quota);
   grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
 
-  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+  grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
   grpc_transport *transport =
       grpc_create_chttp2_transport(&exec_ctx, NULL, mock_endpoint, 1);
   grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL);
@@ -151,7 +151,7 @@ done:
     ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
     GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN);
   }
-  grpc_call_destroy(call);
+  grpc_call_unref(call);
   grpc_completion_queue_destroy(cq);
   grpc_metadata_array_destroy(&initial_metadata_recv);
   grpc_metadata_array_destroy(&trailing_metadata_recv);
diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary
index 6b9678541915f379eb3f5d468ee256c49bf7e821..2bb9de34c563a9350682640f7786d10f09bed6ca 100644
--- a/test/core/end2end/fuzzers/hpack.dictionary
+++ b/test/core/end2end/fuzzers/hpack.dictionary
@@ -10,14 +10,15 @@
 "\x10grpc-payload-bin"
 "\x0Dgrpc-encoding"
 "\x14grpc-accept-encoding"
+"\x15grpc-server-stats-bin"
+"\x0Dgrpc-tags-bin"
+"\x0Egrpc-trace-bin"
 "\x0Ccontent-type"
 "\x1Egrpc-internal-encoding-request"
 "\x0Auser-agent"
 "\x04host"
 "\x08lb-token"
 "\x0Cgrpc-timeout"
-"\x10grpc-tracing-bin"
-"\x0Egrpc-stats-bin"
 "\x00"
 "\x13grpc.wait_for_ready"
 "\x0Cgrpc.timeout"
@@ -76,6 +77,7 @@
 "\x08if-range"
 "\x13if-unmodified-since"
 "\x0Dlast-modified"
+"\x0Blb-cost-bin"
 "\x04link"
 "\x08location"
 "\x0Cmax-forwards"
@@ -152,6 +154,7 @@
 "\x00\x13if-unmodified-since\x00"
 "\x00\x0Dlast-modified\x00"
 "\x00\x08lb-token\x00"
+"\x00\x0Blb-cost-bin\x00"
 "\x00\x04link\x00"
 "\x00\x08location\x00"
 "\x00\x0Cmax-forwards\x00"
diff --git a/test/core/end2end/fuzzers/server_fuzzer.c b/test/core/end2end/fuzzers/server_fuzzer.c
index 186542d4b2d97367fe1a5b06ddaf0163000bd520..6d65fe1847b0435428c10f3721375c5d0ba80cfd 100644
--- a/test/core/end2end/fuzzers/server_fuzzer.c
+++ b/test/core/end2end/fuzzers/server_fuzzer.c
@@ -67,7 +67,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
       grpc_slice_from_copied_buffer((const char *)data, size));
 
   grpc_server *server = grpc_server_create(NULL, NULL);
-  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+  grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
   grpc_server_register_completion_queue(server, cq, NULL);
   // TODO(ctiller): add registered methods (one for POST, one for PUT)
   // void *registered_method =
@@ -109,7 +109,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   }
 
 done:
-  if (call1 != NULL) grpc_call_destroy(call1);
+  if (call1 != NULL) grpc_call_unref(call1);
   grpc_call_details_destroy(&call_details1);
   grpc_metadata_array_destroy(&request_metadata1);
   grpc_server_shutdown_and_notify(server, cq, tag(0xdead));
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/clusterfuzz-testcase-5417405008314368 b/test/core/end2end/fuzzers/server_fuzzer_corpus/clusterfuzz-testcase-5417405008314368
new file mode 100644
index 0000000000000000000000000000000000000000..f896b66adf57b3ffc4f815118c50df71a4dba2b6
Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/clusterfuzz-testcase-5417405008314368 differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/clusterfuzz-testcase-5595941564317696 b/test/core/end2end/fuzzers/server_fuzzer_corpus/clusterfuzz-testcase-5595941564317696
new file mode 100644
index 0000000000000000000000000000000000000000..335ce87196fbdab771bab219b3d0e42d497ca59a
Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/clusterfuzz-testcase-5595941564317696 differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/clusterfuzz-testcase-6312731374256128 b/test/core/end2end/fuzzers/server_fuzzer_corpus/clusterfuzz-testcase-6312731374256128
new file mode 100644
index 0000000000000000000000000000000000000000..4c6eb601ae342400eaccb7d4688136d152f2b06d
Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/clusterfuzz-testcase-6312731374256128 differ
diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py
index 0c749537e60e6c9b6064065a712919749504f056..48e57205395f236ad04066fdfea1ffe4374170d2 100755
--- a/test/core/end2end/gen_build_yaml.py
+++ b/test/core/end2end/gen_build_yaml.py
@@ -39,9 +39,9 @@ import hashlib
 
 FixtureOptions = collections.namedtuple(
     'FixtureOptions',
-    'fullstack includes_proxy dns_resolver secure platforms ci_mac tracing exclude_configs exclude_iomgrs large_writes')
+    'fullstack includes_proxy dns_resolver secure platforms ci_mac tracing exclude_configs exclude_iomgrs large_writes enables_compression')
 default_unsecure_fixture_options = FixtureOptions(
-    True, False, True, False, ['windows', 'linux', 'mac', 'posix'], True, False, [], [], True)
+    True, False, True, False, ['windows', 'linux', 'mac', 'posix'], True, False, [], [], True, False)
 socketpair_unsecure_fixture_options = default_unsecure_fixture_options._replace(fullstack=False, dns_resolver=False)
 default_secure_fixture_options = default_unsecure_fixture_options._replace(secure=True)
 uds_fixture_options = default_unsecure_fixture_options._replace(dns_resolver=False, platforms=['linux', 'mac', 'posix'], exclude_iomgrs=['uv'])
@@ -51,8 +51,7 @@ fd_unsecure_fixture_options = default_unsecure_fixture_options._replace(
 
 # maps fixture name to whether it requires the security library
 END2END_FIXTURES = {
-    'h2_compress': default_unsecure_fixture_options,
-
+    'h2_compress': default_unsecure_fixture_options._replace(enables_compression=True),
     'h2_census': default_unsecure_fixture_options,
     'h2_load_reporting': default_unsecure_fixture_options,
     'h2_fakesec': default_secure_fixture_options._replace(ci_mac=False),
@@ -83,8 +82,8 @@ END2END_FIXTURES = {
 
 TestOptions = collections.namedtuple(
     'TestOptions',
-    'needs_fullstack needs_dns proxyable secure traceable cpu_cost exclude_iomgrs large_writes flaky')
-default_test_options = TestOptions(False, False, True, False, True, 1.0, [], False, False)
+    'needs_fullstack needs_dns proxyable secure traceable cpu_cost exclude_iomgrs large_writes flaky allow_compression')
+default_test_options = TestOptions(False, False, True, False, True, 1.0, [], False, False, True)
 connectivity_test_options = default_test_options._replace(needs_fullstack=True)
 
 LOWCPU = 0.1
@@ -93,12 +92,14 @@ LOWCPU = 0.1
 END2END_TESTS = {
     'authority_not_supported': default_test_options,
     'bad_hostname': default_test_options,
-    'binary_metadata': default_test_options,
+    'bad_ping': connectivity_test_options._replace(proxyable=False),
+    'binary_metadata': default_test_options._replace(cpu_cost=LOWCPU),
     'resource_quota_server': default_test_options._replace(large_writes=True,
-                                                           proxyable=False),
+                                                           proxyable=False,
+                                                           allow_compression=False),
     'call_creds': default_test_options._replace(secure=True),
     'cancel_after_accept': default_test_options._replace(cpu_cost=LOWCPU),
-    'cancel_after_client_done': default_test_options,
+    'cancel_after_client_done': default_test_options._replace(cpu_cost=LOWCPU),
     'cancel_after_invoke': default_test_options._replace(cpu_cost=LOWCPU),
     'cancel_before_invoke': default_test_options._replace(cpu_cost=LOWCPU),
     'cancel_in_a_vacuum': default_test_options._replace(cpu_cost=LOWCPU),
@@ -109,43 +110,49 @@ END2END_TESTS = {
     'default_host': default_test_options._replace(needs_fullstack=True,
                                                   needs_dns=True),
     'disappearing_server': connectivity_test_options._replace(flaky=True),
-    'empty_batch': default_test_options,
-    'filter_causes_close': default_test_options,
+    'empty_batch': default_test_options._replace(cpu_cost=LOWCPU),
+    'filter_causes_close': default_test_options._replace(cpu_cost=LOWCPU),
     'filter_call_init_fails': default_test_options,
-    'filter_latency': default_test_options,
+    'filter_latency': default_test_options._replace(cpu_cost=LOWCPU),
     'graceful_server_shutdown': default_test_options._replace(cpu_cost=LOWCPU),
     'hpack_size': default_test_options._replace(proxyable=False,
-                                                traceable=False),
-    'high_initial_seqno': default_test_options,
+                                                traceable=False,
+                                                cpu_cost=LOWCPU),
+    'high_initial_seqno': default_test_options._replace(cpu_cost=LOWCPU),
     'idempotent_request': default_test_options,
     'invoke_large_request': default_test_options,
-    'keepalive_timeout': default_test_options._replace(proxyable=False),
+    'keepalive_timeout': default_test_options._replace(proxyable=False,
+                                                       cpu_cost=LOWCPU),
     'large_metadata': default_test_options,
-    'max_concurrent_streams': default_test_options._replace(proxyable=False),
-    'max_message_length': default_test_options,
+    'max_concurrent_streams': default_test_options._replace(
+        proxyable=False, cpu_cost=LOWCPU),
+    'max_connection_age': default_test_options._replace(cpu_cost=LOWCPU),
+    'max_connection_idle': connectivity_test_options._replace(
+        proxyable=False, exclude_iomgrs=['uv'], cpu_cost=LOWCPU),
+    'max_message_length': default_test_options._replace(cpu_cost=LOWCPU),
     'negative_deadline': default_test_options,
-    'network_status_change': default_test_options,
+    'network_status_change': default_test_options._replace(cpu_cost=LOWCPU),
     'no_logging': default_test_options._replace(traceable=False),
     'no_op': default_test_options,
     'payload': default_test_options,
     'load_reporting_hook': default_test_options,
-    'ping_pong_streaming': default_test_options,
-    'ping': connectivity_test_options._replace(proxyable=False),
+    'ping_pong_streaming': default_test_options._replace(cpu_cost=LOWCPU),
+    'ping': connectivity_test_options._replace(proxyable=False, cpu_cost=LOWCPU),
     'registered_call': default_test_options,
     'request_with_flags': default_test_options._replace(
         proxyable=False, cpu_cost=LOWCPU),
-    'request_with_payload': default_test_options,
-    'server_finishes_request': default_test_options,
-    'shutdown_finishes_calls': default_test_options,
-    'shutdown_finishes_tags': default_test_options,
-    'simple_cacheable_request': default_test_options,
+    'request_with_payload': default_test_options._replace(cpu_cost=LOWCPU),
+    'server_finishes_request': default_test_options._replace(cpu_cost=LOWCPU),
+    'shutdown_finishes_calls': default_test_options._replace(cpu_cost=LOWCPU),
+    'shutdown_finishes_tags': default_test_options._replace(cpu_cost=LOWCPU),
+    'simple_cacheable_request': default_test_options._replace(cpu_cost=LOWCPU),
     'simple_delayed_request': connectivity_test_options,
     'simple_metadata': default_test_options,
     'simple_request': default_test_options,
-    'streaming_error_response': default_test_options,
+    'streaming_error_response': default_test_options._replace(cpu_cost=LOWCPU),
     'trailing_metadata': default_test_options,
-    'write_buffering': default_test_options,
-    'write_buffering_at_end': default_test_options,
+    'write_buffering': default_test_options._replace(cpu_cost=LOWCPU),
+    'write_buffering_at_end': default_test_options._replace(cpu_cost=LOWCPU),
 }
 
 
@@ -165,6 +172,9 @@ def compatible(f, t):
   if END2END_TESTS[t].large_writes:
     if not END2END_FIXTURES[f].large_writes:
       return False
+  if not END2END_TESTS[t].allow_compression:
+    if END2END_FIXTURES[f].enables_compression:
+      return False
   return True
 
 
diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl
index 431c6995ba0a390ae5df57b0ff565d61ffa3bb2c..dc0925dc9c03bfffa7d6ea0904127e0bfd04f8df 100755
--- a/test/core/end2end/generate_tests.bzl
+++ b/test/core/end2end/generate_tests.bzl
@@ -85,6 +85,7 @@ def test_options(needs_fullstack=False, needs_dns=False, proxyable=True,
 # maps test names to options
 END2END_TESTS = {
     'bad_hostname': test_options(),
+    'bad_ping': test_options(),
     'binary_metadata': test_options(),
     'resource_quota_server': test_options(proxyable=False),
     'call_creds': test_options(secure=True),
@@ -109,6 +110,8 @@ END2END_TESTS = {
     'keepalive_timeout': test_options(proxyable=False),
     'large_metadata': test_options(),
     'max_concurrent_streams': test_options(proxyable=False),
+    'max_connection_age': test_options(),
+    'max_connection_idle': test_options(needs_fullstack=True, proxyable=False),
     'max_message_length': test_options(),
     'negative_deadline': test_options(),
     'network_status_change': test_options(),
diff --git a/test/core/end2end/goaway_server_test.c b/test/core/end2end/goaway_server_test.c
index a9634bfbaecf42ab1beeb62223a054e65af8689d..ababdb70a8016cfb955ec94b15ac515d91e55c96 100644
--- a/test/core/end2end/goaway_server_test.c
+++ b/test/core/end2end/goaway_server_test.c
@@ -52,9 +52,11 @@ static void *tag(intptr_t i) { return (void *)i; }
 
 static gpr_mu g_mu;
 static int g_resolve_port = -1;
-static grpc_error *(*iomgr_resolve_address)(const char *name,
-                                            const char *default_port,
-                                            grpc_resolved_addresses **addrs);
+static void (*iomgr_resolve_address)(grpc_exec_ctx *exec_ctx, const char *addr,
+                                     const char *default_port,
+                                     grpc_pollset_set *interested_parties,
+                                     grpc_closure *on_done,
+                                     grpc_resolved_addresses **addresses);
 
 static void set_resolve_port(int port) {
   gpr_mu_lock(&g_mu);
@@ -62,16 +64,22 @@ static void set_resolve_port(int port) {
   gpr_mu_unlock(&g_mu);
 }
 
-static grpc_error *my_resolve_address(const char *name, const char *addr,
-                                      grpc_resolved_addresses **addrs) {
-  if (0 != strcmp(name, "test")) {
-    return iomgr_resolve_address(name, addr, addrs);
+static void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr,
+                               const char *default_port,
+                               grpc_pollset_set *interested_parties,
+                               grpc_closure *on_done,
+                               grpc_resolved_addresses **addrs) {
+  if (0 != strcmp(addr, "test")) {
+    iomgr_resolve_address(exec_ctx, addr, default_port, interested_parties,
+                          on_done, addrs);
+    return;
   }
 
+  grpc_error *error = GRPC_ERROR_NONE;
   gpr_mu_lock(&g_mu);
   if (g_resolve_port < 0) {
     gpr_mu_unlock(&g_mu);
-    return GRPC_ERROR_CREATE("Forced Failure");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure");
   } else {
     *addrs = gpr_malloc(sizeof(**addrs));
     (*addrs)->naddrs = 1;
@@ -83,8 +91,8 @@ static grpc_error *my_resolve_address(const char *name, const char *addr,
     sa->sin_port = htons((uint16_t)g_resolve_port);
     (*addrs)->addrs[0].len = sizeof(*sa);
     gpr_mu_unlock(&g_mu);
-    return GRPC_ERROR_NONE;
   }
+  grpc_closure_sched(exec_ctx, on_done, error);
 }
 
 int main(int argc, char **argv) {
@@ -96,9 +104,9 @@ int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
 
   gpr_mu_init(&g_mu);
-  iomgr_resolve_address = grpc_blocking_resolve_address;
-  grpc_blocking_resolve_address = my_resolve_address;
   grpc_init();
+  iomgr_resolve_address = grpc_resolve_address;
+  grpc_resolve_address = my_resolve_address;
 
   int was_cancelled1;
   int was_cancelled2;
@@ -121,7 +129,7 @@ int main(int argc, char **argv) {
   grpc_metadata_array_init(&request_metadata2);
   grpc_call_details_init(&request_details2);
 
-  cq = grpc_completion_queue_create(NULL);
+  cq = grpc_completion_queue_create_for_next(NULL);
   cqv = cq_verifier_create(cq);
 
   /* reserve two ports */
@@ -294,10 +302,10 @@ int main(int argc, char **argv) {
   CQ_EXPECT_COMPLETION(cqv, tag(0xdead2), 1);
   cq_verify(cqv);
 
-  grpc_call_destroy(call1);
-  grpc_call_destroy(call2);
-  grpc_call_destroy(server_call1);
-  grpc_call_destroy(server_call2);
+  grpc_call_unref(call1);
+  grpc_call_unref(call2);
+  grpc_call_unref(server_call1);
+  grpc_call_unref(server_call2);
   grpc_server_destroy(server1);
   grpc_server_destroy(server2);
   grpc_channel_destroy(chan);
diff --git a/test/core/end2end/invalid_call_argument_test.c b/test/core/end2end/invalid_call_argument_test.c
index 2a9072570d39468eb7fedaa8cb471a63809e2466..e9a31f278c75800522a0d291dd54a495fb55388d 100644
--- a/test/core/end2end/invalid_call_argument_test.c
+++ b/test/core/end2end/invalid_call_argument_test.c
@@ -31,6 +31,8 @@
  *
  */
 
+#include <grpc/impl/codegen/port_platform.h>
+
 #include <limits.h>
 #include <string.h>
 
@@ -73,7 +75,7 @@ static void prepare_test(int is_client) {
   grpc_metadata_array_init(&g_state.initial_metadata_recv);
   grpc_metadata_array_init(&g_state.trailing_metadata_recv);
   g_state.deadline = grpc_timeout_seconds_to_deadline(2);
-  g_state.cq = grpc_completion_queue_create(NULL);
+  g_state.cq = grpc_completion_queue_create_for_next(NULL);
   g_state.cqv = cq_verifier_create(g_state.cq);
   g_state.details = grpc_empty_slice();
   memset(g_state.ops, 0, sizeof(g_state.ops));
@@ -123,7 +125,8 @@ static void prepare_test(int is_client) {
 }
 
 static void cleanup_test() {
-  grpc_call_destroy(g_state.call);
+  grpc_completion_queue *shutdown_cq;
+  grpc_call_unref(g_state.call);
   cq_verifier_destroy(g_state.cqv);
   grpc_channel_destroy(g_state.chan);
   grpc_slice_unref(g_state.details);
@@ -131,12 +134,14 @@ static void cleanup_test() {
   grpc_metadata_array_destroy(&g_state.trailing_metadata_recv);
 
   if (!g_state.is_client) {
-    grpc_call_destroy(g_state.server_call);
-    grpc_server_shutdown_and_notify(g_state.server, g_state.cq, tag(1000));
-    GPR_ASSERT(grpc_completion_queue_pluck(g_state.cq, tag(1000),
+    shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
+    grpc_call_unref(g_state.server_call);
+    grpc_server_shutdown_and_notify(g_state.server, shutdown_cq, tag(1000));
+    GPR_ASSERT(grpc_completion_queue_pluck(shutdown_cq, tag(1000),
                                            grpc_timeout_seconds_to_deadline(5),
                                            NULL)
                    .type == GRPC_OP_COMPLETE);
+    grpc_completion_queue_destroy(shutdown_cq);
     grpc_server_destroy(g_state.server);
     grpc_call_details_destroy(&g_state.call_details);
     grpc_metadata_array_destroy(&g_state.server_initial_metadata_recv);
diff --git a/test/core/end2end/multiple_server_queues_test.c b/test/core/end2end/multiple_server_queues_test.c
index 5e2eaf4ae9492106fe54992f5a0f7954ca4466ab..4696ecd813c1e9da413a1a1280c1b8ac89619c68 100644
--- a/test/core/end2end/multiple_server_queues_test.c
+++ b/test/core/end2end/multiple_server_queues_test.c
@@ -37,27 +37,50 @@
 int main(int argc, char **argv) {
   grpc_completion_queue *cq1;
   grpc_completion_queue *cq2;
+  grpc_completion_queue *cq3;
+  grpc_completion_queue_attributes attr;
+
   grpc_server *server;
 
   grpc_test_init(argc, argv);
   grpc_init();
-  cq1 = grpc_completion_queue_create(NULL);
-  cq2 = grpc_completion_queue_create(NULL);
+
+  attr.version = 1;
+  attr.cq_completion_type = GRPC_CQ_NEXT;
+  attr.cq_polling_type = GRPC_CQ_DEFAULT_POLLING;
+  cq1 = grpc_completion_queue_create(
+      grpc_completion_queue_factory_lookup(&attr), &attr, NULL);
+
+  attr.cq_polling_type = GRPC_CQ_NON_LISTENING;
+  cq2 = grpc_completion_queue_create(
+      grpc_completion_queue_factory_lookup(&attr), &attr, NULL);
+
+  attr.cq_polling_type = GRPC_CQ_NON_POLLING;
+  cq3 = grpc_completion_queue_create(
+      grpc_completion_queue_factory_lookup(&attr), &attr, NULL);
+
   server = grpc_server_create(NULL, NULL);
   grpc_server_register_completion_queue(server, cq1, NULL);
   grpc_server_add_insecure_http2_port(server, "[::]:0");
   grpc_server_register_completion_queue(server, cq2, NULL);
+  grpc_server_register_completion_queue(server, cq3, NULL);
+
   grpc_server_start(server);
   grpc_server_shutdown_and_notify(server, cq2, NULL);
   grpc_completion_queue_next(cq2, gpr_inf_future(GPR_CLOCK_REALTIME),
                              NULL); /* cue queue hang */
   grpc_completion_queue_shutdown(cq1);
   grpc_completion_queue_shutdown(cq2);
+  grpc_completion_queue_shutdown(cq3);
+
   grpc_completion_queue_next(cq1, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
   grpc_completion_queue_next(cq2, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+  grpc_completion_queue_next(cq3, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+
   grpc_server_destroy(server);
   grpc_completion_queue_destroy(cq1);
   grpc_completion_queue_destroy(cq2);
+  grpc_completion_queue_destroy(cq3);
   grpc_shutdown();
   return 0;
 }
diff --git a/test/core/end2end/no_server_test.c b/test/core/end2end/no_server_test.c
index 26d26d8f7a7a06d476a0f5da0b17e1c8a361ea1c..a479d5c868ad1bce652587671208366728631313 100644
--- a/test/core/end2end/no_server_test.c
+++ b/test/core/end2end/no_server_test.c
@@ -59,7 +59,7 @@ int main(int argc, char **argv) {
 
   grpc_metadata_array_init(&trailing_metadata_recv);
 
-  cq = grpc_completion_queue_create(NULL);
+  cq = grpc_completion_queue_create_for_next(NULL);
   cqv = cq_verifier_create(cq);
 
   /* create a call, channel to a non existant server */
@@ -97,7 +97,7 @@ int main(int argc, char **argv) {
           .type != GRPC_QUEUE_SHUTDOWN)
     ;
   grpc_completion_queue_destroy(cq);
-  grpc_call_destroy(call);
+  grpc_call_unref(call);
   grpc_channel_destroy(chan);
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/authority_not_supported.c b/test/core/end2end/tests/authority_not_supported.c
index 7db2fd6b278589569c9984d8630b1cd0749b8522..13cda08617347c4d497385e6bab1c364e05d61ff 100644
--- a/test/core/end2end/tests/authority_not_supported.c
+++ b/test/core/end2end/tests/authority_not_supported.c
@@ -57,24 +57,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -93,6 +96,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Request/response with metadata and payload.*/
@@ -102,7 +106,6 @@ static void test_with_authority_header(grpc_end2end_test_config config) {
       grpc_slice_from_copied_string("hello world");
   grpc_byte_buffer *request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
   grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"),
                               grpc_slice_from_static_string("val1"),
                               0,
@@ -124,6 +127,7 @@ static void test_with_authority_header(grpc_end2end_test_config config) {
   grpc_slice details;
 
   grpc_slice host = grpc_slice_from_static_string("foo.test.google.fr");
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
                                grpc_slice_from_static_string("/foo"), &host,
                                deadline, NULL);
@@ -178,7 +182,7 @@ static void test_with_authority_header(grpc_end2end_test_config config) {
   grpc_metadata_array_destroy(&initial_metadata_recv);
   grpc_metadata_array_destroy(&trailing_metadata_recv);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/bad_hostname.c b/test/core/end2end/tests/bad_hostname.c
index f50a5805a23aeecef11937fecf949b78e7835ba3..35a531cf7854da33a89d0c1ea51edb322d9efedf 100644
--- a/test/core/end2end/tests/bad_hostname.c
+++ b/test/core/end2end/tests/bad_hostname.c
@@ -59,24 +59,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -95,11 +98,11 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void simple_request_body(grpc_end2end_test_fixture f) {
   grpc_call *c;
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -112,6 +115,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
   grpc_slice details;
 
   grpc_slice host = grpc_slice_from_static_string("slartibartfast.local");
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
                                grpc_slice_from_static_string("/foo"), &host,
                                deadline, NULL);
@@ -159,7 +163,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
 
   cq_verifier_destroy(cqv);
 }
diff --git a/test/core/end2end/tests/bad_ping.c b/test/core/end2end/tests/bad_ping.c
new file mode 100644
index 0000000000000000000000000000000000000000..0928ba60cf9116c0c8fdd936db6ebf9b52968ed3
--- /dev/null
+++ b/test/core/end2end/tests/bad_ping.c
@@ -0,0 +1,238 @@
+/*
+ *
+ * Copyright 2017, 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/core/end2end/end2end_tests.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+
+#include "test/core/end2end/cq_verifier.h"
+
+#define MAX_PING_STRIKES 1
+
+static void *tag(intptr_t t) { return (void *)t; }
+
+static void drain_cq(grpc_completion_queue *cq) {
+  grpc_event ev;
+  do {
+    ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5),
+                                    NULL);
+  } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture *f) {
+  if (!f->server) return;
+  grpc_server_destroy(f->server);
+  f->server = NULL;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture *f) {
+  if (!f->client) return;
+  grpc_channel_destroy(f->client);
+  f->client = NULL;
+}
+
+static void end_test(grpc_end2end_test_fixture *f) {
+  shutdown_server(f);
+  shutdown_client(f);
+
+  grpc_completion_queue_shutdown(f->cq);
+  drain_cq(f->cq);
+  grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+static void test_bad_ping(grpc_end2end_test_config config) {
+  grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL);
+  cq_verifier *cqv = cq_verifier_create(f.cq);
+  grpc_arg client_a[] = {{.type = GRPC_ARG_INTEGER,
+                          .key = GRPC_ARG_HTTP2_MIN_TIME_BETWEEN_PINGS_MS,
+                          .value.integer = 0},
+                         {.type = GRPC_ARG_INTEGER,
+                          .key = GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA,
+                          .value.integer = 20},
+                         {.type = GRPC_ARG_INTEGER,
+                          .key = GRPC_ARG_HTTP2_BDP_PROBE,
+                          .value.integer = 0}};
+  grpc_arg server_a[] = {
+      {.type = GRPC_ARG_INTEGER,
+       .key = GRPC_ARG_HTTP2_MIN_PING_INTERVAL_WITHOUT_DATA_MS,
+       .value.integer = 300000 /* 5 minutes */},
+      {.type = GRPC_ARG_INTEGER,
+       .key = GRPC_ARG_HTTP2_MAX_PING_STRIKES,
+       .value.integer = MAX_PING_STRIKES}};
+  grpc_channel_args client_args = {.num_args = GPR_ARRAY_SIZE(client_a),
+                                   .args = client_a};
+  grpc_channel_args server_args = {.num_args = GPR_ARRAY_SIZE(server_a),
+                                   .args = server_a};
+
+  config.init_client(&f, &client_args);
+  config.init_server(&f, &server_args);
+
+  grpc_call *c;
+  grpc_call *s;
+  gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10);
+  grpc_op ops[6];
+  grpc_op *op;
+  grpc_metadata_array initial_metadata_recv;
+  grpc_metadata_array trailing_metadata_recv;
+  grpc_metadata_array request_metadata_recv;
+  grpc_call_details call_details;
+  grpc_status_code status;
+  grpc_call_error error;
+  grpc_slice details;
+  int was_cancelled = 2;
+
+  c = grpc_channel_create_call(
+      f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+      grpc_slice_from_static_string("/foo"),
+      get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+      NULL);
+  GPR_ASSERT(c);
+
+  grpc_metadata_array_init(&initial_metadata_recv);
+  grpc_metadata_array_init(&trailing_metadata_recv);
+  grpc_metadata_array_init(&request_metadata_recv);
+  grpc_call_details_init(&call_details);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op->data.send_initial_metadata.metadata = NULL;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_INITIAL_METADATA;
+  op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+  op->data.recv_status_on_client.status = &status;
+  op->data.recv_status_on_client.status_details = &details;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  error =
+      grpc_server_request_call(f.server, &s, &call_details,
+                               &request_metadata_recv, f.cq, f.cq, tag(101));
+  GPR_ASSERT(GRPC_CALL_OK == error);
+  CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
+  cq_verify(cqv);
+
+  // Send too many pings to the server to trigger the punishment:
+  // The first ping is sent after data frames, it won't trigger a ping strike.
+  // Each of the following pings will trigger a ping strike, and we need at
+  // least (MAX_PING_STRIKES + 1) strikes to trigger the punishment. So
+  // (MAX_PING_STRIKES + 2) pings are needed here.
+  int i;
+  for (i = 200; i < 202 + MAX_PING_STRIKES; i++) {
+    grpc_channel_ping(f.client, f.cq, tag(i), NULL);
+    CQ_EXPECT_COMPLETION(cqv, tag(i), 1);
+    cq_verify(cqv);
+  }
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+  op->data.send_status_from_server.trailing_metadata_count = 0;
+  op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
+  grpc_slice status_details = grpc_slice_from_static_string("xyz");
+  op->data.send_status_from_server.status_details = &status_details;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+  op->data.recv_close_on_server.cancelled = &was_cancelled;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
+  CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
+  cq_verify(cqv);
+
+  grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead));
+  CQ_EXPECT_COMPLETION(cqv, tag(0xdead), 1);
+  cq_verify(cqv);
+
+  grpc_call_unref(s);
+
+  // The connection should be closed immediately after the misbehaved pings,
+  // the in-progress RPC should fail.
+  GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
+  GPR_ASSERT(0 == grpc_slice_str_cmp(details, "Endpoint read failed"));
+  GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
+  validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+                                config);
+  GPR_ASSERT(was_cancelled == 1);
+
+  grpc_slice_unref(details);
+  grpc_metadata_array_destroy(&initial_metadata_recv);
+  grpc_metadata_array_destroy(&trailing_metadata_recv);
+  grpc_metadata_array_destroy(&request_metadata_recv);
+  grpc_call_details_destroy(&call_details);
+  grpc_call_unref(c);
+  cq_verifier_destroy(cqv);
+  end_test(&f);
+  config.tear_down_data(&f);
+}
+
+void bad_ping(grpc_end2end_test_config config) {
+  GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION);
+  test_bad_ping(config);
+}
+
+void bad_ping_pre_init(void) {}
diff --git a/test/core/end2end/tests/binary_metadata.c b/test/core/end2end/tests/binary_metadata.c
index 7fb60f4495b44c96bd9c10364ae6bde4acaf74e8..3d36849400a162364833372753a6b68c34fee570 100644
--- a/test/core/end2end/tests/binary_metadata.c
+++ b/test/core/end2end/tests/binary_metadata.c
@@ -57,24 +57,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -93,6 +96,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Request/response with metadata and payload.*/
@@ -108,7 +112,6 @@ static void test_request_response_with_metadata_and_payload(
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
   grpc_byte_buffer *response_payload =
       grpc_raw_byte_buffer_create(&response_payload_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
   grpc_metadata meta_c[2] = {
       {grpc_slice_from_static_string("key1-bin"),
        grpc_slice_from_static_string(
@@ -147,6 +150,7 @@ static void test_request_response_with_metadata_and_payload(
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -310,8 +314,8 @@ static void test_request_response_with_metadata_and_payload(
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/call_creds.c b/test/core/end2end/tests/call_creds.c
index 38cba50e12994ee0b5b855a9bd775c8d11e2c2c4..bc430e56b3331f1fcd9e0d23d25d656769705ab5 100644
--- a/test/core/end2end/tests/call_creds.c
+++ b/test/core/end2end/tests/call_creds.c
@@ -75,24 +75,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -111,6 +114,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void print_auth_context(int is_client, const grpc_auth_context *ctx) {
@@ -143,7 +147,6 @@ static void request_response_with_payload_and_call_creds(
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
   grpc_byte_buffer *response_payload =
       grpc_raw_byte_buffer_create(&response_payload_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
   grpc_end2end_test_fixture f;
   cq_verifier *cqv;
   grpc_op ops[6];
@@ -165,6 +168,7 @@ static void request_response_with_payload_and_call_creds(
   f = begin_test(config, test_name, 0);
   cqv = cq_verifier_create(f.cq);
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -343,8 +347,8 @@ static void request_response_with_payload_and_call_creds(
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
@@ -383,7 +387,7 @@ static void test_request_with_server_rejecting_client_creds(
   grpc_op *op;
   grpc_call *c;
   grpc_end2end_test_fixture f;
-  gpr_timespec deadline = five_seconds_time();
+  gpr_timespec deadline = five_seconds_from_now();
   cq_verifier *cqv;
   grpc_metadata_array initial_metadata_recv;
   grpc_metadata_array trailing_metadata_recv;
@@ -469,7 +473,7 @@ static void test_request_with_server_rejecting_client_creds(
   grpc_byte_buffer_destroy(response_payload_recv);
   grpc_slice_unref(details);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
 
   cq_verifier_destroy(cqv);
   end_test(&f);
diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c
index 1a92aa4837844d923d24d7adf77905e79a3fcf5d..e6bcd9d6a30efc208f341ce8ef129d38ed57c1d8 100644
--- a/test/core/end2end/tests/cancel_after_accept.c
+++ b/test/core/end2end/tests/cancel_after_accept.c
@@ -64,24 +64,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -100,6 +103,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Cancel after accept, no payload */
@@ -110,9 +114,6 @@ static void test_cancel_after_accept(grpc_end2end_test_config config,
   grpc_op *op;
   grpc_call *c;
   grpc_call *s;
-  gpr_timespec deadline = use_service_config
-                              ? gpr_inf_future(GPR_CLOCK_MONOTONIC)
-                              : five_seconds_time();
   grpc_metadata_array initial_metadata_recv;
   grpc_metadata_array trailing_metadata_recv;
   grpc_metadata_array request_metadata_recv;
@@ -153,6 +154,9 @@ static void test_cancel_after_accept(grpc_end2end_test_config config,
       begin_test(config, "cancel_after_accept", args, NULL);
   cq_verifier *cqv = cq_verifier_create(f.cq);
 
+  gpr_timespec deadline = use_service_config
+                              ? gpr_inf_future(GPR_CLOCK_MONOTONIC)
+                              : five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/service/method"),
@@ -248,8 +252,8 @@ static void test_cancel_after_accept(grpc_end2end_test_config config,
   grpc_byte_buffer_destroy(response_payload_recv);
   grpc_slice_unref(details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   if (args != NULL) {
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
diff --git a/test/core/end2end/tests/cancel_after_client_done.c b/test/core/end2end/tests/cancel_after_client_done.c
index 0afeecb037be0986c963ca7e3948539b83bffadc..d0e68354d9fd9e162e804e785114fb5746cffb98 100644
--- a/test/core/end2end/tests/cancel_after_client_done.c
+++ b/test/core/end2end/tests/cancel_after_client_done.c
@@ -58,24 +58,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -94,6 +97,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Cancel after accept with a writes closed, no payload */
@@ -105,7 +109,6 @@ static void test_cancel_after_accept_and_writes_closed(
   grpc_call *s;
   grpc_end2end_test_fixture f = begin_test(
       config, "test_cancel_after_accept_and_writes_closed", NULL, NULL);
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_metadata_array initial_metadata_recv;
   grpc_metadata_array trailing_metadata_recv;
@@ -126,6 +129,7 @@ static void test_cancel_after_accept_and_writes_closed(
       grpc_raw_byte_buffer_create(&response_payload_slice, 1);
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -225,8 +229,8 @@ static void test_cancel_after_accept_and_writes_closed(
   grpc_byte_buffer_destroy(response_payload_recv);
   grpc_slice_unref(details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
   end_test(&f);
diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c
index 8a96ef2f89482b8ce09473bf8b32064503210eb0..5bc9ed283bb6d01f08b7b8889da91aa924fd755f 100644
--- a/test/core/end2end/tests/cancel_after_invoke.c
+++ b/test/core/end2end/tests/cancel_after_invoke.c
@@ -49,36 +49,40 @@ static void *tag(intptr_t t) { return (void *)t; }
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char *test_name,
                                             cancellation_mode mode,
+                                            size_t test_ops,
                                             grpc_channel_args *client_args,
                                             grpc_channel_args *server_args) {
   grpc_end2end_test_fixture f;
-  gpr_log(GPR_INFO, "Running test: %s/%s/%s", test_name, config.name,
-          mode.name);
+  gpr_log(GPR_INFO, "Running test: %s/%s/%s [%" PRIdPTR " ops]", test_name,
+          config.name, mode.name, test_ops);
   f = config.create_fixture(client_args, server_args);
   config.init_server(&f, server_args);
   config.init_client(&f, client_args);
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
   grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
-                 .type == GRPC_OP_COMPLETE);
+  grpc_event ev = grpc_completion_queue_next(
+      f->cq, grpc_timeout_seconds_to_deadline(5), NULL);
+  GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
+  GPR_ASSERT(ev.tag == tag(1000));
   grpc_server_destroy(f->server);
   f->server = NULL;
 }
@@ -96,6 +100,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Cancel after invoke, no payload */
@@ -104,9 +109,8 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config,
   grpc_op ops[6];
   grpc_op *op;
   grpc_call *c;
-  grpc_end2end_test_fixture f =
-      begin_test(config, "test_cancel_after_invoke", mode, NULL, NULL);
-  gpr_timespec deadline = five_seconds_time();
+  grpc_end2end_test_fixture f = begin_test(config, "test_cancel_after_invoke",
+                                           mode, test_ops, NULL, NULL);
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_metadata_array initial_metadata_recv;
   grpc_metadata_array trailing_metadata_recv;
@@ -121,6 +125,7 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config,
   grpc_byte_buffer *request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -185,7 +190,7 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config,
   grpc_byte_buffer_destroy(response_payload_recv);
   grpc_slice_unref(details);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
 
   cq_verifier_destroy(cqv);
   end_test(&f);
diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c
index 586aa7ead37c1e80ab08cbb45c6186d70058b53e..67d2e9b8abcd2e3b3a0f1744297d15cbaa78549f 100644
--- a/test/core/end2end/tests/cancel_before_invoke.c
+++ b/test/core/end2end/tests/cancel_before_invoke.c
@@ -57,24 +57,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -93,6 +96,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Cancel before invoke */
@@ -103,7 +107,6 @@ static void test_cancel_before_invoke(grpc_end2end_test_config config,
   grpc_call *c;
   grpc_end2end_test_fixture f =
       begin_test(config, "cancel_before_invoke", NULL, NULL);
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_metadata_array initial_metadata_recv;
   grpc_metadata_array trailing_metadata_recv;
@@ -118,6 +121,7 @@ static void test_cancel_before_invoke(grpc_end2end_test_config config,
   grpc_byte_buffer *request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -182,7 +186,7 @@ static void test_cancel_before_invoke(grpc_end2end_test_config config,
   grpc_byte_buffer_destroy(response_payload_recv);
   grpc_slice_unref(details);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
 
   cq_verifier_destroy(cqv);
   end_test(&f);
diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c
index bc462ddcf56a68427054fc3cf7eac0fad7402fc3..1235cef2dce3094ca754090d2274992ffed44c6f 100644
--- a/test/core/end2end/tests/cancel_in_a_vacuum.c
+++ b/test/core/end2end/tests/cancel_in_a_vacuum.c
@@ -58,24 +58,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -94,6 +97,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Cancel and do nothing */
@@ -102,9 +106,9 @@ static void test_cancel_in_a_vacuum(grpc_end2end_test_config config,
   grpc_call *c;
   grpc_end2end_test_fixture f =
       begin_test(config, "test_cancel_in_a_vacuum", NULL, NULL);
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *v_client = cq_verifier_create(f.cq);
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -114,7 +118,7 @@ static void test_cancel_in_a_vacuum(grpc_end2end_test_config config,
 
   GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, NULL));
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
 
   cq_verifier_destroy(v_client);
   end_test(&f);
diff --git a/test/core/end2end/tests/cancel_with_status.c b/test/core/end2end/tests/cancel_with_status.c
index 7d03fe5580f8e8a6225a992a6b178bd8efa21ac2..e8259f99f116194657afd201ddafba64848809e1 100644
--- a/test/core/end2end/tests/cancel_with_status.c
+++ b/test/core/end2end/tests/cancel_with_status.c
@@ -59,25 +59,28 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
   grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
-                 .type == GRPC_OP_COMPLETE);
+  grpc_event ev = grpc_completion_queue_next(
+      f->cq, grpc_timeout_seconds_to_deadline(5), NULL);
+  GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
+  GPR_ASSERT(ev.tag == tag(1000));
   grpc_server_destroy(f->server);
   f->server = NULL;
 }
@@ -95,12 +98,12 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void simple_request_body(grpc_end2end_test_config config,
                                 grpc_end2end_test_fixture f, size_t num_ops) {
   grpc_call *c;
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -112,6 +115,7 @@ static void simple_request_body(grpc_end2end_test_config config,
 
   gpr_log(GPR_DEBUG, "test with %" PRIuPTR " ops", num_ops);
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -161,7 +165,7 @@ static void simple_request_body(grpc_end2end_test_config config,
   grpc_metadata_array_destroy(&initial_metadata_recv);
   grpc_metadata_array_destroy(&trailing_metadata_recv);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
 
   cq_verifier_destroy(cqv);
 }
diff --git a/test/core/end2end/tests/compressed_payload.c b/test/core/end2end/tests/compressed_payload.c
index 7dd8c112d1187d13e9c5f50b3572891a3618a55e..1fe8613adbef968f5266d4aaaeba5f44234242b0 100644
--- a/test/core/end2end/tests/compressed_payload.c
+++ b/test/core/end2end/tests/compressed_payload.c
@@ -65,24 +65,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -101,6 +104,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void request_for_disabled_algorithm(
@@ -113,7 +117,6 @@ static void request_for_disabled_algorithm(
   grpc_call *s;
   grpc_slice request_payload_slice;
   grpc_byte_buffer *request_payload;
-  gpr_timespec deadline = five_seconds_time();
   grpc_channel_args *client_args;
   grpc_channel_args *server_args;
   grpc_end2end_test_fixture f;
@@ -150,6 +153,7 @@ static void request_for_disabled_algorithm(
   f = begin_test(config, test_name, client_args, server_args);
   cqv = cq_verifier_create(f.cq);
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -257,8 +261,8 @@ static void request_for_disabled_algorithm(
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
@@ -290,7 +294,6 @@ static void request_with_payload_template(
   grpc_call *s;
   grpc_slice request_payload_slice;
   grpc_byte_buffer *request_payload;
-  gpr_timespec deadline = five_seconds_time();
   grpc_channel_args *client_args;
   grpc_channel_args *server_args;
   grpc_end2end_test_fixture f;
@@ -329,6 +332,7 @@ static void request_with_payload_template(
   f = begin_test(config, test_name, client_args, server_args);
   cqv = cq_verifier_create(f.cq);
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -515,8 +519,8 @@ static void request_with_payload_template(
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/connectivity.c b/test/core/end2end/tests/connectivity.c
index 979419a100a9dc5e936865cf1bf70fdea3b0ac13..eb84aaed16b38ee9add6c380b5a48939cd8dae6c 100644
--- a/test/core/end2end/tests/connectivity.c
+++ b/test/core/end2end/tests/connectivity.c
@@ -171,6 +171,9 @@ static void test_connectivity(grpc_end2end_test_config config) {
   grpc_channel_destroy(f.client);
   grpc_completion_queue_shutdown(f.cq);
   grpc_completion_queue_destroy(f.cq);
+
+  /* shutdown_cq is not used in this test */
+  grpc_completion_queue_destroy(f.shutdown_cq);
   config.tear_down_data(&f);
 
   cq_verifier_destroy(cqv);
diff --git a/test/core/end2end/tests/default_host.c b/test/core/end2end/tests/default_host.c
index bc1829b24b781dc20f357259f59e60ce87e7ea4c..efd26829327b8737da39f05eaabe5c6d16f331b2 100644
--- a/test/core/end2end/tests/default_host.c
+++ b/test/core/end2end/tests/default_host.c
@@ -59,24 +59,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -95,12 +98,12 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void simple_request_body(grpc_end2end_test_fixture f) {
   grpc_call *c;
   grpc_call *s;
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -114,6 +117,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
   int was_cancelled = 2;
   char *peer;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
                                grpc_slice_from_static_string("/foo"), NULL,
                                deadline, NULL);
@@ -210,8 +214,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 }
diff --git a/test/core/end2end/tests/disappearing_server.c b/test/core/end2end/tests/disappearing_server.c
index 05440a6f56cc2c9f201fd1271e76abd2dbbb77d8..23016f9ee5c867196d4f154c6032cf1f7e74549f 100644
--- a/test/core/end2end/tests/disappearing_server.c
+++ b/test/core/end2end/tests/disappearing_server.c
@@ -45,16 +45,18 @@
 
 static void *tag(intptr_t t) { return (void *)t; }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
@@ -77,6 +79,9 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+
+  /* Note: shutdown_cq was unused in this test */
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void do_request_and_shutdown_server(grpc_end2end_test_config config,
@@ -84,7 +89,6 @@ static void do_request_and_shutdown_server(grpc_end2end_test_config config,
                                            cq_verifier *cqv) {
   grpc_call *c;
   grpc_call *s;
-  gpr_timespec deadline = five_seconds_time();
   grpc_op ops[6];
   grpc_op *op;
   grpc_metadata_array initial_metadata_recv;
@@ -96,6 +100,7 @@ static void do_request_and_shutdown_server(grpc_end2end_test_config config,
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f->client, NULL, GRPC_PROPAGATE_DEFAULTS, f->cq,
       grpc_slice_from_static_string("/foo"),
@@ -186,8 +191,8 @@ static void do_request_and_shutdown_server(grpc_end2end_test_config config,
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 }
 
 static void disappearing_server_test(grpc_end2end_test_config config) {
diff --git a/test/core/end2end/tests/empty_batch.c b/test/core/end2end/tests/empty_batch.c
index 50bb6b849e14aca00348a9dca1951fd91c93454c..d0971367a67b0617328673849242445cc0bbce50 100644
--- a/test/core/end2end/tests/empty_batch.c
+++ b/test/core/end2end/tests/empty_batch.c
@@ -59,24 +59,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -95,16 +98,17 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void empty_batch_body(grpc_end2end_test_config config,
                              grpc_end2end_test_fixture f) {
   grpc_call *c;
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_call_error error;
   grpc_op *op = NULL;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -117,7 +121,7 @@ static void empty_batch_body(grpc_end2end_test_config config,
   CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
   cq_verify(cqv);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
 
   cq_verifier_destroy(cqv);
 }
diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c
index d2d6e82d57437aafde432b08dbde300f0f9c33e8..3402584fd9a3e0262cb40c4f9fb09d57ae6ea4e6 100644
--- a/test/core/end2end/tests/filter_call_init_fails.c
+++ b/test/core/end2end/tests/filter_call_init_fails.c
@@ -49,7 +49,9 @@
 
 enum { TIMEOUT = 200000 };
 
-static bool g_enable_filter = false;
+static bool g_enable_server_channel_filter = false;
+static bool g_enable_client_channel_filter = false;
+static bool g_enable_client_subchannel_filter = false;
 
 static void *tag(intptr_t t) { return (void *)t; }
 
@@ -65,24 +67,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -101,18 +106,18 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
-// Simple request via a server filter that always fails to initialize
-// the call.
-static void test_request(grpc_end2end_test_config config) {
+// Simple request via a SERVER_CHANNEL filter that always fails to
+// initialize the call.
+static void test_server_channel_filter(grpc_end2end_test_config config) {
   grpc_call *c;
   grpc_call *s;
   grpc_slice request_payload_slice =
       grpc_slice_from_copied_string("hello world");
   grpc_byte_buffer *request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
   grpc_end2end_test_fixture f =
       begin_test(config, "filter_call_init_fails", NULL, NULL);
   cq_verifier *cqv = cq_verifier_create(f.cq);
@@ -127,6 +132,7 @@ static void test_request(grpc_end2end_test_config config) {
   grpc_call_error error;
   grpc_slice details;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -188,7 +194,212 @@ static void test_request(grpc_end2end_test_config config) {
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
+
+  cq_verifier_destroy(cqv);
+
+  grpc_byte_buffer_destroy(request_payload);
+  grpc_byte_buffer_destroy(request_payload_recv);
+
+  end_test(&f);
+  config.tear_down_data(&f);
+}
+
+// Simple request via a CLIENT_CHANNEL or CLIENT_DIRECT_CHANNEL filter
+// that always fails to initialize the call.
+static void test_client_channel_filter(grpc_end2end_test_config config) {
+  grpc_call *c;
+  grpc_slice request_payload_slice =
+      grpc_slice_from_copied_string("hello world");
+  grpc_byte_buffer *request_payload =
+      grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+  gpr_timespec deadline = five_seconds_from_now();
+  grpc_end2end_test_fixture f =
+      begin_test(config, "filter_call_init_fails", NULL, NULL);
+  cq_verifier *cqv = cq_verifier_create(f.cq);
+  grpc_op ops[6];
+  grpc_op *op;
+  grpc_metadata_array initial_metadata_recv;
+  grpc_metadata_array trailing_metadata_recv;
+  grpc_metadata_array request_metadata_recv;
+  grpc_byte_buffer *request_payload_recv = NULL;
+  grpc_call_details call_details;
+  grpc_status_code status;
+  grpc_call_error error;
+  grpc_slice details;
+
+  c = grpc_channel_create_call(
+      f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+      grpc_slice_from_static_string("/foo"),
+      get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+      NULL);
+  GPR_ASSERT(c);
+
+  grpc_metadata_array_init(&initial_metadata_recv);
+  grpc_metadata_array_init(&trailing_metadata_recv);
+  grpc_metadata_array_init(&request_metadata_recv);
+  grpc_call_details_init(&call_details);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op->data.send_initial_metadata.metadata = NULL;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_MESSAGE;
+  op->data.send_message.send_message = request_payload;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_INITIAL_METADATA;
+  op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+  op->data.recv_status_on_client.status = &status;
+  op->data.recv_status_on_client.status_details = &details;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
+  cq_verify(cqv);
+
+  GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
+  GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
+
+  grpc_slice_unref(details);
+  grpc_metadata_array_destroy(&initial_metadata_recv);
+  grpc_metadata_array_destroy(&trailing_metadata_recv);
+  grpc_metadata_array_destroy(&request_metadata_recv);
+  grpc_call_details_destroy(&call_details);
+
+  grpc_call_unref(c);
+
+  cq_verifier_destroy(cqv);
+
+  grpc_byte_buffer_destroy(request_payload);
+  grpc_byte_buffer_destroy(request_payload_recv);
+
+  end_test(&f);
+  config.tear_down_data(&f);
+}
+
+// Simple request via a CLIENT_SUBCHANNEL filter that always fails to
+// initialize the call.
+static void test_client_subchannel_filter(grpc_end2end_test_config config) {
+  grpc_call *c;
+  grpc_slice request_payload_slice =
+      grpc_slice_from_copied_string("hello world");
+  grpc_byte_buffer *request_payload =
+      grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+  gpr_timespec deadline = five_seconds_from_now();
+  grpc_end2end_test_fixture f =
+      begin_test(config, "filter_call_init_fails", NULL, NULL);
+  cq_verifier *cqv = cq_verifier_create(f.cq);
+  grpc_op ops[6];
+  grpc_op *op;
+  grpc_metadata_array initial_metadata_recv;
+  grpc_metadata_array trailing_metadata_recv;
+  grpc_metadata_array request_metadata_recv;
+  grpc_byte_buffer *request_payload_recv = NULL;
+  grpc_call_details call_details;
+  grpc_status_code status;
+  grpc_call_error error;
+  grpc_slice details;
+
+  c = grpc_channel_create_call(
+      f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+      grpc_slice_from_static_string("/foo"),
+      get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+      NULL);
+  GPR_ASSERT(c);
+
+  grpc_metadata_array_init(&initial_metadata_recv);
+  grpc_metadata_array_init(&trailing_metadata_recv);
+  grpc_metadata_array_init(&request_metadata_recv);
+  grpc_call_details_init(&call_details);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op->data.send_initial_metadata.metadata = NULL;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_MESSAGE;
+  op->data.send_message.send_message = request_payload;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_INITIAL_METADATA;
+  op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+  op->data.recv_status_on_client.status = &status;
+  op->data.recv_status_on_client.status_details = &details;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
+  cq_verify(cqv);
+
+  GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
+  GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
+
+  // Reset and create a new call.  (The first call uses a different code
+  // path in client_channel.c than subsequent calls on the same channel,
+  // and we need to test both.)
+  grpc_call_unref(c);
+  status = GRPC_STATUS_OK;
+  grpc_slice_unref(details);
+  details = grpc_empty_slice();
+
+  c = grpc_channel_create_call(
+      f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+      grpc_slice_from_static_string("/foo"),
+      get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+      NULL);
+  GPR_ASSERT(c);
+
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  CQ_EXPECT_COMPLETION(cqv, tag(2), 1);
+  cq_verify(cqv);
+
+  GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
+  GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
+
+  grpc_slice_unref(details);
+  grpc_metadata_array_destroy(&initial_metadata_recv);
+  grpc_metadata_array_destroy(&trailing_metadata_recv);
+  grpc_metadata_array_destroy(&request_metadata_recv);
+  grpc_call_details_destroy(&call_details);
+
+  grpc_call_unref(c);
 
   cq_verifier_destroy(cqv);
 
@@ -206,14 +417,14 @@ static void test_request(grpc_end2end_test_config config) {
 static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
                                   grpc_call_element *elem,
                                   const grpc_call_element_args *args) {
-  return grpc_error_set_int(GRPC_ERROR_CREATE("access denied"),
-                            GRPC_ERROR_INT_GRPC_STATUS,
-                            GRPC_STATUS_PERMISSION_DENIED);
+  return grpc_error_set_int(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("access denied"),
+      GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_PERMISSION_DENIED);
 }
 
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
-                              void *and_free_memory) {}
+                              grpc_closure *ignored) {}
 
 static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_channel_element *elem,
@@ -242,9 +453,10 @@ static const grpc_channel_filter test_filter = {
  * Registration
  */
 
-static bool maybe_add_filter(grpc_exec_ctx *exec_ctx,
-                             grpc_channel_stack_builder *builder, void *arg) {
-  if (g_enable_filter) {
+static bool maybe_add_server_channel_filter(grpc_exec_ctx *exec_ctx,
+                                            grpc_channel_stack_builder *builder,
+                                            void *arg) {
+  if (g_enable_server_channel_filter) {
     // Want to add the filter as close to the end as possible, to make
     // sure that all of the filters work well together.  However, we
     // can't add it at the very end, because the connected channel filter
@@ -261,17 +473,73 @@ static bool maybe_add_filter(grpc_exec_ctx *exec_ctx,
   }
 }
 
+static bool maybe_add_client_channel_filter(grpc_exec_ctx *exec_ctx,
+                                            grpc_channel_stack_builder *builder,
+                                            void *arg) {
+  if (g_enable_client_channel_filter) {
+    // Want to add the filter as close to the end as possible, to make
+    // sure that all of the filters work well together.  However, we
+    // can't add it at the very end, because the connected channel filter
+    // must be the last one.  So we add it right before the last one.
+    grpc_channel_stack_builder_iterator *it =
+        grpc_channel_stack_builder_create_iterator_at_last(builder);
+    GPR_ASSERT(grpc_channel_stack_builder_move_prev(it));
+    const bool retval = grpc_channel_stack_builder_add_filter_before(
+        it, &test_filter, NULL, NULL);
+    grpc_channel_stack_builder_iterator_destroy(it);
+    return retval;
+  } else {
+    return true;
+  }
+}
+
+static bool maybe_add_client_subchannel_filter(
+    grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder, void *arg) {
+  if (g_enable_client_subchannel_filter) {
+    // Want to add the filter as close to the end as possible, to make
+    // sure that all of the filters work well together.  However, we
+    // can't add it at the very end, because the client channel filter
+    // must be the last one.  So we add it right before the last one.
+    grpc_channel_stack_builder_iterator *it =
+        grpc_channel_stack_builder_create_iterator_at_last(builder);
+    GPR_ASSERT(grpc_channel_stack_builder_move_prev(it));
+    const bool retval = grpc_channel_stack_builder_add_filter_before(
+        it, &test_filter, NULL, NULL);
+    grpc_channel_stack_builder_iterator_destroy(it);
+    return retval;
+  } else {
+    return true;
+  }
+}
+
 static void init_plugin(void) {
   grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
-                                   maybe_add_filter, NULL);
+                                   maybe_add_server_channel_filter, NULL);
+  grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX,
+                                   maybe_add_client_channel_filter, NULL);
+  grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX,
+                                   maybe_add_client_subchannel_filter, NULL);
+  grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX,
+                                   maybe_add_client_channel_filter, NULL);
 }
 
 static void destroy_plugin(void) {}
 
 void filter_call_init_fails(grpc_end2end_test_config config) {
-  g_enable_filter = true;
-  test_request(config);
-  g_enable_filter = false;
+  gpr_log(GPR_INFO, "Testing SERVER_CHANNEL filter.");
+  g_enable_server_channel_filter = true;
+  test_server_channel_filter(config);
+  g_enable_server_channel_filter = false;
+  gpr_log(GPR_INFO, "Testing CLIENT_CHANNEL / CLIENT_DIRECT_CHANNEL filter.");
+  g_enable_client_channel_filter = true;
+  test_client_channel_filter(config);
+  g_enable_client_channel_filter = false;
+  if (config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL) {
+    gpr_log(GPR_INFO, "Testing CLIENT_SUBCHANNEL filter.");
+    g_enable_client_subchannel_filter = true;
+    test_client_subchannel_filter(config);
+    g_enable_client_subchannel_filter = false;
+  }
 }
 
 void filter_call_init_fails_pre_init(void) {
diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c
index 25e606556da641e7652bc7f54d44ec3f5f487490..ede8fb49df0f5ca828bea619310c845b30a6fe95 100644
--- a/test/core/end2end/tests/filter_causes_close.c
+++ b/test/core/end2end/tests/filter_causes_close.c
@@ -62,24 +62,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -98,6 +101,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Simple request via a server filter that always closes the stream.*/
@@ -108,7 +112,6 @@ static void test_request(grpc_end2end_test_config config) {
       grpc_slice_from_copied_string("hello world");
   grpc_byte_buffer *request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
   grpc_end2end_test_fixture f =
       begin_test(config, "filter_causes_close", NULL, NULL);
   cq_verifier *cqv = cq_verifier_create(f.cq);
@@ -123,6 +126,7 @@ static void test_request(grpc_end2end_test_config config) {
   grpc_call_error error;
   grpc_slice details;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -185,7 +189,7 @@ static void test_request(grpc_end2end_test_config config) {
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
 
   cq_verifier_destroy(cqv);
 
@@ -210,19 +214,20 @@ static void recv_im_ready(grpc_exec_ctx *exec_ctx, void *arg,
   call_data *calld = elem->call_data;
   grpc_closure_sched(
       exec_ctx, calld->recv_im_ready,
-      grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING(
+      grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
                              "Failure that's not preventable.", &error, 1),
                          GRPC_ERROR_INT_GRPC_STATUS,
                          GRPC_STATUS_PERMISSION_DENIED));
 }
 
-static void start_transport_stream_op(grpc_exec_ctx *exec_ctx,
-                                      grpc_call_element *elem,
-                                      grpc_transport_stream_op *op) {
+static void start_transport_stream_op_batch(
+    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+    grpc_transport_stream_op_batch *op) {
   call_data *calld = elem->call_data;
-  if (op->recv_initial_metadata != NULL) {
-    calld->recv_im_ready = op->recv_initial_metadata_ready;
-    op->recv_initial_metadata_ready =
+  if (op->recv_initial_metadata) {
+    calld->recv_im_ready =
+        op->payload->recv_initial_metadata.recv_initial_metadata_ready;
+    op->payload->recv_initial_metadata.recv_initial_metadata_ready =
         grpc_closure_create(recv_im_ready, elem, grpc_schedule_on_exec_ctx);
   }
   grpc_call_next_op(exec_ctx, elem, op);
@@ -236,7 +241,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
 
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
-                              void *and_free_memory) {}
+                              grpc_closure *ignored) {}
 
 static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_channel_element *elem,
@@ -248,7 +253,7 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
                                  grpc_channel_element *elem) {}
 
 static const grpc_channel_filter test_filter = {
-    start_transport_stream_op,
+    start_transport_stream_op_batch,
     grpc_channel_next_op,
     sizeof(call_data),
     init_call_elem,
diff --git a/test/core/end2end/tests/filter_latency.c b/test/core/end2end/tests/filter_latency.c
index d05e9e79a1175ee4f09168766da28cb7af75a49a..7d2614a06769a48fdfab8f521a27289958e934be 100644
--- a/test/core/end2end/tests/filter_latency.c
+++ b/test/core/end2end/tests/filter_latency.c
@@ -69,24 +69,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -105,6 +108,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 // Simple request via a server filter that saves the reported latency value.
@@ -115,7 +119,6 @@ static void test_request(grpc_end2end_test_config config) {
       grpc_slice_from_copied_string("hello world");
   grpc_byte_buffer *request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
   grpc_end2end_test_fixture f =
       begin_test(config, "filter_latency", NULL, NULL);
   cq_verifier *cqv = cq_verifier_create(f.cq);
@@ -137,6 +140,7 @@ static void test_request(grpc_end2end_test_config config) {
   gpr_mu_unlock(&g_mu);
   const gpr_timespec start_time = gpr_now(GPR_CLOCK_MONOTONIC);
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -224,8 +228,8 @@ static void test_request(grpc_end2end_test_config config) {
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(s);
-  grpc_call_destroy(c);
+  grpc_call_unref(s);
+  grpc_call_unref(c);
 
   cq_verifier_destroy(cqv);
 
@@ -267,7 +271,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
 static void client_destroy_call_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_call_element *elem,
                                      const grpc_call_final_info *final_info,
-                                     void *and_free_memory) {
+                                     grpc_closure *ignored) {
   gpr_mu_lock(&g_mu);
   g_client_latency = final_info->stats.latency;
   gpr_mu_unlock(&g_mu);
@@ -276,7 +280,7 @@ static void client_destroy_call_elem(grpc_exec_ctx *exec_ctx,
 static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_call_element *elem,
                                      const grpc_call_final_info *final_info,
-                                     void *and_free_memory) {
+                                     grpc_closure *ignored) {
   gpr_mu_lock(&g_mu);
   g_server_latency = final_info->stats.latency;
   gpr_mu_unlock(&g_mu);
diff --git a/test/core/end2end/tests/graceful_server_shutdown.c b/test/core/end2end/tests/graceful_server_shutdown.c
index a3ad260cc221341eaa97a0619adad27c2bcfa762..37ac33818f4c72fb7977ba52d1b3ce17b929abc1 100644
--- a/test/core/end2end/tests/graceful_server_shutdown.c
+++ b/test/core/end2end/tests/graceful_server_shutdown.c
@@ -57,16 +57,18 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
@@ -89,13 +91,14 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  /* Note: shutdown_cq is not used in this test */
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void test_early_server_shutdown_finishes_inflight_calls(
     grpc_end2end_test_config config) {
   grpc_call *c;
   grpc_call *s;
-  gpr_timespec deadline = n_seconds_time(10);
   grpc_end2end_test_fixture f = begin_test(
       config, "test_early_server_shutdown_finishes_inflight_calls", NULL, NULL);
   cq_verifier *cqv = cq_verifier_create(f.cq);
@@ -110,6 +113,7 @@ static void test_early_server_shutdown_finishes_inflight_calls(
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = n_seconds_from_now(10);
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -188,7 +192,7 @@ static void test_early_server_shutdown_finishes_inflight_calls(
   CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
   cq_verify(cqv);
 
-  grpc_call_destroy(s);
+  grpc_call_unref(s);
 
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
@@ -202,7 +206,7 @@ static void test_early_server_shutdown_finishes_inflight_calls(
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/high_initial_seqno.c b/test/core/end2end/tests/high_initial_seqno.c
index cca8532b0e0149da78b2836d5187273de9b544d0..893fdd6862111a4c6e3fae43c8691713b65986ad 100644
--- a/test/core/end2end/tests/high_initial_seqno.c
+++ b/test/core/end2end/tests/high_initial_seqno.c
@@ -61,24 +61,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -97,13 +100,13 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void simple_request_body(grpc_end2end_test_config config,
                                 grpc_end2end_test_fixture f) {
   grpc_call *c;
   grpc_call *s;
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -116,6 +119,7 @@ static void simple_request_body(grpc_end2end_test_config config,
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -201,8 +205,8 @@ static void simple_request_body(grpc_end2end_test_config config,
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   /* TODO(ctiller): this rate limits the test, and it should be removed when
                     retry has been implemented; until then cross-thread chatter
diff --git a/test/core/end2end/tests/hpack_size.c b/test/core/end2end/tests/hpack_size.c
index 7601722deea1b863c8e4063c648f31b9bab9cb39..b1db58271e5d122d3a9dc14b407de6dfe8f07461 100644
--- a/test/core/end2end/tests/hpack_size.c
+++ b/test/core/end2end/tests/hpack_size.c
@@ -201,24 +201,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -237,13 +240,13 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void simple_request_body(grpc_end2end_test_config config,
                                 grpc_end2end_test_fixture f, size_t index) {
   grpc_call *c;
   grpc_call *s;
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -268,6 +271,7 @@ static void simple_request_body(grpc_end2end_test_config config,
   extra_metadata[2].value =
       grpc_slice_from_static_string(dragons[index % GPR_ARRAY_SIZE(dragons)]);
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -354,8 +358,8 @@ static void simple_request_body(grpc_end2end_test_config config,
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 }
diff --git a/test/core/end2end/tests/idempotent_request.c b/test/core/end2end/tests/idempotent_request.c
index cef2e100be962bd822505df0f5c6a59e541c826a..1ea2ac477428619f1c4c248338d3bdffefaf2102 100644
--- a/test/core/end2end/tests/idempotent_request.c
+++ b/test/core/end2end/tests/idempotent_request.c
@@ -59,24 +59,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -95,13 +98,13 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void simple_request_body(grpc_end2end_test_config config,
                                 grpc_end2end_test_fixture f) {
   grpc_call *c;
   grpc_call *s;
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -115,6 +118,7 @@ static void simple_request_body(grpc_end2end_test_config config,
   int was_cancelled = 2;
   char *peer;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -215,8 +219,8 @@ static void simple_request_body(grpc_end2end_test_config config,
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 }
diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c
index d799bd8ccf98aac80d6d6c8c205b7a79cbab1c91..a49cf4f3d727bc106080c2c77ccd49fb4ac1ce85 100644
--- a/test/core/end2end/tests/invoke_large_request.c
+++ b/test/core/end2end/tests/invoke_large_request.c
@@ -58,22 +58,23 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, n_seconds_time(5), NULL);
+    ev = grpc_completion_queue_next(cq, n_seconds_from_now(5), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -92,6 +93,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static grpc_slice large_slice(void) {
@@ -128,7 +130,6 @@ static void test_invoke_large_request(grpc_end2end_test_config config,
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
   grpc_byte_buffer *response_payload =
       grpc_raw_byte_buffer_create(&response_payload_slice, 1);
-  gpr_timespec deadline = n_seconds_time(30);
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -143,6 +144,7 @@ static void test_invoke_large_request(grpc_end2end_test_config config,
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = n_seconds_from_now(30);
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -256,8 +258,8 @@ static void test_invoke_large_request(grpc_end2end_test_config config,
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/keepalive_timeout.c b/test/core/end2end/tests/keepalive_timeout.c
index 4296be361903c4baa96dd636f70ae63c3c5dbc4a..ceefe5db8e32acafae35f5aeb0c5dbc55a564cb4 100644
--- a/test/core/end2end/tests/keepalive_timeout.c
+++ b/test/core/end2end/tests/keepalive_timeout.c
@@ -41,6 +41,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
+#include "src/core/ext/transport/chttp2/transport/frame_ping.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/support/env.h"
@@ -60,25 +61,28 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(
-      grpc_completion_queue_pluck(f->cq, tag(1000), five_seconds_time(), NULL)
-          .type == GRPC_OP_COMPLETE);
+
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         five_seconds_from_now(), NULL)
+                 .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
 }
@@ -96,6 +100,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Client sends a request, server replies with a payload, then waits for the
@@ -107,15 +112,16 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) {
       grpc_slice_from_copied_string("hello world");
   grpc_byte_buffer *response_payload =
       grpc_raw_byte_buffer_create(&response_payload_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
 
-  grpc_arg keepalive_args[2];
-  keepalive_args[0].type = GRPC_ARG_INTEGER;
-  keepalive_args[0].key = GRPC_ARG_HTTP2_KEEPALIVE_TIME;
-  keepalive_args[0].value.integer = 2;
-  keepalive_args[1].type = GRPC_ARG_INTEGER;
-  keepalive_args[1].key = GRPC_ARG_HTTP2_KEEPALIVE_TIMEOUT;
-  keepalive_args[1].value.integer = 0;
+  grpc_arg keepalive_args[] = {{.type = GRPC_ARG_INTEGER,
+                                .key = GRPC_ARG_KEEPALIVE_TIME_MS,
+                                .value.integer = 1500},
+                               {.type = GRPC_ARG_INTEGER,
+                                .key = GRPC_ARG_KEEPALIVE_TIMEOUT_MS,
+                                .value.integer = 0},
+                               {.type = GRPC_ARG_INTEGER,
+                                .key = GRPC_ARG_HTTP2_BDP_PROBE,
+                                .value.integer = 1}};
 
   grpc_channel_args *client_args = NULL;
   client_args = grpc_channel_args_copy_and_add(client_args, keepalive_args, 2);
@@ -134,6 +140,10 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) {
   grpc_call_error error;
   grpc_slice details;
 
+  /* Disable ping ack to trigger the keepalive timeout */
+  grpc_set_disable_ping_ack(true);
+
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -180,8 +190,6 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) {
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
-  cq_verify(cqv);
-
   CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
   cq_verify(cqv);
 
@@ -215,8 +223,8 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) {
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/large_metadata.c b/test/core/end2end/tests/large_metadata.c
index ac4c0e7f3b459a4651173151fd2ca11e72bf63af..dd796889dbcd01bcacdaf618e4df103e52d9987f 100644
--- a/test/core/end2end/tests/large_metadata.c
+++ b/test/core/end2end/tests/large_metadata.c
@@ -57,24 +57,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -93,6 +96,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 // Request with a large amount of metadata.
@@ -103,7 +107,6 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) {
       grpc_slice_from_copied_string("hello world");
   grpc_byte_buffer *request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
   grpc_metadata meta;
   const size_t large_size = 64 * 1024;
   grpc_arg arg = {GRPC_ARG_INTEGER,
@@ -125,6 +128,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) {
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -242,8 +246,8 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) {
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/load_reporting_hook.c b/test/core/end2end/tests/load_reporting_hook.c
index d1ee26fe50272ca79bc06509823ac8ccbfebf046..5f671405c271e2b9097f114aecd9841cc7e1049b 100644
--- a/test/core/end2end/tests/load_reporting_hook.c
+++ b/test/core/end2end/tests/load_reporting_hook.c
@@ -41,8 +41,8 @@
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
 
-#include "src/core/ext/load_reporting/load_reporting.h"
-#include "src/core/ext/load_reporting/load_reporting_filter.h"
+#include "src/core/ext/filters/load_reporting/load_reporting.h"
+#include "src/core/ext/filters/load_reporting/load_reporting_filter.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/transport/static_metadata.h"
 
@@ -84,24 +84,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -120,13 +123,13 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void request_response_with_payload(
     grpc_end2end_test_config config, grpc_end2end_test_fixture f,
     const char *method_name, const char *request_msg, const char *response_msg,
-    grpc_metadata *initial_lr_metadata,
-    grpc_load_reporting_cost_context *cost_ctx) {
+    grpc_metadata *initial_lr_metadata, grpc_metadata *trailing_lr_metadata) {
   grpc_slice request_payload_slice = grpc_slice_from_static_string(request_msg);
   grpc_slice response_payload_slice =
       grpc_slice_from_static_string(response_msg);
@@ -136,7 +139,6 @@ static void request_response_with_payload(
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
   grpc_byte_buffer *response_payload =
       grpc_raw_byte_buffer_create(&response_payload_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -151,6 +153,7 @@ static void request_response_with_payload(
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string(method_name),
@@ -239,8 +242,9 @@ static void request_response_with_payload(
   op->reserved = NULL;
   op++;
   op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
-  GPR_ASSERT(cost_ctx != NULL);
-  grpc_call_set_load_reporting_cost_context(s, cost_ctx);
+  GPR_ASSERT(trailing_lr_metadata != NULL);
+  op->data.send_status_from_server.trailing_metadata_count = 1;
+  op->data.send_status_from_server.trailing_metadata = trailing_lr_metadata;
   op->data.send_status_from_server.status = GRPC_STATUS_OK;
   grpc_slice status_details = grpc_slice_from_static_string("xyz");
   op->data.send_status_from_server.status_details = &status_details;
@@ -262,8 +266,8 @@ static void request_response_with_payload(
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
@@ -294,21 +298,21 @@ static void test_load_reporting_hook(grpc_end2end_test_config config) {
   const char *response_msg = "... and the response from the server";
 
   grpc_metadata initial_lr_metadata;
+  grpc_metadata trailing_lr_metadata;
 
   initial_lr_metadata.key = GRPC_MDSTR_LB_TOKEN;
   initial_lr_metadata.value = grpc_slice_from_static_string("client-token");
   memset(&initial_lr_metadata.internal_data, 0,
          sizeof(initial_lr_metadata.internal_data));
 
-  grpc_load_reporting_cost_context *cost_ctx = gpr_malloc(sizeof(*cost_ctx));
-  memset(cost_ctx, 0, sizeof(*cost_ctx));
-  cost_ctx->values_count = 1;
-  cost_ctx->values =
-      gpr_malloc(sizeof(*cost_ctx->values) * cost_ctx->values_count);
-  cost_ctx->values[0] = grpc_slice_from_static_string("cost-token");
+  trailing_lr_metadata.key = GRPC_MDSTR_LB_COST_BIN;
+  trailing_lr_metadata.value = grpc_slice_from_static_string("server-token");
+  memset(&trailing_lr_metadata.internal_data, 0,
+         sizeof(trailing_lr_metadata.internal_data));
 
   request_response_with_payload(config, f, method_name, request_msg,
-                                response_msg, &initial_lr_metadata, cost_ctx);
+                                response_msg, &initial_lr_metadata,
+                                &trailing_lr_metadata);
   end_test(&f);
   {
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c
index e81a6289443b2195b049a5d13a205f2b5f6c542c..8ec92e476a36d8f4601ae831c36bee7828fc4362 100644
--- a/test/core/end2end/tests/max_concurrent_streams.c
+++ b/test/core/end2end/tests/max_concurrent_streams.c
@@ -57,24 +57,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -93,13 +96,13 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void simple_request_body(grpc_end2end_test_config config,
                                 grpc_end2end_test_fixture f) {
   grpc_call *c;
   grpc_call *s;
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -112,6 +115,7 @@ static void simple_request_body(grpc_end2end_test_config config,
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -197,8 +201,8 @@ static void simple_request_body(grpc_end2end_test_config config,
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 }
@@ -257,7 +261,7 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
 
   /* start two requests - ensuring that the second is not accepted until
      the first completes */
-  deadline = n_seconds_time(1000);
+  deadline = n_seconds_from_now(1000);
   c1 = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/alpha"),
@@ -429,10 +433,10 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
 
   cq_verifier_destroy(cqv);
 
-  grpc_call_destroy(c1);
-  grpc_call_destroy(s1);
-  grpc_call_destroy(c2);
-  grpc_call_destroy(s2);
+  grpc_call_unref(c1);
+  grpc_call_unref(s1);
+  grpc_call_unref(c2);
+  grpc_call_unref(s2);
 
   grpc_slice_unref(details1);
   grpc_slice_unref(details2);
@@ -502,13 +506,13 @@ static void test_max_concurrent_streams_with_timeout_on_first(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/alpha"),
       get_host_override_slice("foo.test.google.fr:1234", config),
-      n_seconds_time(3), NULL);
+      n_seconds_from_now(3), NULL);
   GPR_ASSERT(c1);
   c2 = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/beta"),
       get_host_override_slice("foo.test.google.fr:1234", config),
-      n_seconds_time(1000), NULL);
+      n_seconds_from_now(1000), NULL);
   GPR_ASSERT(c2);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(
@@ -624,10 +628,10 @@ static void test_max_concurrent_streams_with_timeout_on_first(
 
   cq_verifier_destroy(cqv);
 
-  grpc_call_destroy(c1);
-  grpc_call_destroy(s1);
-  grpc_call_destroy(c2);
-  grpc_call_destroy(s2);
+  grpc_call_unref(c1);
+  grpc_call_unref(s1);
+  grpc_call_unref(c2);
+  grpc_call_unref(s2);
 
   grpc_slice_unref(details1);
   grpc_slice_unref(details2);
@@ -697,13 +701,13 @@ static void test_max_concurrent_streams_with_timeout_on_second(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/alpha"),
       get_host_override_slice("foo.test.google.fr:1234", config),
-      n_seconds_time(1000), NULL);
+      n_seconds_from_now(1000), NULL);
   GPR_ASSERT(c1);
   c2 = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/beta"),
       get_host_override_slice("foo.test.google.fr:1234", config),
-      n_seconds_time(3), NULL);
+      n_seconds_from_now(3), NULL);
   GPR_ASSERT(c2);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(
@@ -785,7 +789,7 @@ static void test_max_concurrent_streams_with_timeout_on_second(
 
   /* second request is finished because of time out, so destroy the second call
    */
-  grpc_call_destroy(c2);
+  grpc_call_unref(c2);
 
   /* now reply the first call */
   memset(ops, 0, sizeof(ops));
@@ -817,8 +821,8 @@ static void test_max_concurrent_streams_with_timeout_on_second(
 
   cq_verifier_destroy(cqv);
 
-  grpc_call_destroy(c1);
-  grpc_call_destroy(s1);
+  grpc_call_unref(c1);
+  grpc_call_unref(s1);
 
   grpc_slice_unref(details1);
   grpc_slice_unref(details2);
diff --git a/test/core/end2end/tests/max_connection_age.c b/test/core/end2end/tests/max_connection_age.c
new file mode 100644
index 0000000000000000000000000000000000000000..c470dcda6923bea93554f3d1b2dad374a5ae3550
--- /dev/null
+++ b/test/core/end2end/tests/max_connection_age.c
@@ -0,0 +1,382 @@
+/*
+ *
+ * Copyright 2017, 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/core/end2end/end2end_tests.h"
+
+#include <limits.h>
+#include <string.h>
+
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+
+#include "test/core/end2end/cq_verifier.h"
+
+#define MAX_CONNECTION_AGE_MS 500
+#define MAX_CONNECTION_AGE_GRACE_MS 1000
+#define MAX_CONNECTION_IDLE_MS 9999
+
+#define MAX_CONNECTION_AGE_JITTER_MULTIPLIER 1.1
+#define CALL_DEADLINE_S 10
+/* The amount of time we wait for the connection to time out, but after it the
+   connection should not use up its grace period. It should be a number between
+   MAX_CONNECTION_AGE_MS and MAX_CONNECTION_AGE_MS +
+   MAX_CONNECTION_AGE_GRACE_MS */
+#define CQ_MAX_CONNECTION_AGE_WAIT_TIME_S 1
+/* The amount of time we wait after the connection reaches its max age, it
+   should be shorter than CALL_DEADLINE_S - CQ_MAX_CONNECTION_AGE_WAIT_TIME_S */
+#define CQ_MAX_CONNECTION_AGE_GRACE_WAIT_TIME_S 2
+/* The grace period for the test to observe the channel shutdown process */
+#define IMMEDIATE_SHUTDOWN_GRACE_TIME_MS 3000
+
+static void *tag(intptr_t t) { return (void *)t; }
+
+static void drain_cq(grpc_completion_queue *cq) {
+  grpc_event ev;
+  do {
+    ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5),
+                                    NULL);
+  } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture *f) {
+  if (!f->server) return;
+  grpc_server_destroy(f->server);
+  f->server = NULL;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture *f) {
+  if (!f->client) return;
+  grpc_channel_destroy(f->client);
+  f->client = NULL;
+}
+
+static void end_test(grpc_end2end_test_fixture *f) {
+  shutdown_server(f);
+  shutdown_client(f);
+
+  grpc_completion_queue_shutdown(f->cq);
+  drain_cq(f->cq);
+  grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+static void test_max_age_forcibly_close(grpc_end2end_test_config config) {
+  grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL);
+  cq_verifier *cqv = cq_verifier_create(f.cq);
+  grpc_arg server_a[] = {{.type = GRPC_ARG_INTEGER,
+                          .key = GRPC_ARG_MAX_CONNECTION_AGE_MS,
+                          .value.integer = MAX_CONNECTION_AGE_MS},
+                         {.type = GRPC_ARG_INTEGER,
+                          .key = GRPC_ARG_MAX_CONNECTION_AGE_GRACE_MS,
+                          .value.integer = MAX_CONNECTION_AGE_GRACE_MS},
+                         {.type = GRPC_ARG_INTEGER,
+                          .key = GRPC_ARG_MAX_CONNECTION_IDLE_MS,
+                          .value.integer = MAX_CONNECTION_IDLE_MS}};
+  grpc_channel_args server_args = {.num_args = GPR_ARRAY_SIZE(server_a),
+                                   .args = server_a};
+
+  config.init_client(&f, NULL);
+  config.init_server(&f, &server_args);
+
+  grpc_call *c;
+  grpc_call *s;
+  gpr_timespec deadline = grpc_timeout_seconds_to_deadline(CALL_DEADLINE_S);
+  grpc_op ops[6];
+  grpc_op *op;
+  grpc_metadata_array initial_metadata_recv;
+  grpc_metadata_array trailing_metadata_recv;
+  grpc_metadata_array request_metadata_recv;
+  grpc_call_details call_details;
+  grpc_status_code status;
+  grpc_call_error error;
+  grpc_slice details;
+  int was_cancelled = 2;
+
+  c = grpc_channel_create_call(
+      f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+      grpc_slice_from_static_string("/foo"),
+      get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+      NULL);
+  GPR_ASSERT(c);
+
+  grpc_metadata_array_init(&initial_metadata_recv);
+  grpc_metadata_array_init(&trailing_metadata_recv);
+  grpc_metadata_array_init(&request_metadata_recv);
+  grpc_call_details_init(&call_details);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op->data.send_initial_metadata.metadata = NULL;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_INITIAL_METADATA;
+  op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+  op->data.recv_status_on_client.status = &status;
+  op->data.recv_status_on_client.status_details = &details;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  error =
+      grpc_server_request_call(f.server, &s, &call_details,
+                               &request_metadata_recv, f.cq, f.cq, tag(101));
+  GPR_ASSERT(GRPC_CALL_OK == error);
+  CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+  cq_verify(cqv);
+
+  gpr_timespec expect_shutdown_time = grpc_timeout_milliseconds_to_deadline(
+      (int)(MAX_CONNECTION_AGE_MS * MAX_CONNECTION_AGE_JITTER_MULTIPLIER) +
+      MAX_CONNECTION_AGE_GRACE_MS + IMMEDIATE_SHUTDOWN_GRACE_TIME_MS);
+
+  /* Wait for the channel to reach its max age */
+  cq_verify_empty_timeout(cqv, CQ_MAX_CONNECTION_AGE_WAIT_TIME_S);
+
+  /* After the channel reaches its max age, we still do nothing here. And wait
+     for it to use up its max age grace period. */
+  CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+  cq_verify(cqv);
+
+  gpr_timespec channel_shutdown_time = gpr_now(GPR_CLOCK_MONOTONIC);
+  GPR_ASSERT(gpr_time_cmp(channel_shutdown_time, expect_shutdown_time) < 0);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+  op->data.send_status_from_server.trailing_metadata_count = 0;
+  op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
+  grpc_slice status_details = grpc_slice_from_static_string("xyz");
+  op->data.send_status_from_server.status_details = &status_details;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+  op->data.recv_close_on_server.cancelled = &was_cancelled;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+  CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+  cq_verify(cqv);
+
+  grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead));
+  CQ_EXPECT_COMPLETION(cqv, tag(0xdead), true);
+  cq_verify(cqv);
+
+  grpc_call_unref(s);
+
+  /* The connection should be closed immediately after the max age grace period,
+     the in-progress RPC should fail. */
+  GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
+  GPR_ASSERT(0 == grpc_slice_str_cmp(details, "Endpoint read failed"));
+  GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
+  validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+                                config);
+  GPR_ASSERT(was_cancelled == 1);
+
+  grpc_slice_unref(details);
+  grpc_metadata_array_destroy(&initial_metadata_recv);
+  grpc_metadata_array_destroy(&trailing_metadata_recv);
+  grpc_metadata_array_destroy(&request_metadata_recv);
+  grpc_call_details_destroy(&call_details);
+  grpc_call_unref(c);
+  cq_verifier_destroy(cqv);
+  end_test(&f);
+  config.tear_down_data(&f);
+}
+
+static void test_max_age_gracefully_close(grpc_end2end_test_config config) {
+  grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL);
+  cq_verifier *cqv = cq_verifier_create(f.cq);
+  grpc_arg server_a[] = {{.type = GRPC_ARG_INTEGER,
+                          .key = GRPC_ARG_MAX_CONNECTION_AGE_MS,
+                          .value.integer = MAX_CONNECTION_AGE_MS},
+                         {.type = GRPC_ARG_INTEGER,
+                          .key = GRPC_ARG_MAX_CONNECTION_AGE_GRACE_MS,
+                          .value.integer = INT_MAX},
+                         {.type = GRPC_ARG_INTEGER,
+                          .key = GRPC_ARG_MAX_CONNECTION_IDLE_MS,
+                          .value.integer = MAX_CONNECTION_IDLE_MS}};
+  grpc_channel_args server_args = {.num_args = GPR_ARRAY_SIZE(server_a),
+                                   .args = server_a};
+
+  config.init_client(&f, NULL);
+  config.init_server(&f, &server_args);
+
+  grpc_call *c;
+  grpc_call *s;
+  gpr_timespec deadline = grpc_timeout_seconds_to_deadline(CALL_DEADLINE_S);
+  grpc_op ops[6];
+  grpc_op *op;
+  grpc_metadata_array initial_metadata_recv;
+  grpc_metadata_array trailing_metadata_recv;
+  grpc_metadata_array request_metadata_recv;
+  grpc_call_details call_details;
+  grpc_status_code status;
+  grpc_call_error error;
+  grpc_slice details;
+  int was_cancelled = 2;
+
+  c = grpc_channel_create_call(
+      f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+      grpc_slice_from_static_string("/foo"),
+      get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+      NULL);
+  GPR_ASSERT(c);
+
+  grpc_metadata_array_init(&initial_metadata_recv);
+  grpc_metadata_array_init(&trailing_metadata_recv);
+  grpc_metadata_array_init(&request_metadata_recv);
+  grpc_call_details_init(&call_details);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op->data.send_initial_metadata.metadata = NULL;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_INITIAL_METADATA;
+  op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+  op->data.recv_status_on_client.status = &status;
+  op->data.recv_status_on_client.status_details = &details;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  error =
+      grpc_server_request_call(f.server, &s, &call_details,
+                               &request_metadata_recv, f.cq, f.cq, tag(101));
+  GPR_ASSERT(GRPC_CALL_OK == error);
+  CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+  cq_verify(cqv);
+
+  /* Wait for the channel to reach its max age */
+  cq_verify_empty_timeout(cqv, CQ_MAX_CONNECTION_AGE_WAIT_TIME_S);
+
+  /* The connection is shutting down gracefully. In-progress rpc should not be
+     closed, hence the completion queue should see nothing here. */
+  cq_verify_empty_timeout(cqv, CQ_MAX_CONNECTION_AGE_GRACE_WAIT_TIME_S);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+  op->data.send_status_from_server.trailing_metadata_count = 0;
+  op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
+  grpc_slice status_details = grpc_slice_from_static_string("xyz");
+  op->data.send_status_from_server.status_details = &status_details;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+  op->data.recv_close_on_server.cancelled = &was_cancelled;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+  CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+  cq_verify(cqv);
+
+  grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead));
+  CQ_EXPECT_COMPLETION(cqv, tag(0xdead), true);
+  cq_verify(cqv);
+
+  grpc_call_unref(s);
+
+  /* The connection is closed gracefully with goaway, the rpc should still be
+     completed. */
+  GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
+  GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+  GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
+  validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+                                config);
+  GPR_ASSERT(was_cancelled == 1);
+
+  grpc_slice_unref(details);
+  grpc_metadata_array_destroy(&initial_metadata_recv);
+  grpc_metadata_array_destroy(&trailing_metadata_recv);
+  grpc_metadata_array_destroy(&request_metadata_recv);
+  grpc_call_details_destroy(&call_details);
+  grpc_call_unref(c);
+  cq_verifier_destroy(cqv);
+  end_test(&f);
+  config.tear_down_data(&f);
+}
+
+void max_connection_age(grpc_end2end_test_config config) {
+  test_max_age_forcibly_close(config);
+  test_max_age_gracefully_close(config);
+}
+
+void max_connection_age_pre_init(void) {}
diff --git a/test/core/end2end/tests/max_connection_idle.c b/test/core/end2end/tests/max_connection_idle.c
new file mode 100644
index 0000000000000000000000000000000000000000..488d945123a44952eeaf6369cf321508909a81db
--- /dev/null
+++ b/test/core/end2end/tests/max_connection_idle.c
@@ -0,0 +1,255 @@
+/*
+ *
+ * Copyright 2017, 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/core/end2end/end2end_tests.h"
+
+#include <limits.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+
+#include "test/core/end2end/cq_verifier.h"
+
+#define MAX_CONNECTION_IDLE_MS 500
+#define MAX_CONNECTION_AGE_MS 9999
+
+static void *tag(intptr_t t) { return (void *)t; }
+
+static void drain_cq(grpc_completion_queue *cq) {
+  grpc_event ev;
+  do {
+    ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5),
+                                    NULL);
+  } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void simple_request_body(grpc_end2end_test_config config,
+                                grpc_end2end_test_fixture *f) {
+  grpc_call *c;
+  grpc_call *s;
+  cq_verifier *cqv = cq_verifier_create(f->cq);
+  grpc_op ops[6];
+  grpc_op *op;
+  grpc_metadata_array initial_metadata_recv;
+  grpc_metadata_array trailing_metadata_recv;
+  grpc_metadata_array request_metadata_recv;
+  grpc_call_details call_details;
+  grpc_status_code status;
+  grpc_call_error error;
+  grpc_slice details;
+  int was_cancelled = 2;
+  char *peer;
+
+  gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
+  c = grpc_channel_create_call(
+      f->client, NULL, GRPC_PROPAGATE_DEFAULTS, f->cq,
+      grpc_slice_from_static_string("/foo"),
+      get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+      NULL);
+  GPR_ASSERT(c);
+
+  peer = grpc_call_get_peer(c);
+  GPR_ASSERT(peer != NULL);
+  gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+  gpr_free(peer);
+
+  grpc_metadata_array_init(&initial_metadata_recv);
+  grpc_metadata_array_init(&trailing_metadata_recv);
+  grpc_metadata_array_init(&request_metadata_recv);
+  grpc_call_details_init(&call_details);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_INITIAL_METADATA;
+  op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+  op->data.recv_status_on_client.status = &status;
+  op->data.recv_status_on_client.status_details = &details;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  error =
+      grpc_server_request_call(f->server, &s, &call_details,
+                               &request_metadata_recv, f->cq, f->cq, tag(101));
+  GPR_ASSERT(GRPC_CALL_OK == error);
+  CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
+  cq_verify(cqv);
+
+  peer = grpc_call_get_peer(s);
+  GPR_ASSERT(peer != NULL);
+  gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+  gpr_free(peer);
+  peer = grpc_call_get_peer(c);
+  GPR_ASSERT(peer != NULL);
+  gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+  gpr_free(peer);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+  op->data.send_status_from_server.trailing_metadata_count = 0;
+  op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
+  grpc_slice status_details = grpc_slice_from_static_string("xyz");
+  op->data.send_status_from_server.status_details = &status_details;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+  op->data.recv_close_on_server.cancelled = &was_cancelled;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
+  CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
+  cq_verify(cqv);
+
+  GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
+  GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+  GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
+  validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+                                config);
+  GPR_ASSERT(0 == call_details.flags);
+  GPR_ASSERT(was_cancelled == 1);
+
+  grpc_slice_unref(details);
+  grpc_metadata_array_destroy(&initial_metadata_recv);
+  grpc_metadata_array_destroy(&trailing_metadata_recv);
+  grpc_metadata_array_destroy(&request_metadata_recv);
+  grpc_call_details_destroy(&call_details);
+
+  grpc_call_unref(c);
+  grpc_call_unref(s);
+
+  cq_verifier_destroy(cqv);
+}
+
+static void test_max_connection_idle(grpc_end2end_test_config config) {
+  grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL);
+  grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
+  cq_verifier *cqv = cq_verifier_create(f.cq);
+
+  grpc_arg client_a[] = {{.type = GRPC_ARG_INTEGER,
+                          .key = "grpc.testing.fixed_reconnect_backoff_ms",
+                          .value.integer = 1000}};
+  grpc_arg server_a[] = {{.type = GRPC_ARG_INTEGER,
+                          .key = GRPC_ARG_MAX_CONNECTION_IDLE_MS,
+                          .value.integer = MAX_CONNECTION_IDLE_MS},
+                         {.type = GRPC_ARG_INTEGER,
+                          .key = GRPC_ARG_MAX_CONNECTION_AGE_MS,
+                          .value.integer = MAX_CONNECTION_AGE_MS}};
+  grpc_channel_args client_args = {.num_args = GPR_ARRAY_SIZE(client_a),
+                                   .args = client_a};
+  grpc_channel_args server_args = {.num_args = GPR_ARRAY_SIZE(server_a),
+                                   .args = server_a};
+
+  config.init_client(&f, &client_args);
+  config.init_server(&f, &server_args);
+
+  /* check that we're still in idle, and start connecting */
+  GPR_ASSERT(grpc_channel_check_connectivity_state(f.client, 1) ==
+             GRPC_CHANNEL_IDLE);
+  /* we'll go through some set of transitions (some might be missed), until
+     READY is reached */
+  while (state != GRPC_CHANNEL_READY) {
+    grpc_channel_watch_connectivity_state(
+        f.client, state, grpc_timeout_seconds_to_deadline(3), f.cq, tag(99));
+    CQ_EXPECT_COMPLETION(cqv, tag(99), 1);
+    cq_verify(cqv);
+    state = grpc_channel_check_connectivity_state(f.client, 0);
+    GPR_ASSERT(state == GRPC_CHANNEL_READY ||
+               state == GRPC_CHANNEL_CONNECTING ||
+               state == GRPC_CHANNEL_TRANSIENT_FAILURE);
+  }
+
+  /* Use a simple request to cancel and reset the max idle timer */
+  simple_request_body(config, &f);
+
+  /* wait for the channel to reach its maximum idle time */
+  grpc_channel_watch_connectivity_state(
+      f.client, GRPC_CHANNEL_READY,
+      grpc_timeout_milliseconds_to_deadline(MAX_CONNECTION_IDLE_MS + 3000),
+      f.cq, tag(99));
+  CQ_EXPECT_COMPLETION(cqv, tag(99), 1);
+  cq_verify(cqv);
+  state = grpc_channel_check_connectivity_state(f.client, 0);
+  GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
+             state == GRPC_CHANNEL_CONNECTING || state == GRPC_CHANNEL_IDLE);
+
+  grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead));
+  CQ_EXPECT_COMPLETION(cqv, tag(0xdead), 1);
+  cq_verify(cqv);
+
+  grpc_server_destroy(f.server);
+  grpc_channel_destroy(f.client);
+  grpc_completion_queue_shutdown(f.cq);
+  drain_cq(f.cq);
+  grpc_completion_queue_destroy(f.cq);
+  grpc_completion_queue_destroy(f.shutdown_cq);
+  config.tear_down_data(&f);
+
+  cq_verifier_destroy(cqv);
+}
+
+void max_connection_idle(grpc_end2end_test_config config) {
+  test_max_connection_idle(config);
+}
+
+void max_connection_idle_pre_init(void) {}
diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c
index b15d30f58c4c02611cfe07eef35fb725c047a562..f65edab86573a87c5768cbc7ae32a2ba0849596b 100644
--- a/test/core/end2end/tests/max_message_length.c
+++ b/test/core/end2end/tests/max_message_length.c
@@ -66,24 +66,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -102,6 +105,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 // Test with request larger than the limit.
@@ -270,7 +274,7 @@ static void test_max_message_length_on_request(grpc_end2end_test_config config,
   GPR_ASSERT(was_cancelled == 1);
 
 done:
-  GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT);
+  GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED);
   GPR_ASSERT(
       grpc_slice_str_cmp(
           details, send_limit
@@ -285,8 +289,8 @@ done:
   grpc_byte_buffer_destroy(request_payload);
   grpc_byte_buffer_destroy(recv_payload);
 
-  grpc_call_destroy(c);
-  if (s != NULL) grpc_call_destroy(s);
+  grpc_call_unref(c);
+  if (s != NULL) grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
@@ -464,7 +468,7 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config,
   GPR_ASSERT(0 ==
              grpc_slice_str_cmp(call_details.host, "foo.test.google.fr:1234"));
 
-  GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT);
+  GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED);
   GPR_ASSERT(
       grpc_slice_str_cmp(
           details, send_limit
@@ -479,8 +483,8 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config,
   grpc_byte_buffer_destroy(response_payload);
   grpc_byte_buffer_destroy(recv_payload);
 
-  grpc_call_destroy(c);
-  if (s != NULL) grpc_call_destroy(s);
+  grpc_call_unref(c);
+  if (s != NULL) grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/negative_deadline.c b/test/core/end2end/tests/negative_deadline.c
index 0b61efbac97972c1945a76370479fddeba1caab1..113b650a9749edaac719ffa7a87029aab722469c 100644
--- a/test/core/end2end/tests/negative_deadline.c
+++ b/test/core/end2end/tests/negative_deadline.c
@@ -59,24 +59,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -95,12 +98,12 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void simple_request_body(grpc_end2end_test_config config,
                                 grpc_end2end_test_fixture f, size_t num_ops) {
   grpc_call *c;
-  gpr_timespec deadline = gpr_inf_past(GPR_CLOCK_REALTIME);
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -112,6 +115,7 @@ static void simple_request_body(grpc_end2end_test_config config,
 
   gpr_log(GPR_DEBUG, "test with %" PRIuPTR " ops", num_ops);
 
+  gpr_timespec deadline = gpr_inf_past(GPR_CLOCK_REALTIME);
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -158,7 +162,7 @@ static void simple_request_body(grpc_end2end_test_config config,
   grpc_metadata_array_destroy(&initial_metadata_recv);
   grpc_metadata_array_destroy(&trailing_metadata_recv);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
 
   cq_verifier_destroy(cqv);
 }
diff --git a/test/core/end2end/tests/network_status_change.c b/test/core/end2end/tests/network_status_change.c
index 7540ce93a1b18746f98824a13848a249b3a8f0d9..1ea4be81b1e71bf3a3b70a76e7bed833abaf278b 100644
--- a/test/core/end2end/tests/network_status_change.c
+++ b/test/core/end2end/tests/network_status_change.c
@@ -60,24 +60,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(500); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(500);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -96,6 +99,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Client sends a request with payload, server reads then returns status. */
@@ -106,7 +110,6 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) {
       grpc_slice_from_copied_string("hello world");
   grpc_byte_buffer *request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
   grpc_end2end_test_fixture f =
       begin_test(config, "test_invoke_request_with_payload", NULL, NULL);
   cq_verifier *cqv = cq_verifier_create(f.cq);
@@ -122,6 +125,7 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) {
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -227,8 +231,8 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) {
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
@@ -240,6 +244,10 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) {
 }
 
 void network_status_change(grpc_end2end_test_config config) {
+  if (config.feature_mask &
+      FEATURE_MASK_DOES_NOT_SUPPORT_NETWORK_STATUS_CHANGE) {
+    return;
+  }
   test_invoke_network_status_change(config);
 }
 
diff --git a/test/core/end2end/tests/no_logging.c b/test/core/end2end/tests/no_logging.c
index 56e48a88a879572d29f3adeac5fb2b91dffaa09b..17b6886f2cb993ed2236ec71bf2a4a2deef223d8 100644
--- a/test/core/end2end/tests/no_logging.c
+++ b/test/core/end2end/tests/no_logging.c
@@ -87,24 +87,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -123,13 +126,13 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void simple_request_body(grpc_end2end_test_config config,
                                 grpc_end2end_test_fixture f) {
   grpc_call *c;
   grpc_call *s;
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -143,6 +146,7 @@ static void simple_request_body(grpc_end2end_test_config config,
   int was_cancelled = 2;
   char *peer;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -240,8 +244,8 @@ static void simple_request_body(grpc_end2end_test_config config,
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 }
diff --git a/test/core/end2end/tests/no_op.c b/test/core/end2end/tests/no_op.c
index 62fc728c3ebe668b54a0a251b277864ba3de968b..0d98fc9c0a6f52d20c2faafb32038e2a3b6138aa 100644
--- a/test/core/end2end/tests/no_op.c
+++ b/test/core/end2end/tests/no_op.c
@@ -57,24 +57,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -93,6 +96,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void test_no_op(grpc_end2end_test_config config) {
diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c
index b04ee5705c6ec3dfa4f1541fda7289265f9b93cc..3f25ecb8ff60759f9c88c4b637b8555c4b260799 100644
--- a/test/core/end2end/tests/payload.c
+++ b/test/core/end2end/tests/payload.c
@@ -57,24 +57,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -93,6 +96,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Creates and returns a grpc_slice containing random alphanumeric characters.
@@ -126,7 +130,6 @@ static void request_response_with_payload(grpc_end2end_test_config config,
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
   grpc_byte_buffer *response_payload =
       grpc_raw_byte_buffer_create(&response_payload_slice, 1);
-  gpr_timespec deadline = n_seconds_time(60);
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -141,6 +144,7 @@ static void request_response_with_payload(grpc_end2end_test_config config,
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = n_seconds_from_now(60);
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -257,8 +261,8 @@ static void request_response_with_payload(grpc_end2end_test_config config,
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/ping.c b/test/core/end2end/tests/ping.c
index f5bfac2255c8c69d87485640dab4a666af3d3f71..027c17ea4c92d2880fecf8ce81b88bd07833107d 100644
--- a/test/core/end2end/tests/ping.c
+++ b/test/core/end2end/tests/ping.c
@@ -41,24 +41,37 @@
 
 #include "test/core/end2end/cq_verifier.h"
 
+#define PING_NUM 5
+
 static void *tag(intptr_t t) { return (void *)t; }
 
-static void test_ping(grpc_end2end_test_config config) {
+static void test_ping(grpc_end2end_test_config config,
+                      int min_time_between_pings_ms) {
   grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL);
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
   int i;
 
-  grpc_arg a[] = {{.type = GRPC_ARG_INTEGER,
-                   .key = GRPC_ARG_HTTP2_MIN_TIME_BETWEEN_PINGS_MS,
-                   .value.integer = 0},
-                  {.type = GRPC_ARG_INTEGER,
-                   .key = GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA,
-                   .value.integer = 20}};
-  grpc_channel_args client_args = {.num_args = GPR_ARRAY_SIZE(a), .args = a};
+  grpc_arg client_a[] = {{.type = GRPC_ARG_INTEGER,
+                          .key = GRPC_ARG_HTTP2_MIN_TIME_BETWEEN_PINGS_MS,
+                          .value.integer = 0},
+                         {.type = GRPC_ARG_INTEGER,
+                          .key = GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA,
+                          .value.integer = 20}};
+  grpc_arg server_a[] = {
+      {.type = GRPC_ARG_INTEGER,
+       .key = GRPC_ARG_HTTP2_MIN_PING_INTERVAL_WITHOUT_DATA_MS,
+       .value.integer = 0},
+      {.type = GRPC_ARG_INTEGER,
+       .key = GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS,
+       .value.integer = 1}};
+  grpc_channel_args client_args = {.num_args = GPR_ARRAY_SIZE(client_a),
+                                   .args = client_a};
+  grpc_channel_args server_args = {.num_args = GPR_ARRAY_SIZE(server_a),
+                                   .args = server_a};
 
   config.init_client(&f, &client_args);
-  config.init_server(&f, NULL);
+  config.init_server(&f, &server_args);
 
   grpc_channel_ping(f.client, f.cq, tag(0), NULL);
   CQ_EXPECT_COMPLETION(cqv, tag(0), 0);
@@ -70,7 +83,11 @@ static void test_ping(grpc_end2end_test_config config) {
      READY is reached */
   while (state != GRPC_CHANNEL_READY) {
     grpc_channel_watch_connectivity_state(
-        f.client, state, grpc_timeout_seconds_to_deadline(3), f.cq, tag(99));
+        f.client, state,
+        gpr_time_add(grpc_timeout_seconds_to_deadline(3),
+                     gpr_time_from_millis(min_time_between_pings_ms * PING_NUM,
+                                          GPR_TIMESPAN)),
+        f.cq, tag(99));
     CQ_EXPECT_COMPLETION(cqv, tag(99), 1);
     cq_verify(cqv);
     state = grpc_channel_check_connectivity_state(f.client, 0);
@@ -79,7 +96,7 @@ static void test_ping(grpc_end2end_test_config config) {
                state == GRPC_CHANNEL_TRANSIENT_FAILURE);
   }
 
-  for (i = 1; i <= 5; i++) {
+  for (i = 1; i <= PING_NUM; i++) {
     grpc_channel_ping(f.client, f.cq, tag(i), NULL);
     CQ_EXPECT_COMPLETION(cqv, tag(i), 1);
     cq_verify(cqv);
@@ -95,6 +112,9 @@ static void test_ping(grpc_end2end_test_config config) {
   grpc_channel_destroy(f.client);
   grpc_completion_queue_shutdown(f.cq);
   grpc_completion_queue_destroy(f.cq);
+
+  /* f.shutdown_cq is not used in this test */
+  grpc_completion_queue_destroy(f.shutdown_cq);
   config.tear_down_data(&f);
 
   cq_verifier_destroy(cqv);
@@ -102,7 +122,8 @@ static void test_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);
+  test_ping(config, 0);
+  test_ping(config, 100);
 }
 
 void ping_pre_init(void) {}
diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c
index 848f76018d1c65ac78a4a4cf12ee5cb260052534..598e45ee33fee76d55ec698f55bc92d41613f62a 100644
--- a/test/core/end2end/tests/ping_pong_streaming.c
+++ b/test/core/end2end/tests/ping_pong_streaming.c
@@ -57,24 +57,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -93,6 +96,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Client pings and server pongs. Repeat messages rounds before finishing. */
@@ -102,7 +106,6 @@ static void test_pingpong_streaming(grpc_end2end_test_config config,
       begin_test(config, "test_pingpong_streaming", NULL, NULL);
   grpc_call *c;
   grpc_call *s;
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -124,6 +127,7 @@ static void test_pingpong_streaming(grpc_end2end_test_config config,
   grpc_slice response_payload_slice =
       grpc_slice_from_copied_string("hello you");
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -261,8 +265,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config,
   CQ_EXPECT_COMPLETION(cqv, tag(104), 1);
   cq_verify(cqv);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/registered_call.c b/test/core/end2end/tests/registered_call.c
index 9c8ce89c838733033483cb1ffc92882c842b664b..7e07a7129c27f3515ed42fb72e3fc1517e38a32c 100644
--- a/test/core/end2end/tests/registered_call.c
+++ b/test/core/end2end/tests/registered_call.c
@@ -59,24 +59,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -95,13 +98,13 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void simple_request_body(grpc_end2end_test_config config,
                                 grpc_end2end_test_fixture f, void *rc) {
   grpc_call *c;
   grpc_call *s;
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -114,6 +117,7 @@ static void simple_request_body(grpc_end2end_test_config config,
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_registered_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, rc, deadline, NULL);
   GPR_ASSERT(c);
@@ -196,8 +200,8 @@ static void simple_request_body(grpc_end2end_test_config config,
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 }
diff --git a/test/core/end2end/tests/request_with_flags.c b/test/core/end2end/tests/request_with_flags.c
index 329359e08b8f1908bf59d0df2bf199227caff5cc..daf15fa5f7218ed2c1a9b4b3d9018dbcbef419c5 100644
--- a/test/core/end2end/tests/request_with_flags.c
+++ b/test/core/end2end/tests/request_with_flags.c
@@ -58,24 +58,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -94,6 +97,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void test_invoke_request_with_flags(
@@ -104,7 +108,6 @@ static void test_invoke_request_with_flags(
       grpc_slice_from_copied_string("hello world");
   grpc_byte_buffer *request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
   grpc_end2end_test_fixture f =
       begin_test(config, "test_invoke_request_with_flags", NULL, NULL);
   cq_verifier *cqv = cq_verifier_create(f.cq);
@@ -120,6 +123,7 @@ static void test_invoke_request_with_flags(
   grpc_slice details;
   grpc_call_error expectation;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -175,7 +179,7 @@ static void test_invoke_request_with_flags(
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c
index f71f92bbb84c89889e643baa0fb43a3de140afde..43686d58abec627d2e86e33fad048589c90e49ed 100644
--- a/test/core/end2end/tests/request_with_payload.c
+++ b/test/core/end2end/tests/request_with_payload.c
@@ -57,24 +57,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -93,6 +96,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Client sends a request with payload, server reads then returns status. */
@@ -103,7 +107,6 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
       grpc_slice_from_copied_string("hello world");
   grpc_byte_buffer *request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
   grpc_end2end_test_fixture f =
       begin_test(config, "test_invoke_request_with_payload", NULL, NULL);
   cq_verifier *cqv = cq_verifier_create(f.cq);
@@ -119,6 +122,7 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -222,8 +226,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/resource_quota_server.c b/test/core/end2end/tests/resource_quota_server.c
index 4f9ed7a3a17bd65c704ae7bd583421c7e9f1bbb0..6418f5d01ade6683170fdf7a7981bd1a2d44a89d 100644
--- a/test/core/end2end/tests/resource_quota_server.c
+++ b/test/core/end2end/tests/resource_quota_server.c
@@ -57,24 +57,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -93,6 +96,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Creates and returns a grpc_slice containing random alphanumeric characters.
@@ -113,6 +117,10 @@ static grpc_slice generate_random_slice() {
 }
 
 void resource_quota_server(grpc_end2end_test_config config) {
+  if (config.feature_mask &
+      FEATURE_MASK_DOES_NOT_SUPPORT_RESOURCE_QUOTA_SERVER) {
+    return;
+  }
   grpc_resource_quota *resource_quota =
       grpc_resource_quota_create("test_server");
   grpc_resource_quota_resize(resource_quota, 5 * 1024 * 1024);
@@ -161,6 +169,7 @@ void resource_quota_server(grpc_end2end_test_config config) {
   int cancelled_calls_on_client = 0;
   int cancelled_calls_on_server = 0;
   int deadline_exceeded = 0;
+  int unavailable = 0;
 
   grpc_byte_buffer *request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
@@ -191,13 +200,13 @@ void resource_quota_server(grpc_end2end_test_config config) {
         f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
         grpc_slice_from_static_string("/foo"),
         get_host_override_slice("foo.test.google.fr", config),
-        n_seconds_time(60), NULL);
+        n_seconds_from_now(60), NULL);
 
     memset(ops, 0, sizeof(ops));
     op = ops;
     op->op = GRPC_OP_SEND_INITIAL_METADATA;
     op->data.send_initial_metadata.count = 0;
-    op->flags = 0;
+    op->flags = GRPC_INITIAL_METADATA_WAIT_FOR_READY;
     op->reserved = NULL;
     op++;
     op->op = GRPC_OP_SEND_MESSAGE;
@@ -233,7 +242,8 @@ void resource_quota_server(grpc_end2end_test_config config) {
   while (pending_client_calls + pending_server_recv_calls +
              pending_server_end_calls >
          0) {
-    grpc_event ev = grpc_completion_queue_next(f.cq, n_seconds_time(60), NULL);
+    grpc_event ev =
+        grpc_completion_queue_next(f.cq, n_seconds_from_now(60), NULL);
     GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
 
     int ev_tag = (int)(intptr_t)ev.tag;
@@ -251,6 +261,9 @@ void resource_quota_server(grpc_end2end_test_config config) {
         case GRPC_STATUS_DEADLINE_EXCEEDED:
           deadline_exceeded++;
           break;
+        case GRPC_STATUS_UNAVAILABLE:
+          unavailable++;
+          break;
         case GRPC_STATUS_OK:
           break;
         default:
@@ -261,7 +274,7 @@ void resource_quota_server(grpc_end2end_test_config config) {
 
       grpc_metadata_array_destroy(&initial_metadata_recv[call_id]);
       grpc_metadata_array_destroy(&trailing_metadata_recv[call_id]);
-      grpc_call_destroy(client_calls[call_id]);
+      grpc_call_unref(client_calls[call_id]);
       grpc_slice_unref(details[call_id]);
 
       pending_client_calls--;
@@ -343,15 +356,15 @@ void resource_quota_server(grpc_end2end_test_config config) {
       GPR_ASSERT(pending_server_end_calls > 0);
       pending_server_end_calls--;
 
-      grpc_call_destroy(server_calls[call_id]);
+      grpc_call_unref(server_calls[call_id]);
     }
   }
 
   gpr_log(GPR_INFO,
           "Done. %d total calls: %d cancelled at server, %d cancelled at "
-          "client, %d timed out.",
+          "client, %d timed out, %d unavailable.",
           NUM_CALLS, cancelled_calls_on_server, cancelled_calls_on_client,
-          deadline_exceeded);
+          deadline_exceeded, unavailable);
 
   grpc_byte_buffer_destroy(request_payload);
   grpc_slice_unref(request_payload_slice);
diff --git a/test/core/end2end/tests/server_finishes_request.c b/test/core/end2end/tests/server_finishes_request.c
index b42d17002e8f891d7f21ab41b377abf38a3d013b..be0901bfdd8c606f2398cbe10933592a39850dfb 100644
--- a/test/core/end2end/tests/server_finishes_request.c
+++ b/test/core/end2end/tests/server_finishes_request.c
@@ -59,24 +59,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -95,13 +98,13 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void simple_request_body(grpc_end2end_test_config config,
                                 grpc_end2end_test_fixture f) {
   grpc_call *c;
   grpc_call *s;
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -114,6 +117,7 @@ static void simple_request_body(grpc_end2end_test_config config,
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -195,8 +199,8 @@ static void simple_request_body(grpc_end2end_test_config config,
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 }
diff --git a/test/core/end2end/tests/shutdown_finishes_calls.c b/test/core/end2end/tests/shutdown_finishes_calls.c
index c019682ea66fca22199a065d798e6bc7d80fbc07..d19af1a74df0256ac6da64a01466a7aebd02c9da 100644
--- a/test/core/end2end/tests/shutdown_finishes_calls.c
+++ b/test/core/end2end/tests/shutdown_finishes_calls.c
@@ -57,16 +57,18 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
@@ -82,13 +84,14 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  /* f->shutdown_cq is not used in this test */
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void test_early_server_shutdown_finishes_inflight_calls(
     grpc_end2end_test_config config) {
   grpc_call *c;
   grpc_call *s;
-  gpr_timespec deadline = five_seconds_time();
   grpc_end2end_test_fixture f = begin_test(
       config, "test_early_server_shutdown_finishes_inflight_calls", NULL, NULL);
   cq_verifier *cqv = cq_verifier_create(f.cq);
@@ -103,6 +106,7 @@ static void test_early_server_shutdown_finishes_inflight_calls(
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -182,8 +186,8 @@ static void test_early_server_shutdown_finishes_inflight_calls(
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/shutdown_finishes_tags.c b/test/core/end2end/tests/shutdown_finishes_tags.c
index 5540d2aab9c2a1def6f6fb19b8ace1274f9a0819..008f72e6f48514e13fabd8c48511e3f26c882c9c 100644
--- a/test/core/end2end/tests/shutdown_finishes_tags.c
+++ b/test/core/end2end/tests/shutdown_finishes_tags.c
@@ -57,16 +57,18 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
@@ -82,6 +84,8 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  /* f->shutdown_cq is not used in this test */
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void test_early_server_shutdown_finishes_tags(
diff --git a/test/core/end2end/tests/simple_cacheable_request.c b/test/core/end2end/tests/simple_cacheable_request.c
index 4eef02e9eed93b82c90d14c9041d39ff22a12ed1..cc0f89c422ea5b77ac8b971f386ae21d889b71a9 100644
--- a/test/core/end2end/tests/simple_cacheable_request.c
+++ b/test/core/end2end/tests/simple_cacheable_request.c
@@ -59,24 +59,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -95,6 +98,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Request/response with metadata and payload.*/
@@ -110,7 +114,6 @@ static void test_cacheable_request_response_with_metadata_and_payload(
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
   grpc_byte_buffer *response_payload =
       grpc_raw_byte_buffer_create(&response_payload_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
   grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"),
                               grpc_slice_from_static_string("val1"),
                               0,
@@ -144,6 +147,7 @@ static void test_cacheable_request_response_with_metadata_and_payload(
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -270,8 +274,8 @@ static void test_cacheable_request_response_with_metadata_and_payload(
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c
index e3b6aee783eac03fa00aeaffbcb2404d20fae813..9e938f86a6cf1fdc6d19ba351874c7f9a7d50239 100644
--- a/test/core/end2end/tests/simple_delayed_request.c
+++ b/test/core/end2end/tests/simple_delayed_request.c
@@ -45,24 +45,27 @@
 
 static void *tag(intptr_t t) { return (void *)t; }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -81,6 +84,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void simple_delayed_request_body(grpc_end2end_test_config config,
@@ -90,7 +94,6 @@ static void simple_delayed_request_body(grpc_end2end_test_config config,
                                         long delay_us) {
   grpc_call *c;
   grpc_call *s;
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f->cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -106,6 +109,7 @@ static void simple_delayed_request_body(grpc_end2end_test_config config,
   config.init_client(f, client_args);
   config.init_server(f, server_args);
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f->client, NULL, GRPC_PROPAGATE_DEFAULTS, f->cq,
       grpc_slice_from_static_string("/foo"),
@@ -191,8 +195,8 @@ static void simple_delayed_request_body(grpc_end2end_test_config config,
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 }
diff --git a/test/core/end2end/tests/simple_metadata.c b/test/core/end2end/tests/simple_metadata.c
index 7ab5563cfa9501c1888c63c1d76617a07e871f13..08679a588a29754d9adf00682352bc609c6da29a 100644
--- a/test/core/end2end/tests/simple_metadata.c
+++ b/test/core/end2end/tests/simple_metadata.c
@@ -57,24 +57,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -93,6 +96,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Request/response with metadata and payload.*/
@@ -108,7 +112,6 @@ static void test_request_response_with_metadata_and_payload(
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
   grpc_byte_buffer *response_payload =
       grpc_raw_byte_buffer_create(&response_payload_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
   grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"),
                               grpc_slice_from_static_string("val1"),
                               0,
@@ -141,6 +144,7 @@ static void test_request_response_with_metadata_and_payload(
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -262,8 +266,8 @@ static void test_request_response_with_metadata_and_payload(
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c
index af5d74959e38d515c2c2146916c29735948573e8..45c717363bfb96351be099270736763431b8c81a 100644
--- a/test/core/end2end/tests/simple_request.c
+++ b/test/core/end2end/tests/simple_request.c
@@ -59,24 +59,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -95,13 +98,13 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 static void simple_request_body(grpc_end2end_test_config config,
                                 grpc_end2end_test_fixture f) {
   grpc_call *c;
   grpc_call *s;
-  gpr_timespec deadline = five_seconds_time();
   cq_verifier *cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op *op;
@@ -115,6 +118,7 @@ static void simple_request_body(grpc_end2end_test_config config,
   int was_cancelled = 2;
   char *peer;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -215,8 +219,8 @@ static void simple_request_body(grpc_end2end_test_config config,
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 }
diff --git a/test/core/end2end/tests/streaming_error_response.c b/test/core/end2end/tests/streaming_error_response.c
index 42055907c85f2e28e15acab49be69322c4c2c6ad..e59675a655062089f0bb544298e9bda9d7499dcf 100644
--- a/test/core/end2end/tests/streaming_error_response.c
+++ b/test/core/end2end/tests/streaming_error_response.c
@@ -31,6 +31,9 @@
  *
  */
 
+/** \file Verify that status ordering rules are obeyed.
+    \ref doc/status_ordering.md */
+
 #include "test/core/end2end/end2end_tests.h"
 
 #include <stdio.h>
@@ -59,24 +62,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -95,6 +101,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Client sends a request with payload, server reads then returns status. */
@@ -107,7 +114,6 @@ static void test(grpc_end2end_test_config config, bool request_status_early) {
   grpc_slice response_payload2_slice = grpc_slice_from_copied_string("world");
   grpc_byte_buffer *response_payload2 =
       grpc_raw_byte_buffer_create(&response_payload2_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
   grpc_end2end_test_fixture f = begin_test(config, "streaming_error_response",
                                            NULL, NULL, request_status_early);
   cq_verifier *cqv = cq_verifier_create(f.cq);
@@ -124,6 +130,7 @@ static void test(grpc_end2end_test_config config, bool request_status_early) {
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -177,6 +184,9 @@ static void test(grpc_end2end_test_config config, bool request_status_early) {
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
+  if (!request_status_early) {
+    CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
+  }
   cq_verify(cqv);
 
   memset(ops, 0, sizeof(ops));
@@ -188,9 +198,6 @@ static void test(grpc_end2end_test_config config, bool request_status_early) {
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(103), 1);
-  if (!request_status_early) {
-    CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
-  }
   cq_verify(cqv);
 
   memset(ops, 0, sizeof(ops));
@@ -256,8 +263,8 @@ static void test(grpc_end2end_test_config config, bool request_status_early) {
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/trailing_metadata.c b/test/core/end2end/tests/trailing_metadata.c
index dbbda505bc41ce15dce7025642ecf46e11a1c456..ca8eb6389e62e6f0f93810514ac9294b5a7c695a 100644
--- a/test/core/end2end/tests/trailing_metadata.c
+++ b/test/core/end2end/tests/trailing_metadata.c
@@ -57,24 +57,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -93,6 +96,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Request/response with metadata and payload.*/
@@ -108,7 +112,6 @@ static void test_request_response_with_metadata_and_payload(
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
   grpc_byte_buffer *response_payload =
       grpc_raw_byte_buffer_create(&response_payload_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
   grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"),
                               grpc_slice_from_static_string("val1"),
                               0,
@@ -149,6 +152,7 @@ static void test_request_response_with_metadata_and_payload(
   grpc_slice details;
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -272,8 +276,8 @@ static void test_request_response_with_metadata_and_payload(
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/write_buffering.c b/test/core/end2end/tests/write_buffering.c
index abf90ca6e06693bf4e02cb5f32e09d87455ccfb7..f8f2102e67a3ab31d078e8d45380cb848ebc005a 100644
--- a/test/core/end2end/tests/write_buffering.c
+++ b/test/core/end2end/tests/write_buffering.c
@@ -57,24 +57,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -93,6 +96,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Client sends a request with payload, server reads then returns status. */
@@ -106,7 +110,6 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
   grpc_slice request_payload_slice2 = grpc_slice_from_copied_string("abc123");
   grpc_byte_buffer *request_payload2 =
       grpc_raw_byte_buffer_create(&request_payload_slice2, 1);
-  gpr_timespec deadline = five_seconds_time();
   grpc_end2end_test_fixture f =
       begin_test(config, "test_invoke_request_with_payload", NULL, NULL);
   cq_verifier *cqv = cq_verifier_create(f.cq);
@@ -123,6 +126,7 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
   grpc_slice details = grpc_empty_slice();
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -270,8 +274,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/end2end/tests/write_buffering_at_end.c b/test/core/end2end/tests/write_buffering_at_end.c
index 8c02b425baeabe6c130029bf5dd6e69b7eb3fb14..2facd9c1a4a892e83dc299385d82027de6a34541 100644
--- a/test/core/end2end/tests/write_buffering_at_end.c
+++ b/test/core/end2end/tests/write_buffering_at_end.c
@@ -57,24 +57,27 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
   return f;
 }
 
-static gpr_timespec n_seconds_time(int n) {
+static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
 }
 
-static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
 
 static void drain_cq(grpc_completion_queue *cq) {
   grpc_event ev;
   do {
-    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
 }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 f->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
@@ -93,6 +96,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
   grpc_completion_queue_shutdown(f->cq);
   drain_cq(f->cq);
   grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
 }
 
 /* Client sends a request with payload, server reads then returns status. */
@@ -103,7 +107,6 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
       grpc_slice_from_copied_string("hello world");
   grpc_byte_buffer *request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
-  gpr_timespec deadline = five_seconds_time();
   grpc_end2end_test_fixture f =
       begin_test(config, "test_invoke_request_with_payload", NULL, NULL);
   cq_verifier *cqv = cq_verifier_create(f.cq);
@@ -120,6 +123,7 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
   grpc_slice details = grpc_empty_slice();
   int was_cancelled = 2;
 
+  gpr_timespec deadline = five_seconds_from_now();
   c = grpc_channel_create_call(
       f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
       grpc_slice_from_static_string("/foo"),
@@ -261,8 +265,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
   grpc_metadata_array_destroy(&request_metadata_recv);
   grpc_call_details_destroy(&call_details);
 
-  grpc_call_destroy(c);
-  grpc_call_destroy(s);
+  grpc_call_unref(c);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
diff --git a/test/core/fling/client.c b/test/core/fling/client.c
index 85bab6d431b5b9236523a6e5ef240fad76635f5c..3c43f4311c3159bd2fb1d957df53c137f4799c66 100644
--- a/test/core/fling/client.c
+++ b/test/core/fling/client.c
@@ -99,7 +99,7 @@ static void step_ping_pong_request(void) {
                                                    (size_t)(op - ops),
                                                    (void *)1, NULL));
   grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
-  grpc_call_destroy(call);
+  grpc_call_unref(call);
   grpc_byte_buffer_destroy(response_payload_recv);
   call = NULL;
   GPR_TIMER_END("ping_pong", 1);
@@ -208,7 +208,7 @@ int main(int argc, char **argv) {
   }
 
   channel = grpc_insecure_channel_create(target, NULL, NULL);
-  cq = grpc_completion_queue_create(NULL);
+  cq = grpc_completion_queue_create_for_next(NULL);
   the_buffer = grpc_raw_byte_buffer_create(&slice, (size_t)payload_size);
   histogram = gpr_histogram_create(0.01, 60e9);
 
@@ -233,7 +233,7 @@ int main(int argc, char **argv) {
   grpc_profiler_stop();
 
   if (call) {
-    grpc_call_destroy(call);
+    grpc_call_unref(call);
   }
 
   grpc_channel_destroy(channel);
diff --git a/test/core/fling/fling_stream_test.c b/test/core/fling/fling_stream_test.c
index 7e4daaa84fe734ec494d3787e45bde6e69cfff83..948659ab2f4ea797503fdcbf662f100a22d5c2e1 100644
--- a/test/core/fling/fling_stream_test.c
+++ b/test/core/fling/fling_stream_test.c
@@ -31,22 +31,13 @@
  *
  */
 
-#ifndef _POSIX_SOURCE
-#define _POSIX_SOURCE
-#endif
-
-#include <assert.h>
-#include <signal.h>
 #include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/string_util.h>
+#include <grpc/support/subprocess.h>
 #include "src/core/lib/support/string.h"
 #include "test/core/util/port.h"
 
@@ -57,10 +48,7 @@ int main(int argc, char **argv) {
   int port = grpc_pick_unused_port_or_die();
   char *args[10];
   int status;
-  pid_t svr, cli;
-  /* seed rng with pid, so we don't end up with the same random numbers as a
-     concurrently running test binary */
-  srand((unsigned)getpid());
+  gpr_subprocess *svr, *cli;
   /* figure out where we are */
   if (lslash) {
     memcpy(root, me, (size_t)(lslash - me));
@@ -69,45 +57,38 @@ int main(int argc, char **argv) {
     strcpy(root, ".");
   }
   /* start the server */
-  svr = fork();
-  if (svr == 0) {
-    gpr_asprintf(&args[0], "%s/fling_server", root);
-    args[1] = "--bind";
-    gpr_join_host_port(&args[2], "::", port);
-    args[3] = "--no-secure";
-    args[4] = 0;
-    execv(args[0], args);
+  gpr_asprintf(&args[0], "%s/fling_server%s", root,
+               gpr_subprocess_binary_extension());
+  args[1] = "--bind";
+  gpr_join_host_port(&args[2], "::", port);
+  args[3] = "--no-secure";
+  svr = gpr_subprocess_create(4, (const char **)args);
+  gpr_free(args[0]);
+  gpr_free(args[2]);
 
-    gpr_free(args[0]);
-    gpr_free(args[2]);
-    return 1;
-  }
-  /* wait a little */
-  sleep(2);
   /* start the client */
-  cli = fork();
-  if (cli == 0) {
-    gpr_asprintf(&args[0], "%s/fling_client", root);
-    args[1] = "--target";
-    gpr_join_host_port(&args[2], "127.0.0.1", port);
-    args[3] = "--scenario=ping-pong-stream";
-    args[4] = "--no-secure";
-    args[5] = 0;
-    execv(args[0], args);
+  gpr_asprintf(&args[0], "%s/fling_client%s", root,
+               gpr_subprocess_binary_extension());
+  args[1] = "--target";
+  gpr_join_host_port(&args[2], "127.0.0.1", port);
+  args[3] = "--scenario=ping-pong-stream";
+  args[4] = "--no-secure";
+  args[5] = 0;
+  cli = gpr_subprocess_create(6, (const char **)args);
+  gpr_free(args[0]);
+  gpr_free(args[2]);
 
-    gpr_free(args[0]);
-    gpr_free(args[2]);
-    return 1;
-  }
   /* wait for completion */
   printf("waiting for client\n");
-  if (waitpid(cli, &status, 0) == -1) return 2;
-  if (!WIFEXITED(status)) return 4;
-  if (WEXITSTATUS(status)) return WEXITSTATUS(status);
-  printf("waiting for server\n");
-  kill(svr, SIGINT);
-  if (waitpid(svr, &status, 0) == -1) return 2;
-  if (!WIFEXITED(status)) return 4;
-  if (WEXITSTATUS(status)) return WEXITSTATUS(status);
-  return 0;
+  if ((status = gpr_subprocess_join(cli))) {
+    gpr_subprocess_destroy(cli);
+    gpr_subprocess_destroy(svr);
+    return status;
+  }
+  gpr_subprocess_destroy(cli);
+
+  gpr_subprocess_interrupt(svr);
+  status = gpr_subprocess_join(svr);
+  gpr_subprocess_destroy(svr);
+  return status;
 }
diff --git a/test/core/fling/server.c b/test/core/fling/server.c
index 7ea54b1167ebfe5de0ff0749ba2d4014853fdac4..a927e9014ad286087dea76bc52da879d4bce83f9 100644
--- a/test/core/fling/server.c
+++ b/test/core/fling/server.c
@@ -185,6 +185,7 @@ int main(int argc, char **argv) {
   call_state *s;
   char *addr_buf = NULL;
   gpr_cmdline *cl;
+  grpc_completion_queue *shutdown_cq;
   int shutdown_started = 0;
   int shutdown_finished = 0;
 
@@ -214,7 +215,7 @@ int main(int argc, char **argv) {
   }
   gpr_log(GPR_INFO, "creating server on: %s", addr);
 
-  cq = grpc_completion_queue_create(NULL);
+  cq = grpc_completion_queue_create_for_next(NULL);
   if (secure) {
     grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {test_server1_key,
                                                     test_server1_cert};
@@ -242,10 +243,16 @@ int main(int argc, char **argv) {
   while (!shutdown_finished) {
     if (got_sigint && !shutdown_started) {
       gpr_log(GPR_INFO, "Shutting down due to SIGINT");
-      grpc_server_shutdown_and_notify(server, cq, tag(1000));
-      GPR_ASSERT(grpc_completion_queue_pluck(
-                     cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
-                     .type == GRPC_OP_COMPLETE);
+
+      shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
+      grpc_server_shutdown_and_notify(server, shutdown_cq, tag(1000));
+
+      GPR_ASSERT(
+          grpc_completion_queue_pluck(shutdown_cq, tag(1000),
+                                      grpc_timeout_seconds_to_deadline(5), NULL)
+              .type == GRPC_OP_COMPLETE);
+      grpc_completion_queue_destroy(shutdown_cq);
+
       grpc_completion_queue_shutdown(cq);
       shutdown_started = 1;
     }
@@ -294,7 +301,7 @@ int main(int argc, char **argv) {
             break;
           case FLING_SERVER_SEND_STATUS_FOR_STREAMING:
             /* Send status and close completed at server */
-            grpc_call_destroy(call);
+            grpc_call_unref(call);
             if (!shutdown_started) request_call();
             break;
           case FLING_SERVER_READ_FOR_UNARY:
@@ -307,7 +314,7 @@ int main(int argc, char **argv) {
             /* Finished unary call. */
             grpc_byte_buffer_destroy(payload_buffer);
             payload_buffer = NULL;
-            grpc_call_destroy(call);
+            grpc_call_unref(call);
             if (!shutdown_started) request_call();
             break;
         }
diff --git a/test/core/handshake/BUILD b/test/core/handshake/BUILD
index eb8f3a9beb950cbb9471ef41d0856c3d3bb2cd2a..996b503d353c39743d5dd6ab1b3f7f3e7b31181d 100644
--- a/test/core/handshake/BUILD
+++ b/test/core/handshake/BUILD
@@ -34,9 +34,9 @@ cc_test(
     srcs = ["client_ssl.c"],
     copts = ["-std=c99"],
     data = [
-        "//src/core/lib/tsi/test_creds:ca.pem",
-        "//src/core/lib/tsi/test_creds:server1.key",
-        "//src/core/lib/tsi/test_creds:server1.pem",
+        "//src/core/tsi/test_creds:ca.pem",
+        "//src/core/tsi/test_creds:server1.key",
+        "//src/core/tsi/test_creds:server1.pem",
     ],
     deps = [
         "//:gpr",
@@ -51,9 +51,9 @@ cc_test(
     srcs = ["server_ssl.c"],
     copts = ["-std=c99"],
     data = [
-        "//src/core/lib/tsi/test_creds:ca.pem",
-        "//src/core/lib/tsi/test_creds:server1.key",
-        "//src/core/lib/tsi/test_creds:server1.pem",
+        "//src/core/tsi/test_creds:ca.pem",
+        "//src/core/tsi/test_creds:server1.key",
+        "//src/core/tsi/test_creds:server1.pem",
     ],
     deps = [
         "//:gpr",
diff --git a/test/core/handshake/client_ssl.c b/test/core/handshake/client_ssl.c
index 5cfe60de4befb5e58b2cb8d6ec997ce1f7983a9b..f7fa919cd45e3a47c40148beefdd6ebad3063b74 100644
--- a/test/core/handshake/client_ssl.c
+++ b/test/core/handshake/client_ssl.c
@@ -54,9 +54,9 @@
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
-#define SSL_CERT_PATH "src/core/lib/tsi/test_creds/server1.pem"
-#define SSL_KEY_PATH "src/core/lib/tsi/test_creds/server1.key"
-#define SSL_CA_PATH "src/core/lib/tsi/test_creds/ca.pem"
+#define SSL_CERT_PATH "src/core/tsi/test_creds/server1.pem"
+#define SSL_KEY_PATH "src/core/tsi/test_creds/server1.key"
+#define SSL_CA_PATH "src/core/tsi/test_creds/ca.pem"
 
 // Arguments for TLS server thread.
 typedef struct {
@@ -146,7 +146,7 @@ static int alpn_select_cb(SSL *ssl, const uint8_t **out, uint8_t *out_len,
 
 // Minimal TLS server. This is largely based on the example at
 // https://wiki.openssl.org/index.php/Simple_TLS_Server and the gRPC core
-// internals in src/core/lib/tsi/ssl_transport_security.c.
+// internals in src/core/tsi/ssl_transport_security.c.
 static void server_thread(void *arg) {
   const server_args *args = (server_args *)arg;
 
@@ -172,7 +172,7 @@ static void server_thread(void *arg) {
   }
 
   // Set the cipher list to match the one expressed in
-  // src/core/lib/tsi/ssl_transport_security.c.
+  // src/core/tsi/ssl_transport_security.c.
   const char *cipher_list =
       "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-"
       "SHA384:ECDHE-RSA-AES256-GCM-SHA384";
@@ -289,7 +289,8 @@ static bool client_ssl_test(char *server_alpn_preferred) {
   // completed and we know that the client's ALPN list satisfied the server.
   int retries = 10;
   grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
-  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+  grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
+
   while (state != GRPC_CHANNEL_READY && retries-- > 0) {
     grpc_channel_watch_connectivity_state(
         channel, state, grpc_timeout_seconds_to_deadline(3), cq, NULL);
diff --git a/test/core/handshake/server_ssl.c b/test/core/handshake/server_ssl.c
index 0bd5a03cffeca710ad00822e110f03934bc23ccd..30f6474b3fb434e2467cc536853bc977a5f02762 100644
--- a/test/core/handshake/server_ssl.c
+++ b/test/core/handshake/server_ssl.c
@@ -49,9 +49,9 @@
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
-#define SSL_CERT_PATH "src/core/lib/tsi/test_creds/server1.pem"
-#define SSL_KEY_PATH "src/core/lib/tsi/test_creds/server1.key"
-#define SSL_CA_PATH "src/core/lib/tsi/test_creds/ca.pem"
+#define SSL_CERT_PATH "src/core/tsi/test_creds/server1.pem"
+#define SSL_KEY_PATH "src/core/tsi/test_creds/server1.key"
+#define SSL_CA_PATH "src/core/tsi/test_creds/ca.pem"
 
 // Handshake completed signal to server thread.
 static gpr_event client_handshake_complete;
@@ -104,7 +104,7 @@ static void server_thread(void *arg) {
   GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds));
   free(addr);
 
-  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+  grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
 
   grpc_server_register_completion_queue(server, cq, NULL);
   grpc_server_start(server);
@@ -174,7 +174,7 @@ static bool server_ssl_test(const char *alpn_list[], unsigned int alpn_list_len,
   }
 
   // Set the cipher list to match the one expressed in
-  // src/core/lib/tsi/ssl_transport_security.c.
+  // src/core/tsi/ssl_transport_security.c.
   const char *cipher_list =
       "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-"
       "SHA384:ECDHE-RSA-AES256-GCM-SHA384";
diff --git a/test/core/http/httpcli_test.c b/test/core/http/httpcli_test.c
index f690dbaffbcebd8aa3e9528e834afed67dcbc872..d3b45c45056da5c6fc1554521c1b8c0daacb3159 100644
--- a/test/core/http/httpcli_test.c
+++ b/test/core/http/httpcli_test.c
@@ -102,7 +102,7 @@ static void test_get(int port) {
         "pollset_work",
         grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&g_pops),
                           &worker, gpr_now(GPR_CLOCK_MONOTONIC),
-                          n_seconds_time(20))));
+                          n_seconds_time(1))));
     gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
     gpr_mu_lock(g_mu);
@@ -144,7 +144,7 @@ static void test_post(int port) {
         "pollset_work",
         grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&g_pops),
                           &worker, gpr_now(GPR_CLOCK_MONOTONIC),
-                          n_seconds_time(20))));
+                          n_seconds_time(1))));
     gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
     gpr_mu_lock(g_mu);
diff --git a/test/core/http/httpscli_test.c b/test/core/http/httpscli_test.c
index 549411037e56b0e377ec252c44808a8dfe55365c..acc94091f4e44f1317748ce92fc2851ac54f6d5d 100644
--- a/test/core/http/httpscli_test.c
+++ b/test/core/http/httpscli_test.c
@@ -103,7 +103,7 @@ static void test_get(int port) {
         "pollset_work",
         grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&g_pops),
                           &worker, gpr_now(GPR_CLOCK_MONOTONIC),
-                          n_seconds_time(20))));
+                          n_seconds_time(1))));
     gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
     gpr_mu_lock(g_mu);
@@ -146,7 +146,7 @@ static void test_post(int port) {
         "pollset_work",
         grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&g_pops),
                           &worker, gpr_now(GPR_CLOCK_MONOTONIC),
-                          n_seconds_time(20))));
+                          n_seconds_time(1))));
     gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
     gpr_mu_lock(g_mu);
diff --git a/test/core/http/test_server.py b/test/core/http/test_server.py
index 86c2fe96bf9c2c66bf2843a49add7ae7049db62d..dbbf5ceb3c7975b19941d72590107e9643d0daf3 100755
--- a/test/core/http/test_server.py
+++ b/test/core/http/test_server.py
@@ -36,8 +36,8 @@ import os
 import ssl
 import sys
 
-_PEM = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/lib/tsi/test_creds/server1.pem'))
-_KEY = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/lib/tsi/test_creds/server1.key'))
+_PEM = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/tsi/test_creds/server1.pem'))
+_KEY = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/tsi/test_creds/server1.key'))
 print _PEM
 open(_PEM).close()
 
diff --git a/test/core/iomgr/endpoint_pair_test.c b/test/core/iomgr/endpoint_pair_test.c
index 4b98ef257e5ab1a8a479d08063b1e35268c9d25b..c8a60776b9c7b9ae5a72c1bffad25d558459f5a9 100644
--- a/test/core/iomgr/endpoint_pair_test.c
+++ b/test/core/iomgr/endpoint_pair_test.c
@@ -49,11 +49,11 @@ static grpc_endpoint_test_fixture create_fixture_endpoint_pair(
     size_t slice_size) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_endpoint_test_fixture f;
-  grpc_resource_quota *resource_quota =
-      grpc_resource_quota_create("endpoint_pair_test");
-  grpc_endpoint_pair p =
-      grpc_iomgr_create_endpoint_pair("test", resource_quota, slice_size);
-  grpc_resource_quota_unref(resource_quota);
+  grpc_arg a[] = {{.key = GRPC_ARG_TCP_READ_CHUNK_SIZE,
+                   .type = GRPC_ARG_INTEGER,
+                   .value.integer = (int)slice_size}};
+  grpc_channel_args args = {.num_args = GPR_ARRAY_SIZE(a), .args = a};
+  grpc_endpoint_pair p = grpc_iomgr_create_endpoint_pair("test", &args);
 
   f.client_ep = p.client;
   f.server_ep = p.server;
diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c
index 94067a8ca4da1986af42f25f96caeb3c4eeb156b..e274796e23728bd262c26f2266dd8741bc6f5070 100644
--- a/test/core/iomgr/endpoint_tests.c
+++ b/test/core/iomgr/endpoint_tests.c
@@ -233,11 +233,13 @@ static void read_and_write_test(grpc_endpoint_test_config config,
 
   if (shutdown) {
     gpr_log(GPR_DEBUG, "shutdown read");
-    grpc_endpoint_shutdown(&exec_ctx, state.read_ep,
-                           GRPC_ERROR_CREATE("Test Shutdown"));
+    grpc_endpoint_shutdown(
+        &exec_ctx, state.read_ep,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown"));
     gpr_log(GPR_DEBUG, "shutdown write");
-    grpc_endpoint_shutdown(&exec_ctx, state.write_ep,
-                           GRPC_ERROR_CREATE("Test Shutdown"));
+    grpc_endpoint_shutdown(
+        &exec_ctx, state.write_ep,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown"));
   }
   grpc_exec_ctx_flush(&exec_ctx);
 
@@ -299,7 +301,7 @@ static void multiple_shutdown_test(grpc_endpoint_test_config config) {
                                          grpc_schedule_on_exec_ctx));
   wait_for_fail_count(&exec_ctx, &fail_count, 0);
   grpc_endpoint_shutdown(&exec_ctx, f.client_ep,
-                         GRPC_ERROR_CREATE("Test Shutdown"));
+                         GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown"));
   wait_for_fail_count(&exec_ctx, &fail_count, 1);
   grpc_endpoint_read(&exec_ctx, f.client_ep, &slice_buffer,
                      grpc_closure_create(inc_on_failure, &fail_count,
@@ -311,7 +313,7 @@ static void multiple_shutdown_test(grpc_endpoint_test_config config) {
                                           grpc_schedule_on_exec_ctx));
   wait_for_fail_count(&exec_ctx, &fail_count, 3);
   grpc_endpoint_shutdown(&exec_ctx, f.client_ep,
-                         GRPC_ERROR_CREATE("Test Shutdown"));
+                         GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown"));
   wait_for_fail_count(&exec_ctx, &fail_count, 3);
 
   grpc_slice_buffer_destroy_internal(&exec_ctx, &slice_buffer);
diff --git a/test/core/iomgr/error_test.c b/test/core/iomgr/error_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..607dbeea3e7b8eedffaf3326cda29a33ff13ff15
--- /dev/null
+++ b/test/core/iomgr/error_test.c
@@ -0,0 +1,260 @@
+/*
+ *
+ * Copyright 2017, 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/lib/iomgr/error.h"
+
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/useful.h>
+
+#include <string.h>
+
+#include "test/core/util/test_config.h"
+
+static void test_set_get_int() {
+  grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test");
+  GPR_ASSERT(error);
+  intptr_t i = 0;
+  GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_FILE_LINE, &i));
+  GPR_ASSERT(i);  // line set will never be 0
+  GPR_ASSERT(!grpc_error_get_int(error, GRPC_ERROR_INT_ERRNO, &i));
+  GPR_ASSERT(!grpc_error_get_int(error, GRPC_ERROR_INT_SIZE, &i));
+
+  intptr_t errnumber = 314;
+  error = grpc_error_set_int(error, GRPC_ERROR_INT_ERRNO, errnumber);
+  GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_ERRNO, &i));
+  GPR_ASSERT(i == errnumber);
+
+  intptr_t http = 2;
+  error = grpc_error_set_int(error, GRPC_ERROR_INT_HTTP2_ERROR, http);
+  GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_HTTP2_ERROR, &i));
+  GPR_ASSERT(i == http);
+
+  GRPC_ERROR_UNREF(error);
+}
+
+static void test_set_get_str() {
+  grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test");
+
+  grpc_slice str;
+  GPR_ASSERT(!grpc_error_get_str(error, GRPC_ERROR_STR_SYSCALL, &str));
+  GPR_ASSERT(!grpc_error_get_str(error, GRPC_ERROR_STR_TSI_ERROR, &str));
+
+  GPR_ASSERT(grpc_error_get_str(error, GRPC_ERROR_STR_FILE, &str));
+  GPR_ASSERT(strstr((char*)GRPC_SLICE_START_PTR(str),
+                    "error_test.c"));  // __FILE__ expands differently on
+                                       // Windows. All should at least
+                                       // contain error_test.c
+
+  GPR_ASSERT(grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION, &str));
+  GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), "Test",
+                      GRPC_SLICE_LENGTH(str)));
+
+  error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE,
+                             grpc_slice_from_static_string("longer message"));
+  GPR_ASSERT(grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, &str));
+  GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), "longer message",
+                      GRPC_SLICE_LENGTH(str)));
+
+  GRPC_ERROR_UNREF(error);
+}
+
+static void test_copy_and_unref() {
+  // error1 has one ref
+  grpc_error* error1 = grpc_error_set_str(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test"), GRPC_ERROR_STR_GRPC_MESSAGE,
+      grpc_slice_from_static_string("message"));
+  grpc_slice str;
+  GPR_ASSERT(grpc_error_get_str(error1, GRPC_ERROR_STR_GRPC_MESSAGE, &str));
+  GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), "message",
+                      GRPC_SLICE_LENGTH(str)));
+
+  // error 1 has two refs
+  GRPC_ERROR_REF(error1);
+  // this gives error3 a ref to the new error, and decrements error1 to one ref
+  grpc_error* error3 = grpc_error_set_str(
+      error1, GRPC_ERROR_STR_SYSCALL, grpc_slice_from_static_string("syscall"));
+  GPR_ASSERT(error3 != error1);  // should not be the same because of extra ref
+  GPR_ASSERT(grpc_error_get_str(error3, GRPC_ERROR_STR_GRPC_MESSAGE, &str));
+  GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), "message",
+                      GRPC_SLICE_LENGTH(str)));
+
+  // error 1 should not have a syscall but 3 should
+  GPR_ASSERT(!grpc_error_get_str(error1, GRPC_ERROR_STR_SYSCALL, &str));
+  GPR_ASSERT(grpc_error_get_str(error3, GRPC_ERROR_STR_SYSCALL, &str));
+  GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), "syscall",
+                      GRPC_SLICE_LENGTH(str)));
+
+  GRPC_ERROR_UNREF(error1);
+  GRPC_ERROR_UNREF(error3);
+}
+
+static void test_create_referencing() {
+  grpc_error* child = grpc_error_set_str(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child"),
+      GRPC_ERROR_STR_GRPC_MESSAGE, grpc_slice_from_static_string("message"));
+  grpc_error* parent =
+      GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Parent", &child, 1);
+  GPR_ASSERT(parent);
+
+  GRPC_ERROR_UNREF(child);
+  GRPC_ERROR_UNREF(parent);
+}
+
+static void test_create_referencing_many() {
+  grpc_error* children[3];
+  children[0] = grpc_error_set_str(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child1"),
+      GRPC_ERROR_STR_GRPC_MESSAGE, grpc_slice_from_static_string("message"));
+  children[1] =
+      grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child2"),
+                         GRPC_ERROR_INT_HTTP2_ERROR, 5);
+  children[2] = grpc_error_set_str(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child3"),
+      GRPC_ERROR_STR_GRPC_MESSAGE, grpc_slice_from_static_string("message 3"));
+
+  grpc_error* parent =
+      GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Parent", children, 3);
+  GPR_ASSERT(parent);
+
+  for (size_t i = 0; i < 3; ++i) {
+    GRPC_ERROR_UNREF(children[i]);
+  }
+  GRPC_ERROR_UNREF(parent);
+}
+
+static void print_error_string() {
+  grpc_error* error =
+      grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"),
+                         GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNIMPLEMENTED);
+  error = grpc_error_set_int(error, GRPC_ERROR_INT_SIZE, 666);
+  error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE,
+                             grpc_slice_from_static_string("message"));
+  // gpr_log(GPR_DEBUG, "%s", grpc_error_string(error));
+  GRPC_ERROR_UNREF(error);
+}
+
+static void print_error_string_reference() {
+  grpc_error* children[2];
+  children[0] = grpc_error_set_str(
+      grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("1"),
+                         GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNIMPLEMENTED),
+      GRPC_ERROR_STR_GRPC_MESSAGE,
+      grpc_slice_from_static_string("message for child 1"));
+  children[1] = grpc_error_set_str(
+      grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("2sd"),
+                         GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL),
+      GRPC_ERROR_STR_GRPC_MESSAGE,
+      grpc_slice_from_static_string("message for child 2"));
+
+  grpc_error* parent =
+      GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Parent", children, 2);
+
+  for (size_t i = 0; i < 2; ++i) {
+    GRPC_ERROR_UNREF(children[i]);
+  }
+  GRPC_ERROR_UNREF(parent);
+}
+
+static void test_os_error() {
+  int fake_errno = 5;
+  const char* syscall = "syscall name";
+  grpc_error* error = GRPC_OS_ERROR(fake_errno, syscall);
+
+  intptr_t i = 0;
+  GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_ERRNO, &i));
+  GPR_ASSERT(i == fake_errno);
+
+  grpc_slice str;
+  GPR_ASSERT(grpc_error_get_str(error, GRPC_ERROR_STR_SYSCALL, &str));
+  GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), syscall,
+                      GRPC_SLICE_LENGTH(str)));
+  GRPC_ERROR_UNREF(error);
+}
+
+static void test_special() {
+  grpc_error* error = GRPC_ERROR_NONE;
+  error = grpc_error_add_child(
+      error, GRPC_ERROR_CREATE_FROM_STATIC_STRING("test child"));
+  intptr_t i;
+  GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &i));
+  GPR_ASSERT(i == GRPC_STATUS_OK);
+  GRPC_ERROR_UNREF(error);
+}
+
+static void test_overflow() {
+  grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Overflow");
+
+  for (size_t i = 0; i < 150; ++i) {
+    error = grpc_error_add_child(error,
+                                 GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child"));
+  }
+
+  error = grpc_error_set_int(error, GRPC_ERROR_INT_HTTP2_ERROR, 5);
+  error =
+      grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE,
+                         grpc_slice_from_static_string("message for child 2"));
+  error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, 5);
+
+  intptr_t i;
+  GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_HTTP2_ERROR, &i));
+  GPR_ASSERT(i == 5);
+  GPR_ASSERT(!grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &i));
+
+  error = grpc_error_set_int(error, GRPC_ERROR_INT_HTTP2_ERROR, 10);
+  GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_HTTP2_ERROR, &i));
+  GPR_ASSERT(i == 10);
+
+  GRPC_ERROR_UNREF(error);
+  ;
+}
+
+int main(int argc, char** argv) {
+  grpc_test_init(argc, argv);
+  grpc_init();
+  test_set_get_int();
+  test_set_get_str();
+  test_copy_and_unref();
+  print_error_string();
+  print_error_string_reference();
+  test_os_error();
+  test_create_referencing();
+  test_create_referencing_many();
+  test_special();
+  test_overflow();
+  grpc_shutdown();
+
+  return 0;
+}
diff --git a/test/core/iomgr/ev_epoll_linux_test.c b/test/core/iomgr/ev_epoll_linux_test.c
index 4ec959995b2c653faadbee04d11191c1b66d9b0c..0856023b14f6878483836515327609c64399cf51 100644
--- a/test/core/iomgr/ev_epoll_linux_test.c
+++ b/test/core/iomgr/ev_epoll_linux_test.c
@@ -43,6 +43,8 @@
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/useful.h>
 
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/iomgr/workqueue.h"
@@ -90,7 +92,7 @@ static void test_fd_cleanup(grpc_exec_ctx *exec_ctx, test_fd *tfds,
 
   for (i = 0; i < num_fds; i++) {
     grpc_fd_shutdown(exec_ctx, tfds[i].fd,
-                     GRPC_ERROR_CREATE("test_fd_cleanup"));
+                     GRPC_ERROR_CREATE_FROM_STATIC_STRING("test_fd_cleanup"));
     grpc_exec_ctx_flush(exec_ctx);
 
     grpc_fd_orphan(exec_ctx, tfds[i].fd, NULL, &release_fd, "test_fd_cleanup");
@@ -139,23 +141,25 @@ static void increment(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
  * polling_island_merge()[ev_epoll_linux.c], where the parent relationship was
  * inverted.
  */
+
+#define NUM_FDS 2
+#define NUM_POLLSETS 2
+#define NUM_CLOSURES 4
+
 static void test_pollset_queue_merge_items() {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  const int num_fds = 2;
-  const int num_pollsets = 2;
-  const int num_closures = 4;
-  test_fd tfds[num_fds];
-  int fds[num_fds];
-  test_pollset pollsets[num_pollsets];
-  grpc_closure closures[num_closures];
+  test_fd tfds[NUM_FDS];
+  int fds[NUM_FDS];
+  test_pollset pollsets[NUM_POLLSETS];
+  grpc_closure closures[NUM_CLOSURES];
   int i;
   int result = 0;
 
-  test_fd_init(tfds, fds, num_fds);
-  test_pollset_init(pollsets, num_pollsets);
+  test_fd_init(tfds, fds, NUM_FDS);
+  test_pollset_init(pollsets, NUM_POLLSETS);
 
   /* Two distinct polling islands, each with their own FD and pollset. */
-  for (i = 0; i < num_fds; i++) {
+  for (i = 0; i < NUM_FDS; i++) {
     grpc_pollset_add_fd(&exec_ctx, pollsets[i].pollset, tfds[i].fd);
     grpc_exec_ctx_flush(&exec_ctx);
   }
@@ -173,7 +177,7 @@ static void test_pollset_queue_merge_items() {
   grpc_closure_init(
       closures + 3, increment, &result,
       grpc_workqueue_scheduler(grpc_fd_get_polling_island(tfds[1].fd)));
-  for (i = 0; i < num_closures; ++i) {
+  for (i = 0; i < NUM_CLOSURES; ++i) {
     grpc_closure_sched(&exec_ctx, closures + i, GRPC_ERROR_NONE);
   }
 
@@ -186,7 +190,7 @@ static void test_pollset_queue_merge_items() {
    * the merged polling island.
    */
   grpc_pollset_worker *worker = NULL;
-  for (i = 0; i < num_closures; ++i) {
+  for (i = 0; i < NUM_CLOSURES; ++i) {
     const gpr_timespec deadline = gpr_time_add(
         gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(2, GPR_TIMESPAN));
     gpr_mu_lock(pollsets[1].mu);
@@ -196,13 +200,17 @@ static void test_pollset_queue_merge_items() {
                           gpr_now(GPR_CLOCK_MONOTONIC), deadline));
     gpr_mu_unlock(pollsets[1].mu);
   }
-  GPR_ASSERT(result == num_closures);
+  GPR_ASSERT(result == NUM_CLOSURES);
 
-  test_fd_cleanup(&exec_ctx, tfds, num_fds);
-  test_pollset_cleanup(&exec_ctx, pollsets, num_pollsets);
+  test_fd_cleanup(&exec_ctx, tfds, NUM_FDS);
+  test_pollset_cleanup(&exec_ctx, pollsets, NUM_POLLSETS);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
+#undef NUM_FDS
+#undef NUM_POLLSETS
+#undef NUM_CLOSURES
+
 /*
  * Cases to test:
  *  case 1) Polling islands of both fd and pollset are NULL
@@ -213,18 +221,20 @@ static void test_pollset_queue_merge_items() {
  *     case 4.2) Polling islands of fd and pollset are NOT-equal (This results
  *     in a merge)
  * */
+
+#define NUM_FDS 8
+#define NUM_POLLSETS 4
+
 static void test_add_fd_to_pollset() {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  const int num_fds = 8;
-  const int num_pollsets = 4;
-  test_fd tfds[num_fds];
-  int fds[num_fds];
-  test_pollset pollsets[num_pollsets];
+  test_fd tfds[NUM_FDS];
+  int fds[NUM_FDS];
+  test_pollset pollsets[NUM_POLLSETS];
   void *expected_pi = NULL;
   int i;
 
-  test_fd_init(tfds, fds, num_fds);
-  test_pollset_init(pollsets, num_pollsets);
+  test_fd_init(tfds, fds, NUM_FDS);
+  test_pollset_init(pollsets, NUM_POLLSETS);
 
   /*Step 1.
    * Create three polling islands (This will exercise test case 1 and 2) with
@@ -285,22 +295,110 @@ static void test_add_fd_to_pollset() {
 
   /* Compare Fd:0's polling island with that of all other Fds */
   expected_pi = grpc_fd_get_polling_island(tfds[0].fd);
-  for (i = 1; i < num_fds; i++) {
+  for (i = 1; i < NUM_FDS; i++) {
     GPR_ASSERT(grpc_are_polling_islands_equal(
         expected_pi, grpc_fd_get_polling_island(tfds[i].fd)));
   }
 
   /* Compare Fd:0's polling island with that of all other pollsets */
-  for (i = 0; i < num_pollsets; i++) {
+  for (i = 0; i < NUM_POLLSETS; i++) {
     GPR_ASSERT(grpc_are_polling_islands_equal(
         expected_pi, grpc_pollset_get_polling_island(pollsets[i].pollset)));
   }
 
-  test_fd_cleanup(&exec_ctx, tfds, num_fds);
-  test_pollset_cleanup(&exec_ctx, pollsets, num_pollsets);
+  test_fd_cleanup(&exec_ctx, tfds, NUM_FDS);
+  test_pollset_cleanup(&exec_ctx, pollsets, NUM_POLLSETS);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
+#undef NUM_FDS
+#undef NUM_POLLSETS
+
+typedef struct threading_shared {
+  gpr_mu *mu;
+  grpc_pollset *pollset;
+  grpc_wakeup_fd *wakeup_fd;
+  grpc_fd *wakeup_desc;
+  grpc_closure on_wakeup;
+  int wakeups;
+} threading_shared;
+
+static __thread int thread_wakeups = 0;
+
+static void test_threading_loop(void *arg) {
+  threading_shared *shared = arg;
+  while (thread_wakeups < 1000000) {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_pollset_worker *worker;
+    gpr_mu_lock(shared->mu);
+    GPR_ASSERT(GRPC_LOG_IF_ERROR(
+        "pollset_work",
+        grpc_pollset_work(&exec_ctx, shared->pollset, &worker,
+                          gpr_now(GPR_CLOCK_MONOTONIC),
+                          gpr_inf_future(GPR_CLOCK_MONOTONIC))));
+    gpr_mu_unlock(shared->mu);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
+}
+
+static void test_threading_wakeup(grpc_exec_ctx *exec_ctx, void *arg,
+                                  grpc_error *error) {
+  threading_shared *shared = arg;
+  ++shared->wakeups;
+  ++thread_wakeups;
+  if (error == GRPC_ERROR_NONE) {
+    GPR_ASSERT(GRPC_LOG_IF_ERROR(
+        "consume_wakeup", grpc_wakeup_fd_consume_wakeup(shared->wakeup_fd)));
+    grpc_fd_notify_on_read(exec_ctx, shared->wakeup_desc, &shared->on_wakeup);
+    GPR_ASSERT(GRPC_LOG_IF_ERROR("wakeup_next",
+                                 grpc_wakeup_fd_wakeup(shared->wakeup_fd)));
+  }
+}
+
+static void test_threading(void) {
+  threading_shared shared;
+  shared.pollset = gpr_zalloc(grpc_pollset_size());
+  grpc_pollset_init(shared.pollset, &shared.mu);
+
+  gpr_thd_id thds[10];
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
+    gpr_thd_options opt = gpr_thd_options_default();
+    gpr_thd_options_set_joinable(&opt);
+    gpr_thd_new(&thds[i], test_threading_loop, &shared, &opt);
+  }
+  grpc_wakeup_fd fd;
+  GPR_ASSERT(GRPC_LOG_IF_ERROR("wakeup_fd_init", grpc_wakeup_fd_init(&fd)));
+  shared.wakeup_fd = &fd;
+  shared.wakeup_desc = grpc_fd_create(fd.read_fd, "wakeup");
+  shared.wakeups = 0;
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_pollset_add_fd(&exec_ctx, shared.pollset, shared.wakeup_desc);
+    grpc_fd_notify_on_read(
+        &exec_ctx, shared.wakeup_desc,
+        grpc_closure_init(&shared.on_wakeup, test_threading_wakeup, &shared,
+                          grpc_schedule_on_exec_ctx));
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
+  GPR_ASSERT(GRPC_LOG_IF_ERROR("wakeup_first",
+                               grpc_wakeup_fd_wakeup(shared.wakeup_fd)));
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
+    gpr_thd_join(thds[i]);
+  }
+  fd.read_fd = 0;
+  grpc_wakeup_fd_destroy(&fd);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_fd_shutdown(&exec_ctx, shared.wakeup_desc, GRPC_ERROR_CANCELLED);
+    grpc_fd_orphan(&exec_ctx, shared.wakeup_desc, NULL, NULL, "done");
+    grpc_pollset_shutdown(&exec_ctx, shared.pollset,
+                          grpc_closure_create(destroy_pollset, shared.pollset,
+                                              grpc_schedule_on_exec_ctx));
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
+  gpr_free(shared.pollset);
+}
+
 int main(int argc, char **argv) {
   const char *poll_strategy = NULL;
   grpc_test_init(argc, argv);
@@ -310,6 +408,7 @@ int main(int argc, char **argv) {
   if (poll_strategy != NULL && strcmp(poll_strategy, "epoll") == 0) {
     test_add_fd_to_pollset();
     test_pollset_queue_merge_items();
+    test_threading();
   } else {
     gpr_log(GPR_INFO,
             "Skipping the test. The test is only relevant for 'epoll' "
diff --git a/test/core/iomgr/fd_conservation_posix_test.c b/test/core/iomgr/fd_conservation_posix_test.c
index 3dffa02c3c809b3790b375b5f28d92943c7e084a..6ac322bb01458f8532dd955f14bc50958e4a6384 100644
--- a/test/core/iomgr/fd_conservation_posix_test.c
+++ b/test/core/iomgr/fd_conservation_posix_test.c
@@ -57,7 +57,7 @@ int main(int argc, char **argv) {
 
   for (i = 0; i < 100; i++) {
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-    p = grpc_iomgr_create_endpoint_pair("test", resource_quota, 1);
+    p = grpc_iomgr_create_endpoint_pair("test", NULL);
     grpc_endpoint_destroy(&exec_ctx, p.client);
     grpc_endpoint_destroy(&exec_ctx, p.server);
     grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index c1a0ef54d322e4e246775398216056f7da47ab1f..81d2692a084c05d467f4bca7a312ceaae3e07891 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -133,7 +133,7 @@ static void session_shutdown_cb(grpc_exec_ctx *exec_ctx, void *arg, /*session */
   gpr_free(se);
   /* Start to shutdown listen fd. */
   grpc_fd_shutdown(exec_ctx, sv->em_fd,
-                   GRPC_ERROR_CREATE("session_shutdown_cb"));
+                   GRPC_ERROR_CREATE_FROM_STATIC_STRING("session_shutdown_cb"));
 }
 
 /* Called when data become readable in a session. */
diff --git a/test/core/iomgr/pollset_set_test.c b/test/core/iomgr/pollset_set_test.c
index f27e9db8c9a881c414b03434469f08084f20d6f9..3a9d459579f53394dd8f6510354f82c8953029fd 100644
--- a/test/core/iomgr/pollset_set_test.c
+++ b/test/core/iomgr/pollset_set_test.c
@@ -143,7 +143,8 @@ static void cleanup_test_fds(grpc_exec_ctx *exec_ctx, test_fd *tfds,
   int release_fd;
 
   for (int i = 0; i < num_fds; i++) {
-    grpc_fd_shutdown(exec_ctx, tfds[i].fd, GRPC_ERROR_CREATE("fd cleanup"));
+    grpc_fd_shutdown(exec_ctx, tfds[i].fd,
+                     GRPC_ERROR_CREATE_FROM_STATIC_STRING("fd cleanup"));
     grpc_exec_ctx_flush(exec_ctx);
 
     /* grpc_fd_orphan frees the memory allocated for grpc_fd. Normally it also
diff --git a/test/core/iomgr/resource_quota_test.c b/test/core/iomgr/resource_quota_test.c
index a5b28f210d8e761baf719165a4e077e974d47c7b..ebce8b9da6e5476ee7df0b652052a2f3da187f8d 100644
--- a/test/core/iomgr/resource_quota_test.c
+++ b/test/core/iomgr/resource_quota_test.c
@@ -682,6 +682,56 @@ static void test_one_slice_deleted_late(void) {
   }
 }
 
+static void test_resize_to_zero(void) {
+  gpr_log(GPR_INFO, "** test_resize_to_zero **");
+  grpc_resource_quota *q = grpc_resource_quota_create("test_resize_to_zero");
+  grpc_resource_quota_resize(q, 0);
+  grpc_resource_quota_unref(q);
+}
+
+static void test_negative_rq_free_pool(void) {
+  gpr_log(GPR_INFO, "** test_negative_rq_free_pool **");
+  grpc_resource_quota *q =
+      grpc_resource_quota_create("test_negative_rq_free_pool");
+  grpc_resource_quota_resize(q, 1024);
+
+  grpc_resource_user *usr = grpc_resource_user_create(q, "usr");
+
+  grpc_resource_user_slice_allocator alloc;
+  int num_allocs = 0;
+  grpc_resource_user_slice_allocator_init(&alloc, usr, inc_int_cb, &num_allocs);
+
+  grpc_slice_buffer buffer;
+  grpc_slice_buffer_init(&buffer);
+
+  {
+    const int start_allocs = num_allocs;
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_resource_user_alloc_slices(&exec_ctx, &alloc, 1024, 1, &buffer);
+    grpc_exec_ctx_finish(&exec_ctx);
+    GPR_ASSERT(num_allocs == start_allocs + 1);
+  }
+
+  grpc_resource_quota_resize(q, 512);
+
+  double eps = 0.0001;
+  GPR_ASSERT(grpc_resource_quota_get_memory_pressure(q) < 1 + eps);
+  GPR_ASSERT(grpc_resource_quota_get_memory_pressure(q) > 1 - eps);
+
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_resource_user_unref(&exec_ctx, usr);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
+
+  grpc_resource_quota_unref(q);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_slice_buffer_destroy_internal(&exec_ctx, &buffer);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
+}
+
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
   grpc_init();
@@ -705,6 +755,8 @@ int main(int argc, char **argv) {
   test_reclaimers_can_be_posted_repeatedly();
   test_one_slice();
   test_one_slice_deleted_late();
+  test_resize_to_zero();
+  test_negative_rq_free_pool();
   grpc_shutdown();
   return 0;
 }
diff --git a/test/core/iomgr/sockaddr_utils_test.c b/test/core/iomgr/sockaddr_utils_test.c
index 8569c697fe91b527d1588ee810534d120618bed7..09c514c8e6ffa60b2f0345f6e65376d1a72a260f 100644
--- a/test/core/iomgr/sockaddr_utils_test.c
+++ b/test/core/iomgr/sockaddr_utils_test.c
@@ -70,6 +70,12 @@ static grpc_resolved_address make_addr6(const uint8_t *data, size_t data_len) {
   return resolved_addr6;
 }
 
+static void set_addr6_scope_id(grpc_resolved_address *addr, uint32_t scope_id) {
+  struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr->addr;
+  GPR_ASSERT(addr6->sin6_family == AF_INET6);
+  addr6->sin6_scope_id = scope_id;
+}
+
 static const uint8_t kMapped[] = {0, 0, 0,    0,    0,   0, 0, 0,
                                   0, 0, 0xff, 0xff, 192, 0, 2, 1};
 
@@ -222,6 +228,16 @@ static void test_sockaddr_to_string(void) {
   expect_sockaddr_str("[2001:db8::1]:12345", &input6, 1);
   expect_sockaddr_uri("ipv6:[2001:db8::1]:12345", &input6);
 
+  set_addr6_scope_id(&input6, 2);
+  expect_sockaddr_str("[2001:db8::1%252]:12345", &input6, 0);
+  expect_sockaddr_str("[2001:db8::1%252]:12345", &input6, 1);
+  expect_sockaddr_uri("ipv6:[2001:db8::1%252]:12345", &input6);
+
+  set_addr6_scope_id(&input6, 101);
+  expect_sockaddr_str("[2001:db8::1%25101]:12345", &input6, 0);
+  expect_sockaddr_str("[2001:db8::1%25101]:12345", &input6, 1);
+  expect_sockaddr_uri("ipv6:[2001:db8::1%25101]:12345", &input6);
+
   input6 = make_addr6(kMapped, sizeof(kMapped));
   expect_sockaddr_str("[::ffff:192.0.2.1]:12345", &input6, 0);
   expect_sockaddr_str("192.0.2.1:12345", &input6, 1);
@@ -238,8 +254,6 @@ static void test_sockaddr_to_string(void) {
   expect_sockaddr_str("(sockaddr family=123)", &dummy, 0);
   expect_sockaddr_str("(sockaddr family=123)", &dummy, 1);
   GPR_ASSERT(grpc_sockaddr_to_uri(&dummy) == NULL);
-
-  GPR_ASSERT(errno == 0x7EADBEEF);
 }
 
 static void test_sockaddr_set_get_port(void) {
diff --git a/test/core/iomgr/tcp_client_posix_test.c b/test/core/iomgr/tcp_client_posix_test.c
index b324b5a65ed7ad001abfc81c84f436a92adc1b8f..2fae6774e869953370c53e3f6e67cb2cb4a8ac16 100644
--- a/test/core/iomgr/tcp_client_posix_test.c
+++ b/test/core/iomgr/tcp_client_posix_test.c
@@ -77,8 +77,9 @@ static void must_succeed(grpc_exec_ctx *exec_ctx, void *arg,
                          grpc_error *error) {
   GPR_ASSERT(g_connecting != NULL);
   GPR_ASSERT(error == GRPC_ERROR_NONE);
-  grpc_endpoint_shutdown(exec_ctx, g_connecting,
-                         GRPC_ERROR_CREATE("must_succeed called"));
+  grpc_endpoint_shutdown(
+      exec_ctx, g_connecting,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("must_succeed called"));
   grpc_endpoint_destroy(exec_ctx, g_connecting);
   g_connecting = NULL;
   finish_connection();
diff --git a/test/core/iomgr/tcp_client_uv_test.c b/test/core/iomgr/tcp_client_uv_test.c
index f8938d0abb7799fc66c4cee863c21e5bc384098c..92fc3934226deb992c18b320004a3e6ed335c31d 100644
--- a/test/core/iomgr/tcp_client_uv_test.c
+++ b/test/core/iomgr/tcp_client_uv_test.c
@@ -58,7 +58,7 @@ static int g_connections_complete = 0;
 static grpc_endpoint *g_connecting = NULL;
 
 static gpr_timespec test_deadline(void) {
-  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
+  return grpc_timeout_seconds_to_deadline(10);
 }
 
 static void finish_connection() {
@@ -73,7 +73,9 @@ static void must_succeed(grpc_exec_ctx *exec_ctx, void *arg,
                          grpc_error *error) {
   GPR_ASSERT(g_connecting != NULL);
   GPR_ASSERT(error == GRPC_ERROR_NONE);
-  grpc_endpoint_shutdown(exec_ctx, g_connecting);
+  grpc_endpoint_shutdown(
+      exec_ctx, g_connecting,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("must_succeed called"));
   grpc_endpoint_destroy(exec_ctx, g_connecting);
   g_connecting = NULL;
   finish_connection();
@@ -133,7 +135,7 @@ void test_succeeds(void) {
         "pollset_work",
         grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                           gpr_now(GPR_CLOCK_MONOTONIC),
-                          GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5))));
+                          grpc_timeout_seconds_to_deadline(5))));
     gpr_mu_unlock(g_mu);
     grpc_exec_ctx_flush(&exec_ctx);
     gpr_mu_lock(g_mu);
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index 5a55be888fe89b72e23a475211e4a7b58f099f87..2c53a003d23a83dd86a57866c6ca9e1c8ab2ae47 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -183,10 +183,12 @@ static void read_test(size_t num_bytes, size_t slice_size) {
 
   create_sockets(sv);
 
-  grpc_resource_quota *resource_quota = grpc_resource_quota_create("read_test");
-  ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), resource_quota,
-                       slice_size, "test");
-  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
+  grpc_arg a[] = {{.key = GRPC_ARG_TCP_READ_CHUNK_SIZE,
+                   .type = GRPC_ARG_INTEGER,
+                   .value.integer = (int)slice_size}};
+  grpc_channel_args args = {.num_args = GPR_ARRAY_SIZE(a), .args = a};
+  ep = grpc_tcp_create(&exec_ctx, grpc_fd_create(sv[1], "read_test"), &args,
+                       "test");
   grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   written_bytes = fill_socket_partial(sv[0], num_bytes);
@@ -233,11 +235,12 @@ static void large_read_test(size_t slice_size) {
 
   create_sockets(sv);
 
-  grpc_resource_quota *resource_quota =
-      grpc_resource_quota_create("large_read_test");
-  ep = grpc_tcp_create(grpc_fd_create(sv[1], "large_read_test"), resource_quota,
-                       slice_size, "test");
-  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
+  grpc_arg a[] = {{.key = GRPC_ARG_TCP_READ_CHUNK_SIZE,
+                   .type = GRPC_ARG_INTEGER,
+                   .value.integer = (int)slice_size}};
+  grpc_channel_args args = {.num_args = GPR_ARRAY_SIZE(a), .args = a};
+  ep = grpc_tcp_create(&exec_ctx, grpc_fd_create(sv[1], "large_read_test"),
+                       &args, "test");
   grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   written_bytes = fill_socket(sv[0]);
@@ -372,11 +375,12 @@ static void write_test(size_t num_bytes, size_t slice_size) {
 
   create_sockets(sv);
 
-  grpc_resource_quota *resource_quota =
-      grpc_resource_quota_create("write_test");
-  ep = grpc_tcp_create(grpc_fd_create(sv[1], "write_test"), resource_quota,
-                       GRPC_TCP_DEFAULT_READ_SLICE_SIZE, "test");
-  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
+  grpc_arg a[] = {{.key = GRPC_ARG_TCP_READ_CHUNK_SIZE,
+                   .type = GRPC_ARG_INTEGER,
+                   .value.integer = (int)slice_size}};
+  grpc_channel_args args = {.num_args = GPR_ARRAY_SIZE(a), .args = a};
+  ep = grpc_tcp_create(&exec_ctx, grpc_fd_create(sv[1], "write_test"), &args,
+                       "test");
   grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   state.ep = ep;
@@ -441,12 +445,13 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
 
   create_sockets(sv);
 
-  grpc_resource_quota *resource_quota =
-      grpc_resource_quota_create("release_fd_test");
-  ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), resource_quota,
-                       slice_size, "test");
+  grpc_arg a[] = {{.key = GRPC_ARG_TCP_READ_CHUNK_SIZE,
+                   .type = GRPC_ARG_INTEGER,
+                   .value.integer = (int)slice_size}};
+  grpc_channel_args args = {.num_args = GPR_ARRAY_SIZE(a), .args = a};
+  ep = grpc_tcp_create(&exec_ctx, grpc_fd_create(sv[1], "read_test"), &args,
+                       "test");
   GPR_ASSERT(grpc_tcp_fd(ep) == sv[1] && sv[1] >= 0);
-  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   written_bytes = fill_socket_partial(sv[0], num_bytes);
@@ -534,10 +539,14 @@ static grpc_endpoint_test_fixture create_fixture_tcp_socketpair(
   create_sockets(sv);
   grpc_resource_quota *resource_quota =
       grpc_resource_quota_create("tcp_posix_test_socketpair");
-  f.client_ep = grpc_tcp_create(grpc_fd_create(sv[0], "fixture:client"),
-                                resource_quota, slice_size, "test");
-  f.server_ep = grpc_tcp_create(grpc_fd_create(sv[1], "fixture:server"),
-                                resource_quota, slice_size, "test");
+  grpc_arg a[] = {{.key = GRPC_ARG_TCP_READ_CHUNK_SIZE,
+                   .type = GRPC_ARG_INTEGER,
+                   .value.integer = (int)slice_size}};
+  grpc_channel_args args = {.num_args = GPR_ARRAY_SIZE(a), .args = a};
+  f.client_ep = grpc_tcp_create(
+      &exec_ctx, grpc_fd_create(sv[0], "fixture:client"), &args, "test");
+  f.server_ep = grpc_tcp_create(
+      &exec_ctx, grpc_fd_create(sv[1], "fixture:server"), &args, "test");
   grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_endpoint_add_to_pollset(&exec_ctx, f.client_ep, g_pollset);
   grpc_endpoint_add_to_pollset(&exec_ctx, f.server_ep, g_pollset);
diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c
index efadddc0110b4a30c6e774dba11feb42f070374d..112743b95b723a27246dfb82c7a144ba7699f76f 100644
--- a/test/core/iomgr/tcp_server_posix_test.c
+++ b/test/core/iomgr/tcp_server_posix_test.c
@@ -163,7 +163,8 @@ static void test_addr_init_str(test_addr *addr) {
 static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
                        grpc_pollset *pollset,
                        grpc_tcp_server_acceptor *acceptor) {
-  grpc_endpoint_shutdown(exec_ctx, tcp, GRPC_ERROR_CREATE("Connected"));
+  grpc_endpoint_shutdown(exec_ctx, tcp,
+                         GRPC_ERROR_CREATE_FROM_STATIC_STRING("Connected"));
   grpc_endpoint_destroy(exec_ctx, tcp);
 
   on_connect_result temp_result;
@@ -285,7 +286,7 @@ static grpc_error *tcp_connect(grpc_exec_ctx *exec_ctx, const test_addr *remote,
   if (g_nconnects != nconnects_before + 1) {
     gpr_mu_unlock(g_mu);
     close(clifd);
-    return GRPC_ERROR_CREATE("Didn't connect");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Didn't connect");
   }
   close(clifd);
   *result = g_result;
@@ -454,7 +455,8 @@ int main(int argc, char **argv) {
   const grpc_channel_args channel_args = {1, chan_args};
   struct ifaddrs *ifa = NULL;
   struct ifaddrs *ifa_it;
-  test_addrs dst_addrs;
+  // Zalloc dst_addrs to avoid oversized frames.
+  test_addrs *dst_addrs = gpr_zalloc(sizeof(*dst_addrs));
   grpc_test_init(argc, argv);
   grpc_init();
   g_pollset = gpr_zalloc(grpc_pollset_size());
@@ -469,24 +471,25 @@ int main(int argc, char **argv) {
     gpr_log(GPR_ERROR, "getifaddrs: %s", strerror(errno));
     return EXIT_FAILURE;
   }
-  dst_addrs.naddrs = 0;
-  for (ifa_it = ifa; ifa_it != NULL && dst_addrs.naddrs < MAX_ADDRS;
+  dst_addrs->naddrs = 0;
+  for (ifa_it = ifa; ifa_it != NULL && dst_addrs->naddrs < MAX_ADDRS;
        ifa_it = ifa_it->ifa_next) {
     if (ifa_it->ifa_addr == NULL) {
       continue;
     } else if (ifa_it->ifa_addr->sa_family == AF_INET) {
-      dst_addrs.addrs[dst_addrs.naddrs].addr.len = sizeof(struct sockaddr_in);
+      dst_addrs->addrs[dst_addrs->naddrs].addr.len = sizeof(struct sockaddr_in);
     } else if (ifa_it->ifa_addr->sa_family == AF_INET6) {
-      dst_addrs.addrs[dst_addrs.naddrs].addr.len = sizeof(struct sockaddr_in6);
+      dst_addrs->addrs[dst_addrs->naddrs].addr.len =
+          sizeof(struct sockaddr_in6);
     } else {
       continue;
     }
-    memcpy(dst_addrs.addrs[dst_addrs.naddrs].addr.addr, ifa_it->ifa_addr,
-           dst_addrs.addrs[dst_addrs.naddrs].addr.len);
+    memcpy(dst_addrs->addrs[dst_addrs->naddrs].addr.addr, ifa_it->ifa_addr,
+           dst_addrs->addrs[dst_addrs->naddrs].addr.len);
     GPR_ASSERT(
-        grpc_sockaddr_set_port(&dst_addrs.addrs[dst_addrs.naddrs].addr, 0));
-    test_addr_init_str(&dst_addrs.addrs[dst_addrs.naddrs]);
-    ++dst_addrs.naddrs;
+        grpc_sockaddr_set_port(&dst_addrs->addrs[dst_addrs->naddrs].addr, 0));
+    test_addr_init_str(&dst_addrs->addrs[dst_addrs->naddrs]);
+    ++dst_addrs->naddrs;
   }
   freeifaddrs(ifa);
   ifa = NULL;
@@ -495,20 +498,21 @@ int main(int argc, char **argv) {
   test_connect(1, NULL, NULL, false);
   test_connect(10, NULL, NULL, false);
 
-  /* Set dst_addrs.addrs[i].len=0 for dst_addrs that are unreachable with a "::"
-     listener. */
-  test_connect(1, NULL, &dst_addrs, true);
+  /* Set dst_addrs->addrs[i].len=0 for dst_addrs that are unreachable with a
+     "::" listener. */
+  test_connect(1, NULL, dst_addrs, true);
 
   /* Test connect(2) with dst_addrs. */
-  test_connect(1, &channel_args, &dst_addrs, false);
+  test_connect(1, &channel_args, dst_addrs, false);
   /* Test connect(2) with dst_addrs. */
-  test_connect(10, &channel_args, &dst_addrs, false);
+  test_connect(10, &channel_args, dst_addrs, false);
 
   grpc_closure_init(&destroyed, destroy_pollset, g_pollset,
                     grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
+  gpr_free(dst_addrs);
   gpr_free(g_pollset);
   return EXIT_SUCCESS;
 }
diff --git a/test/core/iomgr/tcp_server_uv_test.c b/test/core/iomgr/tcp_server_uv_test.c
index 7b458c90f3deb2473ce2fc604129969ad098ce29..1e039585c1e8dae2e738ef148de95a300dad2eee 100644
--- a/test/core/iomgr/tcp_server_uv_test.c
+++ b/test/core/iomgr/tcp_server_uv_test.c
@@ -115,7 +115,8 @@ static void server_weak_ref_set(server_weak_ref *weak_ref,
 static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
                        grpc_pollset *pollset,
                        grpc_tcp_server_acceptor *acceptor) {
-  grpc_endpoint_shutdown(exec_ctx, tcp);
+  grpc_endpoint_shutdown(exec_ctx, tcp,
+                         GRPC_ERROR_CREATE_FROM_STATIC_STRING("Connected"));
   grpc_endpoint_destroy(exec_ctx, tcp);
 
   on_connect_result temp_result;
@@ -203,7 +204,7 @@ static void close_cb(uv_handle_t *handle) { gpr_free(handle); }
 
 static void tcp_connect(grpc_exec_ctx *exec_ctx, const struct sockaddr *remote,
                         socklen_t remote_len, on_connect_result *result) {
-  gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
+  gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10);
   uv_tcp_t *client_handle = gpr_malloc(sizeof(uv_tcp_t));
   uv_connect_t *req = gpr_malloc(sizeof(uv_connect_t));
   int nconnects_before;
diff --git a/test/core/iomgr/timer_heap_test.c b/test/core/iomgr/timer_heap_test.c
index 410d972313b37d27b96f08aa1a76ef1fde3cabb7..153304fa7b41483916aac0eb6871a0324f2dc57c 100644
--- a/test/core/iomgr/timer_heap_test.c
+++ b/test/core/iomgr/timer_heap_test.c
@@ -47,13 +47,7 @@
 
 #include "test/core/util/test_config.h"
 
-static gpr_timespec random_deadline(void) {
-  gpr_timespec ts;
-  ts.tv_sec = rand();
-  ts.tv_nsec = rand();
-  ts.clock_type = GPR_CLOCK_REALTIME;
-  return ts;
-}
+static gpr_atm random_deadline(void) { return rand(); }
 
 static grpc_timer *create_test_elements(size_t num_elements) {
   grpc_timer *elems = gpr_malloc(num_elements * sizeof(grpc_timer));
@@ -78,12 +72,10 @@ static void check_valid(grpc_timer_heap *pq) {
     size_t left_child = 1u + 2u * i;
     size_t right_child = left_child + 1u;
     if (left_child < pq->timer_count) {
-      GPR_ASSERT(gpr_time_cmp(pq->timers[i]->deadline,
-                              pq->timers[left_child]->deadline) <= 0);
+      GPR_ASSERT(pq->timers[i]->deadline <= pq->timers[left_child]->deadline);
     }
     if (right_child < pq->timer_count) {
-      GPR_ASSERT(gpr_time_cmp(pq->timers[i]->deadline,
-                              pq->timers[right_child]->deadline) <= 0);
+      GPR_ASSERT(pq->timers[i]->deadline <= pq->timers[right_child]->deadline);
     }
   }
 }
@@ -227,20 +219,19 @@ static void test2(void) {
     }
 
     if (num_inserted) {
-      gpr_timespec *min_deadline = NULL;
+      gpr_atm *min_deadline = NULL;
       for (size_t i = 0; i < elems_size; i++) {
         if (elems[i].inserted) {
           if (min_deadline == NULL) {
             min_deadline = &elems[i].elem.deadline;
           } else {
-            if (gpr_time_cmp(elems[i].elem.deadline, *min_deadline) < 0) {
+            if (elems[i].elem.deadline < *min_deadline) {
               min_deadline = &elems[i].elem.deadline;
             }
           }
         }
       }
-      GPR_ASSERT(
-          0 == gpr_time_cmp(grpc_timer_heap_top(&pq)->deadline, *min_deadline));
+      GPR_ASSERT(grpc_timer_heap_top(&pq)->deadline == *min_deadline);
     }
   }
 
diff --git a/test/core/iomgr/timer_list_test.c b/test/core/iomgr/timer_list_test.c
index 85ad5277cc058a10e67c10104e327409eaf8cf02..46e41dd4490bc320b39d42fb3af32e3180e9d415 100644
--- a/test/core/iomgr/timer_list_test.c
+++ b/test/core/iomgr/timer_list_test.c
@@ -45,6 +45,9 @@
 
 #define MAX_CB 30
 
+extern int grpc_timer_trace;
+extern int grpc_timer_check_trace;
+
 static int cb_called[MAX_CB][2];
 
 static void cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
@@ -57,7 +60,11 @@ static void add_test(void) {
   grpc_timer timers[20];
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
+  gpr_log(GPR_INFO, "add_test");
+
   grpc_timer_list_init(start);
+  grpc_timer_trace = 1;
+  grpc_timer_check_trace = 1;
   memset(cb_called, 0, sizeof(cb_called));
 
   /* 10 ms timers.  will expire in the current epoch */
@@ -120,9 +127,7 @@ static void add_test(void) {
 }
 
 static gpr_timespec tfm(int m) {
-  gpr_timespec t = gpr_time_from_millis(m, GPR_TIMESPAN);
-  t.clock_type = GPR_CLOCK_REALTIME;
-  return t;
+  return gpr_time_from_millis(m, GPR_CLOCK_REALTIME);
 }
 
 /* Cleaning up a list with pending timers. */
@@ -130,7 +135,11 @@ void destruction_test(void) {
   grpc_timer timers[5];
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
+  gpr_log(GPR_INFO, "destruction_test");
+
   grpc_timer_list_init(gpr_time_0(GPR_CLOCK_REALTIME));
+  grpc_timer_trace = 1;
+  grpc_timer_check_trace = 1;
   memset(cb_called, 0, sizeof(cb_called));
 
   grpc_timer_init(
@@ -170,6 +179,7 @@ void destruction_test(void) {
 
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
+  gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG);
   add_test();
   destruction_test();
   return 0;
diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c
index d57a37b2a97b6f7ffedf1449e7caee47cf309525..1f1696a7a7a0b86cf1a4c54d03268ff10c536bb4 100644
--- a/test/core/iomgr/udp_server_test.c
+++ b/test/core/iomgr/udp_server_test.c
@@ -48,9 +48,12 @@
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
+#include <grpc/support/useful.h>
 
+#include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/ev_posix.h"
 #include "src/core/lib/iomgr/iomgr.h"
+#include "src/core/lib/iomgr/socket_factory_posix.h"
 #include "test/core/util/test_config.h"
 
 #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", #x)
@@ -62,8 +65,7 @@ static int g_number_of_writes = 0;
 static int g_number_of_bytes_read = 0;
 static int g_number_of_orphan_calls = 0;
 
-static void on_read(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
-                    grpc_server *server) {
+static void on_read(grpc_exec_ctx *exec_ctx, grpc_fd *emfd, void *user_data) {
   char read_buffer[512];
   ssize_t byte_count;
 
@@ -79,7 +81,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
   gpr_mu_unlock(g_mu);
 }
 
-static void on_write(grpc_exec_ctx *exec_ctx, grpc_fd *emfd) {
+static void on_write(grpc_exec_ctx *exec_ctx, grpc_fd *emfd, void *user_data) {
   gpr_mu_lock(g_mu);
   g_number_of_writes++;
 
@@ -88,22 +90,66 @@ static void on_write(grpc_exec_ctx *exec_ctx, grpc_fd *emfd) {
   gpr_mu_unlock(g_mu);
 }
 
-static void on_fd_orphaned(grpc_exec_ctx *exec_ctx, grpc_fd *emfd) {
+static void on_fd_orphaned(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
+                           grpc_closure *closure, void *user_data) {
   gpr_log(GPR_INFO, "gRPC FD about to be orphaned: %d",
           grpc_fd_wrapped_fd(emfd));
   g_number_of_orphan_calls++;
 }
 
+struct test_socket_factory {
+  grpc_socket_factory base;
+  int number_of_socket_calls;
+  int number_of_bind_calls;
+};
+typedef struct test_socket_factory test_socket_factory;
+
+static int test_socket_factory_socket(grpc_socket_factory *factory, int domain,
+                                      int type, int protocol) {
+  test_socket_factory *f = (test_socket_factory *)factory;
+  f->number_of_socket_calls++;
+  return socket(domain, type, protocol);
+}
+
+static int test_socket_factory_bind(grpc_socket_factory *factory, int sockfd,
+                                    const grpc_resolved_address *addr) {
+  test_socket_factory *f = (test_socket_factory *)factory;
+  f->number_of_bind_calls++;
+  return bind(sockfd, (struct sockaddr *)addr->addr, (socklen_t)addr->len);
+}
+
+static int test_socket_factory_compare(grpc_socket_factory *a,
+                                       grpc_socket_factory *b) {
+  return GPR_ICMP(a, b);
+}
+
+static void test_socket_factory_destroy(grpc_socket_factory *factory) {
+  test_socket_factory *f = (test_socket_factory *)factory;
+  gpr_free(f);
+}
+
+static const grpc_socket_factory_vtable test_socket_factory_vtable = {
+    test_socket_factory_socket, test_socket_factory_bind,
+    test_socket_factory_compare, test_socket_factory_destroy};
+
+static test_socket_factory *test_socket_factory_create(void) {
+  test_socket_factory *factory = gpr_malloc(sizeof(test_socket_factory));
+  grpc_socket_factory_init(&factory->base, &test_socket_factory_vtable);
+  factory->number_of_socket_calls = 0;
+  factory->number_of_bind_calls = 0;
+  return factory;
+}
+
 static void test_no_op(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_udp_server *s = grpc_udp_server_create();
+  grpc_udp_server *s = grpc_udp_server_create(NULL);
   grpc_udp_server_destroy(&exec_ctx, s, NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_no_op_with_start(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_udp_server *s = grpc_udp_server_create();
+  grpc_udp_server *s = grpc_udp_server_create(NULL);
   LOG_TEST("test_no_op_with_start");
   grpc_udp_server_start(&exec_ctx, s, NULL, 0, NULL);
   grpc_udp_server_destroy(&exec_ctx, s, NULL);
@@ -115,7 +161,7 @@ static void test_no_op_with_port(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_resolved_address resolved_addr;
   struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr;
-  grpc_udp_server *s = grpc_udp_server_create();
+  grpc_udp_server *s = grpc_udp_server_create(NULL);
   LOG_TEST("test_no_op_with_port");
 
   memset(&resolved_addr, 0, sizeof(resolved_addr));
@@ -131,12 +177,44 @@ static void test_no_op_with_port(void) {
   GPR_ASSERT(g_number_of_orphan_calls == 1);
 }
 
+static void test_no_op_with_port_and_socket_factory(void) {
+  g_number_of_orphan_calls = 0;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_resolved_address resolved_addr;
+  struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr;
+
+  test_socket_factory *socket_factory = test_socket_factory_create();
+  grpc_arg socket_factory_arg =
+      grpc_socket_factory_to_arg(&socket_factory->base);
+  grpc_channel_args *channel_args =
+      grpc_channel_args_copy_and_add(NULL, &socket_factory_arg, 1);
+  grpc_udp_server *s = grpc_udp_server_create(channel_args);
+  grpc_channel_args_destroy(&exec_ctx, channel_args);
+
+  LOG_TEST("test_no_op_with_port_and_socket_factory");
+
+  memset(&resolved_addr, 0, sizeof(resolved_addr));
+  resolved_addr.len = sizeof(struct sockaddr_in);
+  addr->sin_family = AF_INET;
+  GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, on_read, on_write,
+                                      on_fd_orphaned));
+  GPR_ASSERT(socket_factory->number_of_socket_calls == 1);
+  GPR_ASSERT(socket_factory->number_of_bind_calls == 1);
+
+  grpc_udp_server_destroy(&exec_ctx, s, NULL);
+  grpc_exec_ctx_finish(&exec_ctx);
+  grpc_socket_factory_unref(&socket_factory->base);
+
+  /* The server had a single FD, which should have been orphaned. */
+  GPR_ASSERT(g_number_of_orphan_calls == 1);
+}
+
 static void test_no_op_with_port_and_start(void) {
   g_number_of_orphan_calls = 0;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_resolved_address resolved_addr;
   struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr;
-  grpc_udp_server *s = grpc_udp_server_create();
+  grpc_udp_server *s = grpc_udp_server_create(NULL);
   LOG_TEST("test_no_op_with_port_and_start");
 
   memset(&resolved_addr, 0, sizeof(resolved_addr));
@@ -150,9 +228,9 @@ static void test_no_op_with_port_and_start(void) {
   grpc_udp_server_destroy(&exec_ctx, s, NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 
-  /* The server had a single FD, which is orphaned once in *
-   * deactivated_all_ports, and once in grpc_udp_server_destroy. */
-  GPR_ASSERT(g_number_of_orphan_calls == 2);
+  /* The server had a single FD, which is orphaned exactly once in *
+   * grpc_udp_server_destroy. */
+  GPR_ASSERT(g_number_of_orphan_calls == 1);
 }
 
 static void test_receive(int number_of_clients) {
@@ -160,7 +238,7 @@ static void test_receive(int number_of_clients) {
   grpc_resolved_address resolved_addr;
   struct sockaddr_storage *addr = (struct sockaddr_storage *)resolved_addr.addr;
   int clifd, svrfd;
-  grpc_udp_server *s = grpc_udp_server_create();
+  grpc_udp_server *s = grpc_udp_server_create(NULL);
   int i;
   int number_of_reads_before;
   gpr_timespec deadline;
@@ -219,9 +297,9 @@ static void test_receive(int number_of_clients) {
   grpc_udp_server_destroy(&exec_ctx, s, NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 
-  /* The server had a single FD, which is orphaned once in *
-   * deactivated_all_ports, and once in grpc_udp_server_destroy. */
-  GPR_ASSERT(g_number_of_orphan_calls == 2);
+  /* The server had a single FD, which is orphaned exactly once in *
+   * grpc_udp_server_destroy. */
+  GPR_ASSERT(g_number_of_orphan_calls == 1);
 
   /* The write callback should have fired a few times. */
   GPR_ASSERT(g_number_of_writes > 0);
@@ -243,6 +321,7 @@ int main(int argc, char **argv) {
   test_no_op();
   test_no_op_with_start();
   test_no_op_with_port();
+  test_no_op_with_port_and_socket_factory();
   test_no_op_with_port_and_start();
   test_receive(1);
   test_receive(10);
diff --git a/test/core/memory_usage/client.c b/test/core/memory_usage/client.c
index 09f0e2d8670f52d792e8b1b0a2b374566edf31c8..ee68399988b9ae43ddd7549fb457dbbddb95a849 100644
--- a/test/core/memory_usage/client.c
+++ b/test/core/memory_usage/client.c
@@ -43,6 +43,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
+#include "src/core/lib/support/env.h"
 #include "src/core/lib/support/string.h"
 #include "test/core/util/memory_counters.h"
 #include "test/core/util/test_config.h"
@@ -119,7 +120,7 @@ static void finish_ping_pong_request(int call_idx) {
   grpc_metadata_array_destroy(&calls[call_idx].initial_metadata_recv);
   grpc_metadata_array_destroy(&calls[call_idx].trailing_metadata_recv);
   grpc_slice_unref(calls[call_idx].details);
-  grpc_call_destroy(calls[call_idx].call);
+  grpc_call_unref(calls[call_idx].call);
   calls[call_idx].call = NULL;
 }
 
@@ -186,7 +187,7 @@ static struct grpc_memory_counters send_snapshot_request(int call_idx,
   grpc_byte_buffer_destroy(response_payload_recv);
   grpc_slice_unref(calls[call_idx].details);
   calls[call_idx].details = grpc_empty_slice();
-  grpc_call_destroy(calls[call_idx].call);
+  grpc_call_unref(calls[call_idx].call);
   calls[call_idx].call = NULL;
 
   return snapshot;
@@ -222,7 +223,7 @@ int main(int argc, char **argv) {
     calls[k].details = grpc_empty_slice();
   }
 
-  cq = grpc_completion_queue_create(NULL);
+  cq = grpc_completion_queue_create_for_next(NULL);
 
   struct grpc_memory_counters client_channel_start =
       grpc_memory_counters_snapshot();
@@ -236,6 +237,11 @@ int main(int argc, char **argv) {
       0, grpc_slice_from_static_string("Reflector/GetAfterSvrCreation"));
 
   // warmup period
+  for (int i = 0; i < warmup_iterations; i++) {
+    send_snapshot_request(
+        0, grpc_slice_from_static_string("Reflector/SimpleSnapshot"));
+  }
+
   for (call_idx = 0; call_idx < warmup_iterations; ++call_idx) {
     init_ping_pong_request(call_idx + 1);
   }
@@ -310,6 +316,29 @@ int main(int argc, char **argv) {
           server_calls_end.total_size_relative -
               after_server_create.total_size_relative);
 
+  const char *csv_file = "memory_usage.csv";
+  FILE *csv = fopen(csv_file, "w");
+  if (csv) {
+    char *env_build = gpr_getenv("BUILD_NUMBER");
+    char *env_job = gpr_getenv("JOB_NAME");
+    fprintf(csv, "%f,%zi,%zi,%f,%zi,%s,%s\n",
+            (double)(client_calls_inflight.total_size_relative -
+                     client_benchmark_calls_start.total_size_relative) /
+                benchmark_iterations,
+            client_channel_end.total_size_relative -
+                client_channel_start.total_size_relative,
+            after_server_create.total_size_relative -
+                before_server_create.total_size_relative,
+            (double)(server_calls_inflight.total_size_relative -
+                     server_benchmark_calls_start.total_size_relative) /
+                benchmark_iterations,
+            server_calls_end.total_size_relative -
+                after_server_create.total_size_relative,
+            env_build == NULL ? "" : env_build, env_job == NULL ? "" : env_job);
+    fclose(csv);
+    gpr_log(GPR_INFO, "Summary written to %s", csv_file);
+  }
+
   grpc_memory_counters_destroy();
   return 0;
 }
diff --git a/test/core/memory_usage/server.c b/test/core/memory_usage/server.c
index ab059c25b8b13b34d6d061b0a92e8d23650b33e8..1c70f5eac0d60a332f9ff1f2ea45627564496938 100644
--- a/test/core/memory_usage/server.c
+++ b/test/core/memory_usage/server.c
@@ -161,6 +161,7 @@ int main(int argc, char **argv) {
   grpc_event ev;
   char *addr_buf = NULL;
   gpr_cmdline *cl;
+  grpc_completion_queue *shutdown_cq;
   int shutdown_started = 0;
   int shutdown_finished = 0;
 
@@ -188,7 +189,7 @@ int main(int argc, char **argv) {
   }
   gpr_log(GPR_INFO, "creating server on: %s", addr);
 
-  cq = grpc_completion_queue_create(NULL);
+  cq = grpc_completion_queue_create_for_next(NULL);
 
   struct grpc_memory_counters before_server_create =
       grpc_memory_counters_snapshot();
@@ -230,10 +231,14 @@ int main(int argc, char **argv) {
   while (!shutdown_finished) {
     if (got_sigint && !shutdown_started) {
       gpr_log(GPR_INFO, "Shutting down due to SIGINT");
-      grpc_server_shutdown_and_notify(server, cq, tag(1000));
-      GPR_ASSERT(grpc_completion_queue_pluck(
-                     cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
-                     .type == GRPC_OP_COMPLETE);
+
+      shutdown_cq = grpc_completion_queue_create_for_pluck(NULL);
+      grpc_server_shutdown_and_notify(server, shutdown_cq, tag(1000));
+      GPR_ASSERT(
+          grpc_completion_queue_pluck(shutdown_cq, tag(1000),
+                                      grpc_timeout_seconds_to_deadline(5), NULL)
+              .type == GRPC_OP_COMPLETE);
+      grpc_completion_queue_destroy(shutdown_cq);
       grpc_completion_queue_shutdown(cq);
       shutdown_started = 1;
     }
@@ -281,7 +286,7 @@ int main(int argc, char **argv) {
           case FLING_SERVER_WAIT_FOR_DESTROY:
             break;
           case FLING_SERVER_SEND_STATUS_FLING_CALL:
-            grpc_call_destroy(s->call);
+            grpc_call_unref(s->call);
             grpc_call_details_destroy(&s->call_details);
             grpc_metadata_array_destroy(&s->initial_metadata_send);
             grpc_metadata_array_destroy(&s->request_metadata_recv);
@@ -299,7 +304,7 @@ int main(int argc, char **argv) {
           case FLING_SERVER_SEND_STATUS_SNAPSHOT:
             grpc_byte_buffer_destroy(payload_buffer);
             grpc_byte_buffer_destroy(terminal_buffer);
-            grpc_call_destroy(s->call);
+            grpc_call_unref(s->call);
             grpc_call_details_destroy(&s->call_details);
             grpc_metadata_array_destroy(&s->initial_metadata_send);
             grpc_metadata_array_destroy(&s->request_metadata_recv);
diff --git a/test/core/nanopb/fuzzer_response.c b/test/core/nanopb/fuzzer_response.c
index 202c120c670fe2417f4dc9f1e34ceec3678359ba..35c0efe90d930da430facc65aa070f6560437fe7 100644
--- a/test/core/nanopb/fuzzer_response.c
+++ b/test/core/nanopb/fuzzer_response.c
@@ -36,7 +36,7 @@
 
 #include <grpc/support/alloc.h>
 
-#include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h"
 
 bool squelch = true;
 bool leak_check = true;
diff --git a/test/core/nanopb/fuzzer_serverlist.c b/test/core/nanopb/fuzzer_serverlist.c
index b225ae0d519b63640beb97ea1042f9c71c58590b..e1df401968de3588f6de6e766e3a90fc9bd4d6e3 100644
--- a/test/core/nanopb/fuzzer_serverlist.c
+++ b/test/core/nanopb/fuzzer_serverlist.c
@@ -36,7 +36,7 @@
 
 #include <grpc/support/alloc.h>
 
-#include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h"
 
 bool squelch = true;
 bool leak_check = true;
diff --git a/test/core/security/BUILD b/test/core/security/BUILD
index e750c39b7c61c24aa3df66695727da575c43f3bb..a81e1d366b0926e3c79420034e063bb9562954c1 100644
--- a/test/core/security/BUILD
+++ b/test/core/security/BUILD
@@ -34,7 +34,7 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
 grpc_fuzzer(
   name = "ssl_server_fuzzer",
   srcs = ["ssl_server_fuzzer.c"],
-  deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util"],
+  deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util", "//test/core/end2end:ssl_test_data"],
   corpus = "corpus",
   copts = ["-std=c99"],
 )
@@ -44,7 +44,8 @@ cc_library(
     srcs = ["oauth2_utils.c"],
     hdrs = ["oauth2_utils.h"],
     deps = ["//:grpc"],
-    copts = ['-std=c99']
+    copts = ['-std=c99'],
+    visibility = ["//test/cpp:__subpackages__"],
 )
 
 cc_test(
@@ -54,13 +55,6 @@ cc_test(
     copts = ['-std=c99']
 )
 
-cc_test(
-    name = "b64_test",
-    srcs = ["b64_test.c"],
-    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
-    copts = ['-std=c99']
-)
-
 cc_test(
     name = "credentials_test",
     srcs = ["credentials_test.c"],
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index c0933c64a6884e31bb622f28455c2e7387c1693c..9bdce71ba0cd55d0017c72b9d14dc13b292f6b84 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -582,7 +582,7 @@ static void on_oauth2_creds_get_metadata_failure(
 static void validate_compute_engine_http_request(
     const grpc_httpcli_request *request) {
   GPR_ASSERT(request->handshaker != &grpc_httpcli_ssl);
-  GPR_ASSERT(strcmp(request->host, "metadata") == 0);
+  GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0);
   GPR_ASSERT(
       strcmp(request->http.path,
              "/computeMetadata/v1/instance/service-accounts/default/token") ==
diff --git a/test/core/security/json_token_test.c b/test/core/security/json_token_test.c
index 5cebb09bb253301084423bedebb188342f79a835..97dfe87896c318cdc075fad48ba227c913e4e212 100644
--- a/test/core/security/json_token_test.c
+++ b/test/core/security/json_token_test.c
@@ -43,7 +43,7 @@
 
 #include "src/core/lib/json/json.h"
 #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
-#include "src/core/lib/security/util/b64.h"
+#include "src/core/lib/slice/b64.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "test/core/util/test_config.h"
 
diff --git a/test/core/security/jwt_verifier_test.c b/test/core/security/jwt_verifier_test.c
index 0a73f675280df4700d6da54d1fb294fee93c8532..7eec780a91e270e4bdef752bf391a7c978de10ea 100644
--- a/test/core/security/jwt_verifier_test.c
+++ b/test/core/security/jwt_verifier_test.c
@@ -44,7 +44,7 @@
 
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/security/credentials/jwt/json_token.h"
-#include "src/core/lib/security/util/b64.h"
+#include "src/core/lib/slice/b64.h"
 #include "test/core/util/test_config.h"
 
 /* This JSON key was generated with the GCE console and revoked immediately.
diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c
index d2b76bae39c48834cabdf527b008a12cd0f0adb8..71d8057ac3140b74d3c6712ccb835675b74e4588 100644
--- a/test/core/security/secure_endpoint_test.c
+++ b/test/core/security/secure_endpoint_test.c
@@ -39,11 +39,12 @@
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include <grpc/support/useful.h>
 #include "src/core/lib/iomgr/endpoint_pair.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/security/transport/secure_endpoint.h"
 #include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/tsi/fake_transport_security.h"
+#include "src/core/tsi/fake_transport_security.h"
 #include "test/core/util/test_config.h"
 
 static gpr_mu *g_mu;
@@ -57,10 +58,11 @@ static grpc_endpoint_test_fixture secure_endpoint_create_fixture_tcp_socketpair(
   grpc_endpoint_test_fixture f;
   grpc_endpoint_pair tcp;
 
-  grpc_resource_quota *resource_quota =
-      grpc_resource_quota_create("secure_endpoint_test");
-  tcp = grpc_iomgr_create_endpoint_pair("fixture", resource_quota, slice_size);
-  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
+  grpc_arg a[] = {{.key = GRPC_ARG_TCP_READ_CHUNK_SIZE,
+                   .type = GRPC_ARG_INTEGER,
+                   .value.integer = (int)slice_size}};
+  grpc_channel_args args = {.num_args = GPR_ARRAY_SIZE(a), .args = a};
+  tcp = grpc_iomgr_create_endpoint_pair("fixture", &args);
   grpc_endpoint_add_to_pollset(&exec_ctx, tcp.client, g_pollset);
   grpc_endpoint_add_to_pollset(&exec_ctx, tcp.server, g_pollset);
 
@@ -166,10 +168,12 @@ static void test_leftover(grpc_endpoint_test_config config, size_t slice_size) {
   GPR_ASSERT(incoming.count == 1);
   GPR_ASSERT(grpc_slice_eq(s, incoming.slices[0]));
 
-  grpc_endpoint_shutdown(&exec_ctx, f.client_ep,
-                         GRPC_ERROR_CREATE("test_leftover end"));
-  grpc_endpoint_shutdown(&exec_ctx, f.server_ep,
-                         GRPC_ERROR_CREATE("test_leftover end"));
+  grpc_endpoint_shutdown(
+      &exec_ctx, f.client_ep,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("test_leftover end"));
+  grpc_endpoint_shutdown(
+      &exec_ctx, f.server_ep,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("test_leftover end"));
   grpc_endpoint_destroy(&exec_ctx, f.client_ep);
   grpc_endpoint_destroy(&exec_ctx, f.server_ep);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/security/security_connector_test.c b/test/core/security/security_connector_test.c
index 4219b134f2504ae08b021f384e62f57348420bd1..6c7b8e688f0de448d7e320f42bad088a1269cf49 100644
--- a/test/core/security/security_connector_test.c
+++ b/test/core/security/security_connector_test.c
@@ -46,8 +46,8 @@
 #include "src/core/lib/support/env.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/support/tmpfile.h"
-#include "src/core/lib/tsi/ssl_transport_security.h"
-#include "src/core/lib/tsi/transport_security.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) {
diff --git a/test/core/security/ssl_server_fuzzer.c b/test/core/security/ssl_server_fuzzer.c
index f789278add8f8abd1a71298d411224c1aabed78d..cbbaf9f298cd988b72d6e14aa8ba49d2e09b105d 100644
--- a/test/core/security/ssl_server_fuzzer.c
+++ b/test/core/security/ssl_server_fuzzer.c
@@ -38,6 +38,7 @@
 #include "src/core/lib/iomgr/load_file.h"
 #include "src/core/lib/security/credentials/credentials.h"
 #include "src/core/lib/security/transport/security_connector.h"
+#include "test/core/end2end/data/ssl_test_data.h"
 #include "test/core/util/memory_counters.h"
 #include "test/core/util/mock_endpoint.h"
 
@@ -46,10 +47,6 @@ bool squelch = true;
 // Turning this on will fail the leak check.
 bool leak_check = false;
 
-#define SSL_CERT_PATH "src/core/lib/tsi/test_creds/server1.pem"
-#define SSL_KEY_PATH "src/core/lib/tsi/test_creds/server1.key"
-#define SSL_CA_PATH "src/core/lib/tsi/test_creds/ca.pem"
-
 static void discard_write(grpc_slice slice) {}
 
 static void dont_log(gpr_log_func_args *args) {}
@@ -88,12 +85,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   // Load key pair and establish server SSL credentials.
   grpc_ssl_pem_key_cert_pair pem_key_cert_pair;
   grpc_slice ca_slice, cert_slice, key_slice;
-  GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
-                               grpc_load_file(SSL_CA_PATH, 1, &ca_slice)));
-  GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
-                               grpc_load_file(SSL_CERT_PATH, 1, &cert_slice)));
-  GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
-                               grpc_load_file(SSL_KEY_PATH, 1, &key_slice)));
+  ca_slice = grpc_slice_from_static_string(test_root_cert);
+  cert_slice = grpc_slice_from_static_string(test_server1_cert);
+  key_slice = grpc_slice_from_static_string(test_server1_key);
   const char *ca_cert = (const char *)GRPC_SLICE_START_PTR(ca_slice);
   pem_key_cert_pair.private_key = (const char *)GRPC_SLICE_START_PTR(key_slice);
   pem_key_cert_pair.cert_chain = (const char *)GRPC_SLICE_START_PTR(cert_slice);
@@ -121,8 +115,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   // server will wait for more data. Explicitly fail the server by shutting down
   // the endpoint.
   if (!state.done_callback_called) {
-    grpc_endpoint_shutdown(&exec_ctx, mock_endpoint,
-                           GRPC_ERROR_CREATE("Explicit close"));
+    grpc_endpoint_shutdown(
+        &exec_ctx, mock_endpoint,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Explicit close"));
     grpc_exec_ctx_flush(&exec_ctx);
   }
 
diff --git a/test/core/slice/BUILD b/test/core/slice/BUILD
index 67a47063482c3b5bc7440409830be608b7ba7462..18cf6f60af0bb92b5cde453968e060294927b5bb 100644
--- a/test/core/slice/BUILD
+++ b/test/core/slice/BUILD
@@ -47,8 +47,36 @@ cc_test(
 )
 
 cc_test(
-    name = "slice_buffer_test",
+    name = "slice_test",
+    srcs = ["slice_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "slice_string_helpers_test",
     srcs = ["slice_string_helpers_test.c"],
     deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
     copts = ['-std=c99']
 )
+
+cc_test(
+    name = "slice_buffer_test",
+    srcs = ["slice_buffer_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "slice_hash_table_test",
+    srcs = ["slice_hash_table_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "b64_test",
+    srcs = ["b64_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
diff --git a/test/core/security/b64_test.c b/test/core/slice/b64_test.c
similarity index 99%
rename from test/core/security/b64_test.c
rename to test/core/slice/b64_test.c
index 28af48075ebf51b13bd553455865ded94c48c172..9e5c06551c793c12c0ae97c36e162ed81309dcf1 100644
--- a/test/core/security/b64_test.c
+++ b/test/core/slice/b64_test.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/lib/security/util/b64.h"
+#include "src/core/lib/slice/b64.h"
 
 #include <string.h>
 
diff --git a/test/core/slice/percent_encoding_test.c b/test/core/slice/percent_encoding_test.c
index 222e695fd427bd439593c96a746f11f34e5dfa15..89f81549552bbb2e037c6d405b7d88e61b6f4fc7 100644
--- a/test/core/slice/percent_encoding_test.c
+++ b/test/core/slice/percent_encoding_test.c
@@ -146,6 +146,7 @@ int main(int argc, char **argv) {
   TEST_VECTOR("\x0f", "%0F", grpc_url_percent_encoding_unreserved_bytes);
   TEST_VECTOR("\xff", "%FF", grpc_url_percent_encoding_unreserved_bytes);
   TEST_VECTOR("\xee", "%EE", grpc_url_percent_encoding_unreserved_bytes);
+  TEST_VECTOR("%2", "%252", grpc_url_percent_encoding_unreserved_bytes);
   TEST_NONCONFORMANT_VECTOR("%", "%",
                             grpc_url_percent_encoding_unreserved_bytes);
   TEST_NONCONFORMANT_VECTOR("%A", "%A",
diff --git a/test/core/slice/slice_buffer_test.c b/test/core/slice/slice_buffer_test.c
index bf9ae197d21e3d214a970a3b4537fc230377cbe3..41cff3d4d22e30a441158aea1d7a35c229890851 100644
--- a/test/core/slice/slice_buffer_test.c
+++ b/test/core/slice/slice_buffer_test.c
@@ -115,8 +115,8 @@ void test_slice_buffer_move_first() {
   grpc_slice_buffer_move_first(&src, 2, &dst);
   src_len -= 2;
   dst_len += 2;
-  GPR_ASSERT(src.length == src.length);
-  GPR_ASSERT(dst.length == dst.length);
+  GPR_ASSERT(src.length == src_len);
+  GPR_ASSERT(dst.length == dst_len);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/slice/slice_hash_table_test.c b/test/core/slice/slice_hash_table_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..67041b2d5c998c07d7b7e21938e30c405ff82547
--- /dev/null
+++ b/test/core/slice/slice_hash_table_test.c
@@ -0,0 +1,138 @@
+/*
+ *
+ * Copyright 2017, 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/lib/slice/slice_hash_table.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/lib/slice/slice_internal.h"
+#include "test/core/util/test_config.h"
+
+typedef struct {
+  char* key;
+  char* value;
+} test_entry;
+
+static void populate_entries(const test_entry* input, size_t num_entries,
+                             grpc_slice_hash_table_entry* output) {
+  for (size_t i = 0; i < num_entries; ++i) {
+    output[i].key = grpc_slice_from_copied_string(input[i].key);
+    output[i].value = gpr_strdup(input[i].value);
+  }
+}
+
+static void check_values(const test_entry* input, size_t num_entries,
+                         grpc_slice_hash_table* table) {
+  for (size_t i = 0; i < num_entries; ++i) {
+    grpc_slice key = grpc_slice_from_static_string(input[i].key);
+    char* actual = grpc_slice_hash_table_get(table, key);
+    GPR_ASSERT(actual != NULL);
+    GPR_ASSERT(strcmp(actual, input[i].value) == 0);
+    grpc_slice_unref(key);
+  }
+}
+
+static void check_non_existent_value(const char* key_string,
+                                     grpc_slice_hash_table* table) {
+  grpc_slice key = grpc_slice_from_static_string(key_string);
+  GPR_ASSERT(grpc_slice_hash_table_get(table, key) == NULL);
+  grpc_slice_unref(key);
+}
+
+static void destroy_string(grpc_exec_ctx* exec_ctx, void* value) {
+  gpr_free(value);
+}
+
+static void test_slice_hash_table() {
+  const test_entry test_entries[] = {
+      {"key_0", "value_0"},   {"key_1", "value_1"},   {"key_2", "value_2"},
+      {"key_3", "value_3"},   {"key_4", "value_4"},   {"key_5", "value_5"},
+      {"key_6", "value_6"},   {"key_7", "value_7"},   {"key_8", "value_8"},
+      {"key_9", "value_9"},   {"key_10", "value_10"}, {"key_11", "value_11"},
+      {"key_12", "value_12"}, {"key_13", "value_13"}, {"key_14", "value_14"},
+      {"key_15", "value_15"}, {"key_16", "value_16"}, {"key_17", "value_17"},
+      {"key_18", "value_18"}, {"key_19", "value_19"}, {"key_20", "value_20"},
+      {"key_21", "value_21"}, {"key_22", "value_22"}, {"key_23", "value_23"},
+      {"key_24", "value_24"}, {"key_25", "value_25"}, {"key_26", "value_26"},
+      {"key_27", "value_27"}, {"key_28", "value_28"}, {"key_29", "value_29"},
+      {"key_30", "value_30"}, {"key_31", "value_31"}, {"key_32", "value_32"},
+      {"key_33", "value_33"}, {"key_34", "value_34"}, {"key_35", "value_35"},
+      {"key_36", "value_36"}, {"key_37", "value_37"}, {"key_38", "value_38"},
+      {"key_39", "value_39"}, {"key_40", "value_40"}, {"key_41", "value_41"},
+      {"key_42", "value_42"}, {"key_43", "value_43"}, {"key_44", "value_44"},
+      {"key_45", "value_45"}, {"key_46", "value_46"}, {"key_47", "value_47"},
+      {"key_48", "value_48"}, {"key_49", "value_49"}, {"key_50", "value_50"},
+      {"key_51", "value_51"}, {"key_52", "value_52"}, {"key_53", "value_53"},
+      {"key_54", "value_54"}, {"key_55", "value_55"}, {"key_56", "value_56"},
+      {"key_57", "value_57"}, {"key_58", "value_58"}, {"key_59", "value_59"},
+      {"key_60", "value_60"}, {"key_61", "value_61"}, {"key_62", "value_62"},
+      {"key_63", "value_63"}, {"key_64", "value_64"}, {"key_65", "value_65"},
+      {"key_66", "value_66"}, {"key_67", "value_67"}, {"key_68", "value_68"},
+      {"key_69", "value_69"}, {"key_70", "value_70"}, {"key_71", "value_71"},
+      {"key_72", "value_72"}, {"key_73", "value_73"}, {"key_74", "value_74"},
+      {"key_75", "value_75"}, {"key_76", "value_76"}, {"key_77", "value_77"},
+      {"key_78", "value_78"}, {"key_79", "value_79"}, {"key_80", "value_80"},
+      {"key_81", "value_81"}, {"key_82", "value_82"}, {"key_83", "value_83"},
+      {"key_84", "value_84"}, {"key_85", "value_85"}, {"key_86", "value_86"},
+      {"key_87", "value_87"}, {"key_88", "value_88"}, {"key_89", "value_89"},
+      {"key_90", "value_90"}, {"key_91", "value_91"}, {"key_92", "value_92"},
+      {"key_93", "value_93"}, {"key_94", "value_94"}, {"key_95", "value_95"},
+      {"key_96", "value_96"}, {"key_97", "value_97"}, {"key_98", "value_98"},
+      {"key_99", "value_99"},
+  };
+  const size_t num_entries = GPR_ARRAY_SIZE(test_entries);
+  // Construct table.
+  grpc_slice_hash_table_entry* entries =
+      gpr_zalloc(sizeof(*entries) * num_entries);
+  populate_entries(test_entries, num_entries, entries);
+  grpc_slice_hash_table* table =
+      grpc_slice_hash_table_create(num_entries, entries, destroy_string);
+  gpr_free(entries);
+  // Check contents of table.
+  check_values(test_entries, num_entries, table);
+  check_non_existent_value("XX", table);
+  // Clean up.
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_slice_hash_table_unref(&exec_ctx, table);
+  grpc_exec_ctx_finish(&exec_ctx);
+}
+
+int main(int argc, char** argv) {
+  grpc_test_init(argc, argv);
+  test_slice_hash_table();
+  return 0;
+}
diff --git a/test/core/support/arena_test.c b/test/core/support/arena_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..9eba8a0fa6341811db8b20395509af5aa1d99364
--- /dev/null
+++ b/test/core/support/arena_test.c
@@ -0,0 +1,143 @@
+/*
+ *
+ * Copyright 2017, 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/lib/support/arena.h"
+
+#include <grpc/support/alloc.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 <inttypes.h>
+#include <string.h>
+
+#include "src/core/lib/support/string.h"
+#include "test/core/util/test_config.h"
+
+static void test_noop(void) { gpr_arena_destroy(gpr_arena_create(1)); }
+
+static void test(const char *name, size_t init_size, const size_t *allocs,
+                 size_t nallocs) {
+  gpr_strvec v;
+  char *s;
+  gpr_strvec_init(&v);
+  gpr_asprintf(&s, "test '%s': %" PRIdPTR " <- {", name, init_size);
+  gpr_strvec_add(&v, s);
+  for (size_t i = 0; i < nallocs; i++) {
+    gpr_asprintf(&s, "%" PRIdPTR ",", allocs[i]);
+    gpr_strvec_add(&v, s);
+  }
+  gpr_strvec_add(&v, gpr_strdup("}"));
+  s = gpr_strvec_flatten(&v, NULL);
+  gpr_strvec_destroy(&v);
+  gpr_log(GPR_INFO, "%s", s);
+  gpr_free(s);
+
+  gpr_arena *a = gpr_arena_create(init_size);
+  void **ps = gpr_zalloc(sizeof(*ps) * nallocs);
+  for (size_t i = 0; i < nallocs; i++) {
+    ps[i] = gpr_arena_alloc(a, allocs[i]);
+    // ensure no duplicate results
+    for (size_t j = 0; j < i; j++) {
+      GPR_ASSERT(ps[i] != ps[j]);
+    }
+    // ensure writable
+    memset(ps[i], 1, allocs[i]);
+  }
+  gpr_arena_destroy(a);
+  gpr_free(ps);
+}
+
+#define TEST(name, init_size, ...)                     \
+  static const size_t allocs_##name[] = {__VA_ARGS__}; \
+  test(#name, init_size, allocs_##name, GPR_ARRAY_SIZE(allocs_##name))
+
+#define CONCURRENT_TEST_THREADS 100
+
+size_t concurrent_test_iterations() {
+  if (sizeof(void *) < 8) return 1000;
+  return 100000;
+}
+
+typedef struct {
+  gpr_event ev_start;
+  gpr_arena *arena;
+} concurrent_test_args;
+
+static void concurrent_test_body(void *arg) {
+  concurrent_test_args *a = arg;
+  gpr_event_wait(&a->ev_start, gpr_inf_future(GPR_CLOCK_REALTIME));
+  for (size_t i = 0; i < concurrent_test_iterations(); i++) {
+    *(char *)gpr_arena_alloc(a->arena, 1) = (char)i;
+  }
+}
+
+static void concurrent_test(void) {
+  gpr_log(GPR_DEBUG, "concurrent_test");
+
+  concurrent_test_args args;
+  gpr_event_init(&args.ev_start);
+  args.arena = gpr_arena_create(1024);
+
+  gpr_thd_id thds[CONCURRENT_TEST_THREADS];
+
+  for (int i = 0; i < CONCURRENT_TEST_THREADS; i++) {
+    gpr_thd_options opt = gpr_thd_options_default();
+    gpr_thd_options_set_joinable(&opt);
+    gpr_thd_new(&thds[i], concurrent_test_body, &args, &opt);
+  }
+
+  gpr_event_set(&args.ev_start, (void *)1);
+
+  for (int i = 0; i < CONCURRENT_TEST_THREADS; i++) {
+    gpr_thd_join(thds[i]);
+  }
+
+  gpr_arena_destroy(args.arena);
+}
+
+int main(int argc, char *argv[]) {
+  grpc_test_init(argc, argv);
+
+  test_noop();
+  TEST(0_1, 0, 1);
+  TEST(1_1, 1, 1);
+  TEST(1_2, 1, 2);
+  TEST(1_3, 1, 3);
+  TEST(1_inc, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
+  TEST(6_123, 6, 1, 2, 3);
+  concurrent_test();
+
+  return 0;
+}
diff --git a/test/core/support/cpu_test.c b/test/core/support/cpu_test.c
index ca0fe0ccb50630a56afeb340b5ce4addaa679dae..7b9bf6c5e1dac246497297c8d375d7fe5e0ee944 100644
--- a/test/core/support/cpu_test.c
+++ b/test/core/support/cpu_test.c
@@ -81,9 +81,12 @@ static void worker_thread(void *arg) {
   uint32_t cpu;
   unsigned r = 12345678;
   unsigned i, j;
-  for (i = 0; i < 1000 / grpc_test_slowdown_factor(); i++) {
+  /* Avoid repetitive division calculations */
+  int64_t max_i = 1000 / grpc_test_slowdown_factor();
+  int64_t max_j = 1000000 / grpc_test_slowdown_factor();
+  for (i = 0; i < max_i; i++) {
     /* run for a bit - just calculate something random. */
-    for (j = 0; j < 1000000 / grpc_test_slowdown_factor(); j++) {
+    for (j = 0; j < max_j; j++) {
       r = (r * 17) & ((r - i) | (r * i));
     }
     cpu = gpr_cpu_current_cpu();
diff --git a/src/node/ext/server_generic.cc b/test/core/support/memory_test.cc
similarity index 59%
rename from src/node/ext/server_generic.cc
rename to test/core/support/memory_test.cc
index 0cf20f754a817693ae888bc2f99363bec04653a7..8db316a423870c0e110154931a4ea8818e4262c7 100644
--- a/src/node/ext/server_generic.cc
+++ b/test/core/support/memory_test.cc
@@ -31,43 +31,59 @@
  *
  */
 
-#ifndef GRPC_UV
+#include "src/core/lib/support/memory.h"
+#include <gtest/gtest.h>
+#include "test/core/util/test_config.h"
 
-#include "server.h"
+namespace grpc_core {
+namespace testing {
 
-#include <node.h>
-#include <nan.h>
-#include "grpc/grpc.h"
-#include "grpc/support/time.h"
+struct Foo {
+  Foo(int p, int q) : a(p), b(q) {}
+  int a;
+  int b;
+};
 
-namespace grpc {
-namespace node {
+TEST(MemoryTest, NewDeleteTest) { Delete(New<int>()); }
 
-Server::Server(grpc_server *server) : wrapped_server(server) {
-  shutdown_queue = grpc_completion_queue_create(NULL);
-  grpc_server_register_non_listening_completion_queue(server, shutdown_queue,
-                                                      NULL);
+TEST(MemoryTest, NewDeleteWithArgTest) {
+  int* i = New<int>(42);
+  EXPECT_EQ(42, *i);
+  Delete(i);
 }
 
-Server::~Server() {
-  this->ShutdownServer();
-  grpc_completion_queue_shutdown(this->shutdown_queue);
-  grpc_completion_queue_destroy(this->shutdown_queue);
+TEST(MemoryTest, NewDeleteWithArgsTest) {
+  Foo* p = New<Foo>(1, 2);
+  EXPECT_EQ(1, p->a);
+  EXPECT_EQ(2, p->b);
+  Delete(p);
 }
 
-void Server::ShutdownServer() {
-  if (this->wrapped_server != NULL) {
-    grpc_server_shutdown_and_notify(this->wrapped_server, this->shutdown_queue,
-                                    NULL);
-    grpc_server_cancel_all_calls(this->wrapped_server);
-    grpc_completion_queue_pluck(this->shutdown_queue, NULL,
-                                gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
-    grpc_server_destroy(this->wrapped_server);
-    this->wrapped_server = NULL;
+TEST(MemoryTest, MakeUniqueTest) { MakeUnique<int>(); }
+
+TEST(MemoryTest, MakeUniqueWithArgTest) {
+  auto i = MakeUnique<int>(42);
+  EXPECT_EQ(42, *i);
+}
+
+TEST(MemoryTest, UniquePtrWithCustomDeleter) {
+  int n = 0;
+  class IncrementingDeleter {
+   public:
+    void operator()(int* p) { ++*p; }
+  };
+  {
+    UniquePtr<int, IncrementingDeleter> p(&n);
+    EXPECT_EQ(0, n);
   }
+  EXPECT_EQ(1, n);
 }
 
-}  // namespace grpc
-}  // namespace node
+}  // namespace testing
+}  // namespace grpc_core
 
-#endif /* GRPC_UV */
+int main(int argc, char** argv) {
+  grpc_test_init(argc, argv);
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/test/core/support/mpscq_test.c b/test/core/support/mpscq_test.c
index 491eb9148be07234afa3be467e60e156d8739937..695066c68e3918d2414ba16026e5bb0a1312e55e 100644
--- a/test/core/support/mpscq_test.c
+++ b/test/core/support/mpscq_test.c
@@ -76,7 +76,7 @@ typedef struct {
   gpr_event *start;
 } thd_args;
 
-#define THREAD_ITERATIONS 100000
+#define THREAD_ITERATIONS 10000
 
 static void test_thread(void *args) {
   thd_args *a = args;
diff --git a/test/core/support/spinlock_test.c b/test/core/support/spinlock_test.c
index c70e76c7ea1c729c8decf1116ecaea74c46ee9a5..96055e9bd785ebd5b5f4873e3dc5e195c69bee9e 100644
--- a/test/core/support/spinlock_test.c
+++ b/test/core/support/spinlock_test.c
@@ -109,7 +109,7 @@ static void test(const char *name, void (*body)(void *m), int timeout_s,
       start, gpr_time_from_micros((int64_t)timeout_s * 1000000, GPR_TIMESPAN));
   fprintf(stderr, "%s:", name);
   while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0) {
-    iterations <<= 1;
+    if (iterations < INT64_MAX / 2) iterations <<= 1;
     fprintf(stderr, " %ld", (long)iterations);
     m = test_new(10, iterations, incr_step);
     test_create_threads(m, body);
diff --git a/test/core/support/time_test.c b/test/core/support/time_test.c
index e9ca08d0419d5161d71c6726a65f9cf971d306d5..00d0b765036647f7bfe5ba66a53636386ee5a4b4 100644
--- a/test/core/support/time_test.c
+++ b/test/core/support/time_test.c
@@ -47,32 +47,17 @@ static void to_fp(void *arg, const char *buf, size_t len) {
   fwrite(buf, 1, len, (FILE *)arg);
 }
 
-/* Convert gpr_uintmax x to ascii base b (2..16), and write with
-   (*writer)(arg, ...), zero padding to "chars" digits).  */
-static void u_to_s(uintmax_t x, unsigned base, int chars,
-                   void (*writer)(void *arg, const char *buf, size_t len),
-                   void *arg) {
-  char buf[64];
-  char *p = buf + sizeof(buf);
-  do {
-    *--p = "0123456789abcdef"[x % base];
-    x /= base;
-    chars--;
-  } while (x != 0 || chars > 0);
-  (*writer)(arg, p, (size_t)(buf + sizeof(buf) - p));
-}
-
 /* Convert gpr_intmax x to ascii base b (2..16), and write with
    (*writer)(arg, ...), zero padding to "chars" digits).  */
-static void i_to_s(intmax_t x, unsigned base, int chars,
+static void i_to_s(intmax_t x, int base, int chars,
                    void (*writer)(void *arg, const char *buf, size_t len),
                    void *arg) {
-  if (x < 0) {
-    (*writer)(arg, "-", 1);
-    u_to_s((uintmax_t)-x, base, chars - 1, writer, arg);
-  } else {
-    u_to_s((uintmax_t)x, base, chars, writer, arg);
-  }
+  char buf[64];
+  char fmt[32];
+  GPR_ASSERT(base == 16 || base == 10);
+  sprintf(fmt, "%%0%d%s", chars, base == 16 ? PRIxMAX : PRIdMAX);
+  sprintf(buf, fmt, x);
+  (*writer)(arg, buf, strlen(buf));
 }
 
 /* Convert ts to ascii, and write with (*writer)(arg, ...).  */
@@ -255,6 +240,22 @@ static void test_similar(void) {
                                    gpr_time_from_micros(10, GPR_TIMESPAN)));
 }
 
+static void test_convert_extreme(void) {
+  gpr_timespec realtime = {INT64_MAX, 1, GPR_CLOCK_REALTIME};
+  gpr_timespec monotime = gpr_convert_clock_type(realtime, GPR_CLOCK_MONOTONIC);
+  GPR_ASSERT(monotime.tv_sec == realtime.tv_sec);
+  GPR_ASSERT(monotime.clock_type == GPR_CLOCK_MONOTONIC);
+}
+
+static void test_cmp_extreme(void) {
+  gpr_timespec t1 = {INT64_MAX, 1, GPR_CLOCK_REALTIME};
+  gpr_timespec t2 = {INT64_MAX, 2, GPR_CLOCK_REALTIME};
+  GPR_ASSERT(gpr_time_cmp(t1, t2) == 0);
+  t1.tv_sec = INT64_MIN;
+  t2.tv_sec = INT64_MIN;
+  GPR_ASSERT(gpr_time_cmp(t1, t2) == 0);
+}
+
 int main(int argc, char *argv[]) {
   grpc_test_init(argc, argv);
 
@@ -263,5 +264,7 @@ int main(int argc, char *argv[]) {
   test_overflow();
   test_sticky_infinities();
   test_similar();
+  test_convert_extreme();
+  test_cmp_extreme();
   return 0;
 }
diff --git a/test/core/surface/alarm_test.c b/test/core/surface/alarm_test.c
index 4afe357c2775136459b3e6e2dea89e9d7f91e279..6ea3444fe21469b139b2a8057b54ad570fabdeb4 100644
--- a/test/core/surface/alarm_test.c
+++ b/test/core/surface/alarm_test.c
@@ -58,7 +58,7 @@ static void test_alarm(void) {
   grpc_completion_queue *cc;
 
   LOG_TEST("test_alarm");
-  cc = grpc_completion_queue_create(NULL);
+  cc = grpc_completion_queue_create_for_next(NULL);
   {
     /* regular expiry */
     grpc_event ev;
diff --git a/test/core/surface/channel_create_test.c b/test/core/surface/channel_create_test.c
index 654e5324d980aa376a074913f755b3937f0cd2ad..21bf6a0b7d55b9f2f90ac8d8a0ef42eed4eff81d 100644
--- a/test/core/surface/channel_create_test.c
+++ b/test/core/surface/channel_create_test.c
@@ -36,7 +36,7 @@
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
 
-#include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/surface/channel.h"
 #include "test/core/util/test_config.h"
diff --git a/test/core/surface/completion_queue_test.c b/test/core/surface/completion_queue_test.c
index 07f6a9869b721676da8f2e662400ce52ccd531c5..35bda5b641811a629fd5be03b53934b8c798f54f 100644
--- a/test/core/surface/completion_queue_test.c
+++ b/test/core/surface/completion_queue_test.c
@@ -51,33 +51,88 @@ static void *create_test_tag(void) {
 static void shutdown_and_destroy(grpc_completion_queue *cc) {
   grpc_event ev;
   grpc_completion_queue_shutdown(cc);
-  ev = grpc_completion_queue_next(cc, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
+
+  switch (grpc_get_cq_completion_type(cc)) {
+    case GRPC_CQ_NEXT: {
+      ev = grpc_completion_queue_next(cc, gpr_inf_past(GPR_CLOCK_REALTIME),
+                                      NULL);
+      break;
+    }
+    case GRPC_CQ_PLUCK: {
+      ev = grpc_completion_queue_pluck(cc, create_test_tag(),
+                                       gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
+      break;
+    }
+    default: {
+      gpr_log(GPR_ERROR, "Unknown completion type");
+      break;
+    }
+  }
+
   GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN);
   grpc_completion_queue_destroy(cc);
 }
 
 /* ensure we can create and destroy a completion channel */
 static void test_no_op(void) {
+  grpc_cq_completion_type completion_types[] = {GRPC_CQ_NEXT, GRPC_CQ_PLUCK};
+  grpc_cq_polling_type polling_types[] = {
+      GRPC_CQ_DEFAULT_POLLING, GRPC_CQ_NON_LISTENING, GRPC_CQ_NON_POLLING};
+  grpc_completion_queue_attributes attr;
   LOG_TEST("test_no_op");
-  shutdown_and_destroy(grpc_completion_queue_create(NULL));
+
+  attr.version = 1;
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(completion_types); i++) {
+    for (size_t j = 0; j < GPR_ARRAY_SIZE(polling_types); j++) {
+      attr.cq_completion_type = completion_types[i];
+      attr.cq_polling_type = polling_types[j];
+      shutdown_and_destroy(grpc_completion_queue_create(
+          grpc_completion_queue_factory_lookup(&attr), &attr, NULL));
+    }
+  }
 }
 
 static void test_pollset_conversion(void) {
-  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
-  GPR_ASSERT(grpc_cq_from_pollset(grpc_cq_pollset(cq)) == cq);
-  shutdown_and_destroy(cq);
+  grpc_cq_completion_type completion_types[] = {GRPC_CQ_NEXT, GRPC_CQ_PLUCK};
+  grpc_cq_polling_type polling_types[] = {GRPC_CQ_DEFAULT_POLLING,
+                                          GRPC_CQ_NON_LISTENING};
+  grpc_completion_queue *cq;
+  grpc_completion_queue_attributes attr;
+
+  LOG_TEST("test_pollset_conversion");
+
+  attr.version = 1;
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(completion_types); i++) {
+    for (size_t j = 0; j < GPR_ARRAY_SIZE(polling_types); j++) {
+      attr.cq_completion_type = completion_types[i];
+      attr.cq_polling_type = polling_types[j];
+      cq = grpc_completion_queue_create(
+          grpc_completion_queue_factory_lookup(&attr), &attr, NULL);
+      GPR_ASSERT(grpc_cq_from_pollset(grpc_cq_pollset(cq)) == cq);
+      shutdown_and_destroy(cq);
+    }
+  }
 }
 
 static void test_wait_empty(void) {
+  grpc_cq_polling_type polling_types[] = {
+      GRPC_CQ_DEFAULT_POLLING, GRPC_CQ_NON_LISTENING, GRPC_CQ_NON_POLLING};
   grpc_completion_queue *cc;
+  grpc_completion_queue_attributes attr;
   grpc_event event;
 
   LOG_TEST("test_wait_empty");
 
-  cc = grpc_completion_queue_create(NULL);
-  event = grpc_completion_queue_next(cc, gpr_now(GPR_CLOCK_REALTIME), NULL);
-  GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT);
-  shutdown_and_destroy(cc);
+  attr.version = 1;
+  attr.cq_completion_type = GRPC_CQ_NEXT;
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(polling_types); i++) {
+    attr.cq_polling_type = polling_types[i];
+    cc = grpc_completion_queue_create(
+        grpc_completion_queue_factory_lookup(&attr), &attr, NULL);
+    event = grpc_completion_queue_next(cc, gpr_now(GPR_CLOCK_REALTIME), NULL);
+    GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT);
+    shutdown_and_destroy(cc);
+  }
 }
 
 static void do_nothing_end_completion(grpc_exec_ctx *exec_ctx, void *arg,
@@ -87,50 +142,80 @@ static void test_cq_end_op(void) {
   grpc_event ev;
   grpc_completion_queue *cc;
   grpc_cq_completion completion;
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_cq_polling_type polling_types[] = {
+      GRPC_CQ_DEFAULT_POLLING, GRPC_CQ_NON_LISTENING, GRPC_CQ_NON_POLLING};
+  grpc_completion_queue_attributes attr;
+  grpc_exec_ctx init_exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_exec_ctx exec_ctx;
   void *tag = create_test_tag();
 
   LOG_TEST("test_cq_end_op");
 
-  cc = grpc_completion_queue_create(NULL);
-
-  grpc_cq_begin_op(cc, tag);
-  grpc_cq_end_op(&exec_ctx, cc, tag, GRPC_ERROR_NONE, do_nothing_end_completion,
-                 NULL, &completion);
-
-  ev = grpc_completion_queue_next(cc, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
-  GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
-  GPR_ASSERT(ev.tag == tag);
-  GPR_ASSERT(ev.success);
-
-  shutdown_and_destroy(cc);
-  grpc_exec_ctx_finish(&exec_ctx);
+  attr.version = 1;
+  attr.cq_completion_type = GRPC_CQ_NEXT;
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(polling_types); i++) {
+    exec_ctx = init_exec_ctx;  // Reset exec_ctx
+    attr.cq_polling_type = polling_types[i];
+    cc = grpc_completion_queue_create(
+        grpc_completion_queue_factory_lookup(&attr), &attr, NULL);
+
+    grpc_cq_begin_op(cc, tag);
+    grpc_cq_end_op(&exec_ctx, cc, tag, GRPC_ERROR_NONE,
+                   do_nothing_end_completion, NULL, &completion);
+
+    ev = grpc_completion_queue_next(cc, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
+    GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
+    GPR_ASSERT(ev.tag == tag);
+    GPR_ASSERT(ev.success);
+
+    shutdown_and_destroy(cc);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 }
 
 static void test_shutdown_then_next_polling(void) {
+  grpc_cq_polling_type polling_types[] = {
+      GRPC_CQ_DEFAULT_POLLING, GRPC_CQ_NON_LISTENING, GRPC_CQ_NON_POLLING};
   grpc_completion_queue *cc;
+  grpc_completion_queue_attributes attr;
   grpc_event event;
   LOG_TEST("test_shutdown_then_next_polling");
 
-  cc = grpc_completion_queue_create(NULL);
-  grpc_completion_queue_shutdown(cc);
-  event =
-      grpc_completion_queue_next(cc, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
-  GPR_ASSERT(event.type == GRPC_QUEUE_SHUTDOWN);
-  grpc_completion_queue_destroy(cc);
+  attr.version = 1;
+  attr.cq_completion_type = GRPC_CQ_NEXT;
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(polling_types); i++) {
+    attr.cq_polling_type = polling_types[i];
+    cc = grpc_completion_queue_create(
+        grpc_completion_queue_factory_lookup(&attr), &attr, NULL);
+    grpc_completion_queue_shutdown(cc);
+    event =
+        grpc_completion_queue_next(cc, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
+    GPR_ASSERT(event.type == GRPC_QUEUE_SHUTDOWN);
+    grpc_completion_queue_destroy(cc);
+  }
 }
 
 static void test_shutdown_then_next_with_timeout(void) {
+  grpc_cq_polling_type polling_types[] = {
+      GRPC_CQ_DEFAULT_POLLING, GRPC_CQ_NON_LISTENING, GRPC_CQ_NON_POLLING};
   grpc_completion_queue *cc;
+  grpc_completion_queue_attributes attr;
   grpc_event event;
   LOG_TEST("test_shutdown_then_next_with_timeout");
 
-  cc = grpc_completion_queue_create(NULL);
-  grpc_completion_queue_shutdown(cc);
-  event =
-      grpc_completion_queue_next(cc, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
-  GPR_ASSERT(event.type == GRPC_QUEUE_SHUTDOWN);
-  grpc_completion_queue_destroy(cc);
+  attr.version = 1;
+  attr.cq_completion_type = GRPC_CQ_NEXT;
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(polling_types); i++) {
+    attr.cq_polling_type = polling_types[i];
+    cc = grpc_completion_queue_create(
+        grpc_completion_queue_factory_lookup(&attr), &attr, NULL);
+
+    grpc_completion_queue_shutdown(cc);
+    event = grpc_completion_queue_next(cc, gpr_inf_future(GPR_CLOCK_REALTIME),
+                                       NULL);
+    GPR_ASSERT(event.type == GRPC_QUEUE_SHUTDOWN);
+    grpc_completion_queue_destroy(cc);
+  }
 }
 
 static void test_pluck(void) {
@@ -138,7 +223,11 @@ static void test_pluck(void) {
   grpc_completion_queue *cc;
   void *tags[128];
   grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)];
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_cq_polling_type polling_types[] = {
+      GRPC_CQ_DEFAULT_POLLING, GRPC_CQ_NON_LISTENING, GRPC_CQ_NON_POLLING};
+  grpc_completion_queue_attributes attr;
+  grpc_exec_ctx init_exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_exec_ctx exec_ctx;
   unsigned i, j;
 
   LOG_TEST("test_pluck");
@@ -150,49 +239,71 @@ static void test_pluck(void) {
     }
   }
 
-  cc = grpc_completion_queue_create(NULL);
+  attr.version = 1;
+  attr.cq_completion_type = GRPC_CQ_PLUCK;
+  for (size_t pidx = 0; pidx < GPR_ARRAY_SIZE(polling_types); pidx++) {
+    exec_ctx = init_exec_ctx;  // reset exec_ctx
+    attr.cq_polling_type = polling_types[pidx];
+    cc = grpc_completion_queue_create(
+        grpc_completion_queue_factory_lookup(&attr), &attr, NULL);
+
+    for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
+      grpc_cq_begin_op(cc, tags[i]);
+      grpc_cq_end_op(&exec_ctx, cc, tags[i], GRPC_ERROR_NONE,
+                     do_nothing_end_completion, NULL, &completions[i]);
+    }
 
-  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
-    grpc_cq_begin_op(cc, tags[i]);
-    grpc_cq_end_op(&exec_ctx, cc, tags[i], GRPC_ERROR_NONE,
-                   do_nothing_end_completion, NULL, &completions[i]);
-  }
+    for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
+      ev = grpc_completion_queue_pluck(cc, tags[i],
+                                       gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
+      GPR_ASSERT(ev.tag == tags[i]);
+    }
 
-  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
-    ev = grpc_completion_queue_pluck(cc, tags[i],
-                                     gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
-    GPR_ASSERT(ev.tag == tags[i]);
-  }
+    for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
+      grpc_cq_begin_op(cc, tags[i]);
+      grpc_cq_end_op(&exec_ctx, cc, tags[i], GRPC_ERROR_NONE,
+                     do_nothing_end_completion, NULL, &completions[i]);
+    }
 
-  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
-    grpc_cq_begin_op(cc, tags[i]);
-    grpc_cq_end_op(&exec_ctx, cc, tags[i], GRPC_ERROR_NONE,
-                   do_nothing_end_completion, NULL, &completions[i]);
-  }
+    for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
+      ev = grpc_completion_queue_pluck(cc, tags[GPR_ARRAY_SIZE(tags) - i - 1],
+                                       gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
+      GPR_ASSERT(ev.tag == tags[GPR_ARRAY_SIZE(tags) - i - 1]);
+    }
 
-  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
-    ev = grpc_completion_queue_pluck(cc, tags[GPR_ARRAY_SIZE(tags) - i - 1],
-                                     gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
-    GPR_ASSERT(ev.tag == tags[GPR_ARRAY_SIZE(tags) - i - 1]);
+    shutdown_and_destroy(cc);
+    grpc_exec_ctx_finish(&exec_ctx);
   }
-
-  shutdown_and_destroy(cc);
-  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_pluck_after_shutdown(void) {
+  grpc_cq_polling_type polling_types[] = {
+      GRPC_CQ_DEFAULT_POLLING, GRPC_CQ_NON_LISTENING, GRPC_CQ_NON_POLLING};
   grpc_event ev;
   grpc_completion_queue *cc;
+  grpc_completion_queue_attributes attr;
 
   LOG_TEST("test_pluck_after_shutdown");
-  cc = grpc_completion_queue_create(NULL);
-  grpc_completion_queue_shutdown(cc);
-  ev = grpc_completion_queue_pluck(cc, NULL, gpr_inf_future(GPR_CLOCK_REALTIME),
-                                   NULL);
-  GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN);
-  grpc_completion_queue_destroy(cc);
+
+  attr.version = 1;
+  attr.cq_completion_type = GRPC_CQ_PLUCK;
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(polling_types); i++) {
+    attr.cq_polling_type = polling_types[i];
+    cc = grpc_completion_queue_create(
+        grpc_completion_queue_factory_lookup(&attr), &attr, NULL);
+    grpc_completion_queue_shutdown(cc);
+    ev = grpc_completion_queue_pluck(cc, NULL,
+                                     gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+    GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN);
+    grpc_completion_queue_destroy(cc);
+  }
 }
 
+struct thread_state {
+  grpc_completion_queue *cc;
+  void *tag;
+};
+
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
   grpc_init();
diff --git a/test/core/surface/completion_queue_threading_test.c b/test/core/surface/completion_queue_threading_test.c
index 2d55ead843e76694014ac9a7f291fee447e92f9e..bff69ec74fd27644bdda13e46b4de6aa5a5d5bd7 100644
--- a/test/core/surface/completion_queue_threading_test.c
+++ b/test/core/surface/completion_queue_threading_test.c
@@ -52,7 +52,24 @@ static void *create_test_tag(void) {
 static void shutdown_and_destroy(grpc_completion_queue *cc) {
   grpc_event ev;
   grpc_completion_queue_shutdown(cc);
-  ev = grpc_completion_queue_next(cc, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
+
+  switch (grpc_get_cq_completion_type(cc)) {
+    case GRPC_CQ_NEXT: {
+      ev = grpc_completion_queue_next(cc, gpr_inf_past(GPR_CLOCK_REALTIME),
+                                      NULL);
+      break;
+    }
+    case GRPC_CQ_PLUCK: {
+      ev = grpc_completion_queue_pluck(cc, create_test_tag(),
+                                       gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
+      break;
+    }
+    default: {
+      gpr_log(GPR_ERROR, "Unknown completion type");
+      break;
+    }
+  }
+
   GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN);
   grpc_completion_queue_destroy(cc);
 }
@@ -84,7 +101,7 @@ static void test_too_many_plucks(void) {
 
   LOG_TEST("test_too_many_plucks");
 
-  cc = grpc_completion_queue_create(NULL);
+  cc = grpc_completion_queue_create_for_pluck(NULL);
   gpr_thd_options_set_joinable(&thread_options);
 
   for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
@@ -210,7 +227,7 @@ static void test_threading(size_t producers, size_t consumers) {
       gpr_malloc((producers + consumers) * sizeof(test_thread_options));
   gpr_event phase1 = GPR_EVENT_INIT;
   gpr_event phase2 = GPR_EVENT_INIT;
-  grpc_completion_queue *cc = grpc_completion_queue_create(NULL);
+  grpc_completion_queue *cc = grpc_completion_queue_create_for_next(NULL);
   size_t i;
   size_t total_consumed = 0;
   static int optid = 101;
diff --git a/test/core/surface/concurrent_connectivity_test.c b/test/core/surface/concurrent_connectivity_test.c
index ff927385d47ed903e9c04a272917277409684352..d6841ea1f881b4328ac678851748b466eccabf19 100644
--- a/test/core/surface/concurrent_connectivity_test.c
+++ b/test/core/surface/concurrent_connectivity_test.c
@@ -66,7 +66,7 @@ static int detag(void *p) { return (int)(uintptr_t)p; }
 
 void create_loop_destroy(void *addr) {
   for (int i = 0; i < NUM_OUTER_LOOPS; ++i) {
-    grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+    grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
     grpc_channel *chan = grpc_insecure_channel_create((char *)addr, NULL, NULL);
 
     for (int j = 0; j < NUM_INNER_LOOPS; ++j) {
@@ -109,7 +109,8 @@ static void on_connect(grpc_exec_ctx *exec_ctx, void *vargs, grpc_endpoint *tcp,
                        grpc_tcp_server_acceptor *acceptor) {
   gpr_free(acceptor);
   struct server_thread_args *args = (struct server_thread_args *)vargs;
-  grpc_endpoint_shutdown(exec_ctx, tcp, GRPC_ERROR_CREATE("Connected"));
+  grpc_endpoint_shutdown(exec_ctx, tcp,
+                         GRPC_ERROR_CREATE_FROM_STATIC_STRING("Connected"));
   grpc_endpoint_destroy(exec_ctx, tcp);
   GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, NULL));
 }
@@ -195,7 +196,7 @@ int main(int argc, char **argv) {
   gpr_asprintf(&args.addr, "localhost:%d", port);
   args.server = grpc_server_create(NULL, NULL);
   grpc_server_add_insecure_http2_port(args.server, args.addr);
-  args.cq = grpc_completion_queue_create(NULL);
+  args.cq = grpc_completion_queue_create_for_next(NULL);
   grpc_server_register_completion_queue(args.server, args.cq, NULL);
   grpc_server_start(args.server);
   gpr_thd_new(&server, server_thread, &args, &options);
diff --git a/test/core/surface/lame_client_test.c b/test/core/surface/lame_client_test.c
index 9deb50bb044e3d3a9dd344fe2d1fa7232dcb23d8..ba0cee07d361dca1d94f389fd213cfadea402e5f 100644
--- a/test/core/surface/lame_client_test.c
+++ b/test/core/surface/lame_client_test.c
@@ -108,7 +108,7 @@ int main(int argc, char **argv) {
   GPR_ASSERT(GRPC_CHANNEL_SHUTDOWN ==
              grpc_channel_check_connectivity_state(chan, 0));
 
-  cq = grpc_completion_queue_create(NULL);
+  cq = grpc_completion_queue_create_for_next(NULL);
 
   grpc_slice host = grpc_slice_from_static_string("anywhere");
   call = grpc_channel_create_call(chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
@@ -156,7 +156,7 @@ int main(int argc, char **argv) {
   GPR_ASSERT(strcmp(peer, "lampoon:national") == 0);
   gpr_free(peer);
 
-  grpc_call_destroy(call);
+  grpc_call_unref(call);
   grpc_channel_destroy(chan);
   cq_verifier_destroy(cqv);
   grpc_completion_queue_destroy(cq);
diff --git a/test/core/surface/secure_channel_create_test.c b/test/core/surface/secure_channel_create_test.c
index 567f8ae16e0366a6d1d539a8d43ef06914dd00e0..adb956cd8b5fb6f2795e56ee90bd7704a1ec6ea9 100644
--- a/test/core/surface/secure_channel_create_test.c
+++ b/test/core/surface/secure_channel_create_test.c
@@ -36,7 +36,7 @@
 #include <grpc/grpc.h>
 #include <grpc/grpc_security.h>
 #include <grpc/support/log.h>
-#include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/lib/security/credentials/fake/fake_credentials.h"
 #include "src/core/lib/security/transport/security_connector.h"
 #include "src/core/lib/surface/channel.h"
diff --git a/test/core/surface/sequential_connectivity_test.c b/test/core/surface/sequential_connectivity_test.c
index 5f66f900372c7ecf5ebed5734b2925a1dee1700a..fbecdd7e388278a0e287674b7a32dc04a46ef7db 100644
--- a/test/core/surface/sequential_connectivity_test.c
+++ b/test/core/surface/sequential_connectivity_test.c
@@ -76,7 +76,8 @@ static void run_test(const test_fixture *fixture) {
 
   grpc_server *server = grpc_server_create(NULL, NULL);
   fixture->add_server_port(server, addr);
-  grpc_completion_queue *server_cq = grpc_completion_queue_create(NULL);
+  grpc_completion_queue *server_cq =
+      grpc_completion_queue_create_for_next(NULL);
   grpc_server_register_completion_queue(server, server_cq, NULL);
   grpc_server_start(server);
 
@@ -86,7 +87,7 @@ static void run_test(const test_fixture *fixture) {
   gpr_thd_options_set_joinable(&thdopt);
   gpr_thd_new(&server_thread, server_thread_func, &sta, &thdopt);
 
-  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+  grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
   grpc_channel *channels[NUM_CONNECTIONS];
   for (size_t i = 0; i < NUM_CONNECTIONS; i++) {
     channels[i] = fixture->create_channel(addr);
diff --git a/test/core/surface/server_chttp2_test.c b/test/core/surface/server_chttp2_test.c
index 6c178abdad1987390206ee2f3fee55a7b01ba4ef..06293e51020835b252c7429095c28f4f79eb6508 100644
--- a/test/core/surface/server_chttp2_test.c
+++ b/test/core/surface/server_chttp2_test.c
@@ -39,7 +39,7 @@
 #include <grpc/support/time.h>
 #include "src/core/lib/security/credentials/credentials.h"
 #include "src/core/lib/security/credentials/fake/fake_credentials.h"
-#include "src/core/lib/tsi/fake_transport_security.h"
+#include "src/core/tsi/fake_transport_security.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
@@ -60,7 +60,7 @@ void test_add_same_port_twice() {
 
   int port = grpc_pick_unused_port_or_die();
   char *addr = NULL;
-  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+  grpc_completion_queue *cq = grpc_completion_queue_create_for_pluck(NULL);
   grpc_server *server = grpc_server_create(&args, NULL);
   grpc_server_credentials *fake_creds =
       grpc_fake_transport_security_server_credentials_create();
diff --git a/test/core/surface/server_test.c b/test/core/surface/server_test.c
index 3fd1c2c26636b07445a258b04648572abbf664c1..81a39de216dcb8d8993c83f877f3d7ee2cf4d91a 100644
--- a/test/core/surface/server_test.c
+++ b/test/core/surface/server_test.c
@@ -70,7 +70,7 @@ void test_register_method_fail(void) {
 }
 
 void test_request_call_on_no_server_cq(void) {
-  grpc_completion_queue *cc = grpc_completion_queue_create(NULL);
+  grpc_completion_queue *cc = grpc_completion_queue_create_for_next(NULL);
   grpc_server *server = grpc_server_create(NULL, NULL);
   GPR_ASSERT(GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE ==
              grpc_server_request_call(server, NULL, NULL, NULL, cc, cc, NULL));
@@ -91,7 +91,7 @@ void test_bind_server_twice(void) {
   char *addr;
   grpc_server *server1 = grpc_server_create(&args, NULL);
   grpc_server *server2 = grpc_server_create(&args, NULL);
-  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+  grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
   int port = grpc_pick_unused_port_or_die();
   gpr_asprintf(&addr, "[::]:%d", port);
   grpc_server_register_completion_queue(server1, cq, NULL);
@@ -128,7 +128,7 @@ void test_bind_server_to_addr(const char *host, bool secure) {
   } else {
     GPR_ASSERT(grpc_server_add_insecure_http2_port(server, addr));
   }
-  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+  grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
   grpc_server_register_completion_queue(server, cq, NULL);
   grpc_server_start(server);
   grpc_server_shutdown_and_notify(server, cq, NULL);
diff --git a/test/core/transport/BUILD b/test/core/transport/BUILD
index 865b0c26ef5933d6b8eea44752c4e37016ebf564..08b2fd3332a53d1a9ff06b0debd79ae7700b5ac2 100644
--- a/test/core/transport/BUILD
+++ b/test/core/transport/BUILD
@@ -64,6 +64,13 @@ cc_test(
     copts = ['-std=c99']
 )
 
+cc_test(
+    name = "stream_owned_slice_test",
+    srcs = ["stream_owned_slice_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
 cc_test(
     name = "timeout_encoding_test",
     srcs = ["timeout_encoding_test.c"],
diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c
index d572d79a7ffec08f206ec7360221b08b77660ab7..f4ccc71b395b179cb81106fe485a0c38299fe407 100644
--- a/test/core/transport/chttp2/hpack_encoder_test.c
+++ b/test/core/transport/chttp2/hpack_encoder_test.c
@@ -60,9 +60,9 @@ size_t cap_to_delete = 0;
 
 /* verify that the output generated by encoding the stream matches the
    hexstring passed in */
-static void verify(grpc_exec_ctx *exec_ctx, size_t window_available, int eof,
-                   size_t expect_window_used, const char *expected,
-                   size_t nheaders, ...) {
+static void verify(grpc_exec_ctx *exec_ctx, size_t window_available, bool eof,
+                   bool use_true_binary_metadata, size_t expect_window_used,
+                   const char *expected, size_t nheaders, ...) {
   grpc_slice_buffer output;
   grpc_slice merged;
   grpc_slice expect = parse_hexstring(expected);
@@ -103,8 +103,14 @@ static void verify(grpc_exec_ctx *exec_ctx, size_t window_available, int eof,
 
   grpc_transport_one_way_stats stats;
   memset(&stats, 0, sizeof(stats));
-  grpc_chttp2_encode_header(exec_ctx, &g_compressor, 0xdeadbeef, &b, eof, 16384,
-                            &stats, &output);
+  grpc_encode_header_options hopt = {
+      .stream_id = 0xdeadbeef,
+      .is_eof = eof,
+      .use_true_binary_metadata = use_true_binary_metadata,
+      .max_frame_size = 16384,
+      .stats = &stats,
+  };
+  grpc_chttp2_encode_header(exec_ctx, &g_compressor, &b, &hopt, &output);
   merged = grpc_slice_merge(output.slices, output.count);
   grpc_slice_buffer_destroy_internal(exec_ctx, &output);
   grpc_metadata_batch_destroy(exec_ctx, &b);
@@ -127,25 +133,28 @@ static void verify(grpc_exec_ctx *exec_ctx, size_t window_available, int eof,
 static void test_basic_headers(grpc_exec_ctx *exec_ctx) {
   int i;
 
-  verify(exec_ctx, 0, 0, 0, "000005 0104 deadbeef 40 0161 0161", 1, "a", "a");
-  verify(exec_ctx, 0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a");
-  verify(exec_ctx, 0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a");
-  verify(exec_ctx, 0, 0, 0, "000006 0104 deadbeef be 40 0162 0163", 2, "a", "a",
-         "b", "c");
-  verify(exec_ctx, 0, 0, 0, "000002 0104 deadbeef bf be", 2, "a", "a", "b",
-         "c");
-  verify(exec_ctx, 0, 0, 0, "000004 0104 deadbeef 7f 00 0164", 1, "a", "d");
+  verify(exec_ctx, 0, false, false, 0, "000005 0104 deadbeef 40 0161 0161", 1,
+         "a", "a");
+  verify(exec_ctx, 0, false, false, 0, "000001 0104 deadbeef be", 1, "a", "a");
+  verify(exec_ctx, 0, false, false, 0, "000001 0104 deadbeef be", 1, "a", "a");
+  verify(exec_ctx, 0, false, false, 0, "000006 0104 deadbeef be 40 0162 0163",
+         2, "a", "a", "b", "c");
+  verify(exec_ctx, 0, false, false, 0, "000002 0104 deadbeef bf be", 2, "a",
+         "a", "b", "c");
+  verify(exec_ctx, 0, false, false, 0, "000004 0104 deadbeef 7f 00 0164", 1,
+         "a", "d");
 
   /* flush out what's there to make a few values look very popular */
   for (i = 0; i < 350; i++) {
-    verify(exec_ctx, 0, 0, 0, "000003 0104 deadbeef c0 bf be", 3, "a", "a", "b",
-           "c", "a", "d");
+    verify(exec_ctx, 0, false, false, 0, "000003 0104 deadbeef c0 bf be", 3,
+           "a", "a", "b", "c", "a", "d");
   }
 
-  verify(exec_ctx, 0, 0, 0, "000006 0104 deadbeef c0 00 016b 0176", 2, "a", "a",
-         "k", "v");
+  verify(exec_ctx, 0, false, false, 0, "000006 0104 deadbeef c0 00 016b 0176",
+         2, "a", "a", "k", "v");
   /* this could be 000004 0104 deadbeef 0f 30 0176 also */
-  verify(exec_ctx, 0, 0, 0, "000004 0104 deadbeef 0f 2f 0176", 1, "a", "v");
+  verify(exec_ctx, 0, false, false, 0, "000004 0104 deadbeef 0f 2f 0176", 1,
+         "a", "v");
 }
 
 static void encode_int_to_str(int i, char *p) {
@@ -179,17 +188,17 @@ static void test_decode_table_overflow(grpc_exec_ctx *exec_ctx) {
     }
 
     if (i > 0) {
-      verify(exec_ctx, 0, 0, 0, expect, 2, "aa", "ba", key, value);
+      verify(exec_ctx, 0, false, false, 0, expect, 2, "aa", "ba", key, value);
     } else {
-      verify(exec_ctx, 0, 0, 0, expect, 1, key, value);
+      verify(exec_ctx, 0, false, false, 0, expect, 1, key, value);
     }
     gpr_free(expect);
   }
 
   /* if the above passes, then we must have just knocked this pair out of the
      decoder stack, and so we'll be forced to re-encode it */
-  verify(exec_ctx, 0, 0, 0, "000007 0104 deadbeef 40 026161 026261", 1, "aa",
-         "ba");
+  verify(exec_ctx, 0, false, false, 0, "000007 0104 deadbeef 40 026161 026261",
+         1, "aa", "ba");
 }
 
 static void verify_table_size_change_match_elem_size(grpc_exec_ctx *exec_ctx,
@@ -214,8 +223,12 @@ static void verify_table_size_change_match_elem_size(grpc_exec_ctx *exec_ctx,
 
   grpc_transport_one_way_stats stats;
   memset(&stats, 0, sizeof(stats));
-  grpc_chttp2_encode_header(exec_ctx, &g_compressor, 0xdeadbeef, &b, 0, 16384,
-                            &stats, &output);
+  grpc_encode_header_options hopt = {.stream_id = 0xdeadbeef,
+                                     .is_eof = false,
+                                     .use_true_binary_metadata = false,
+                                     .max_frame_size = 16384,
+                                     .stats = &stats};
+  grpc_chttp2_encode_header(exec_ctx, &g_compressor, &b, &hopt, &output);
   grpc_slice_buffer_destroy_internal(exec_ctx, &output);
   grpc_metadata_batch_destroy(exec_ctx, &b);
 
diff --git a/test/core/transport/chttp2/hpack_parser_corpus/clusterfuzz-testcase-5298216461402112 b/test/core/transport/chttp2/hpack_parser_corpus/clusterfuzz-testcase-5298216461402112
new file mode 100644
index 0000000000000000000000000000000000000000..04d48d6d76f8bedfb6e708cb4e877791999dacef
Binary files /dev/null and b/test/core/transport/chttp2/hpack_parser_corpus/clusterfuzz-testcase-5298216461402112 differ
diff --git a/test/core/transport/stream_owned_slice_test.c b/test/core/transport/stream_owned_slice_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..97ba1083f3c56a9dc41d7c03b2d7f80df1d97fd1
--- /dev/null
+++ b/test/core/transport/stream_owned_slice_test.c
@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright 2017, 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/lib/transport/transport.h"
+
+#include "test/core/util/test_config.h"
+
+#include <grpc/support/log.h>
+
+static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {}
+
+int main(int argc, char **argv) {
+  grpc_test_init(argc, argv);
+
+  uint8_t buffer[] = "abc123";
+  grpc_stream_refcount r;
+  GRPC_STREAM_REF_INIT(&r, 1, do_nothing, NULL, "test");
+  GPR_ASSERT(r.refs.count == 1);
+  grpc_slice slice =
+      grpc_slice_from_stream_owned_buffer(&r, buffer, sizeof(buffer));
+  GPR_ASSERT(GRPC_SLICE_START_PTR(slice) == buffer);
+  GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == sizeof(buffer));
+  GPR_ASSERT(r.refs.count == 2);
+  grpc_slice_unref(slice);
+  GPR_ASSERT(r.refs.count == 1);
+
+  return 0;
+}
diff --git a/test/core/tsi/transport_security_test.c b/test/core/tsi/transport_security_test.c
index 01e8770b2405ef780f82f85f023d8476c282cfb7..4214407823a6c8c5042b26bf4d721d0019c4f490 100644
--- a/test/core/tsi/transport_security_test.c
+++ b/test/core/tsi/transport_security_test.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/lib/tsi/transport_security.h"
+#include "src/core/tsi/transport_security.h"
 
 #include <string.h>
 
@@ -43,8 +43,8 @@
 #include <openssl/crypto.h>
 
 #include "src/core/lib/support/string.h"
-#include "src/core/lib/tsi/fake_transport_security.h"
-#include "src/core/lib/tsi/ssl_transport_security.h"
+#include "src/core/tsi/fake_transport_security.h"
+#include "src/core/tsi/ssl_transport_security.h"
 #include "test/core/util/test_config.h"
 
 typedef struct {
@@ -376,6 +376,8 @@ static void test_handshaker_invalid_args(void) {
              TSI_INVALID_ARGUMENT);
   GPR_ASSERT(tsi_handshaker_get_bytes_to_send_to_peer(NULL, NULL, NULL) ==
              TSI_INVALID_ARGUMENT);
+  GPR_ASSERT(tsi_handshaker_next(NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL) ==
+             TSI_INVALID_ARGUMENT);
 }
 
 static void test_handshaker_invalid_state(void) {
diff --git a/test/core/util/BUILD b/test/core/util/BUILD
index e6d0d247dbd39d5b04e7104ee19faaebe9333ff0..03c79f1f154d9b2a59e631c704dd5e8fc229ed8c 100644
--- a/test/core/util/BUILD
+++ b/test/core/util/BUILD
@@ -56,9 +56,11 @@ cc_library(
         "reconnect_server.c",
         "slice_splitter.c",
         "test_tcp_server.c",
+        "trickle_endpoint.c",
     ],
     hdrs = [
         "debugger_macros.h",
+        "trickle_endpoint.h",
         "grpc_profiler.h",
         "mock_endpoint.h",
         "parse_hexstring.h",
diff --git a/test/core/util/debugger_macros.c b/test/core/util/debugger_macros.c
index de6a2f38a777c9626e6541240e55a3b59824c28a..af61d933ddbc93aa7bfc01c6798c4121bc44a3e7 100644
--- a/test/core/util/debugger_macros.c
+++ b/test/core/util/debugger_macros.c
@@ -39,7 +39,7 @@
 
 #include <stdio.h>
 
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
 #include "src/core/ext/transport/chttp2/transport/internal.h"
 #include "src/core/lib/channel/connected_channel.h"
 #include "src/core/lib/surface/call.h"
diff --git a/test/core/util/memory_counters.c b/test/core/util/memory_counters.c
index 7c8b620f34f09bf5610cfea4b073f72fcf5b30ce..c27065f26053f5d931048d18da2679a270730514 100644
--- a/test/core/util/memory_counters.c
+++ b/test/core/util/memory_counters.c
@@ -46,17 +46,23 @@ static void *guard_malloc(size_t size);
 static void *guard_realloc(void *vptr, size_t size);
 static void guard_free(void *vptr);
 
+#ifdef GPR_LOW_LEVEL_COUNTERS
+/* hide these from the microbenchmark atomic stats */
+#define NO_BARRIER_FETCH_ADD(x, sz) \
+  __atomic_fetch_add((x), (sz), __ATOMIC_RELAXED)
+#define NO_BARRIER_LOAD(x) __atomic_load_n((x), __ATOMIC_RELAXED)
+#else
+#define NO_BARRIER_FETCH_ADD(x, sz) gpr_atm_no_barrier_fetch_add(x, sz)
+#define NO_BARRIER_LOAD(x) gpr_atm_no_barrier_load(x)
+#endif
+
 static void *guard_malloc(size_t size) {
   size_t *ptr;
   if (!size) return NULL;
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_absolute,
-                               (gpr_atm)size);
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_relative,
-                               (gpr_atm)size);
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_allocs_absolute,
-                               (gpr_atm)1);
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_allocs_relative,
-                               (gpr_atm)1);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, (gpr_atm)1);
   ptr = g_old_allocs.malloc_fn(size + sizeof(size));
   *ptr++ = size;
   return ptr;
@@ -72,14 +78,10 @@ static void *guard_realloc(void *vptr, size_t size) {
     return NULL;
   }
   --ptr;
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_absolute,
-                               (gpr_atm)size);
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_relative,
-                               -(gpr_atm)*ptr);
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_relative,
-                               (gpr_atm)size);
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_allocs_absolute,
-                               (gpr_atm)1);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -(gpr_atm)*ptr);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1);
   ptr = g_old_allocs.realloc_fn(ptr, size + sizeof(size));
   *ptr++ = size;
   return ptr;
@@ -89,10 +91,8 @@ static void guard_free(void *vptr) {
   size_t *ptr = vptr;
   if (!vptr) return;
   --ptr;
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_relative,
-                               -(gpr_atm)*ptr);
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_allocs_relative,
-                               -(gpr_atm)1);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -(gpr_atm)*ptr);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, -(gpr_atm)1);
   g_old_allocs.free_fn(ptr);
 }
 
@@ -112,12 +112,12 @@ void grpc_memory_counters_destroy() {
 struct grpc_memory_counters grpc_memory_counters_snapshot() {
   struct grpc_memory_counters counters;
   counters.total_size_relative =
-      gpr_atm_no_barrier_load(&g_memory_counters.total_size_relative);
+      NO_BARRIER_LOAD(&g_memory_counters.total_size_relative);
   counters.total_size_absolute =
-      gpr_atm_no_barrier_load(&g_memory_counters.total_size_absolute);
+      NO_BARRIER_LOAD(&g_memory_counters.total_size_absolute);
   counters.total_allocs_relative =
-      gpr_atm_no_barrier_load(&g_memory_counters.total_allocs_relative);
+      NO_BARRIER_LOAD(&g_memory_counters.total_allocs_relative);
   counters.total_allocs_absolute =
-      gpr_atm_no_barrier_load(&g_memory_counters.total_allocs_absolute);
+      NO_BARRIER_LOAD(&g_memory_counters.total_allocs_absolute);
   return counters;
 }
diff --git a/test/core/util/mock_endpoint.c b/test/core/util/mock_endpoint.c
index b8fed7e14b330af0e258cc0eec8a2bd1ee150c62..c747297984b15c8144c5018ee4d702882d0f45ef 100644
--- a/test/core/util/mock_endpoint.c
+++ b/test/core/util/mock_endpoint.c
@@ -89,8 +89,9 @@ static void me_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   grpc_mock_endpoint *m = (grpc_mock_endpoint *)ep;
   gpr_mu_lock(&m->mu);
   if (m->on_read) {
-    grpc_closure_sched(exec_ctx, m->on_read, GRPC_ERROR_CREATE_REFERENCING(
-                                                 "Endpoint Shutdown", &why, 1));
+    grpc_closure_sched(exec_ctx, m->on_read,
+                       GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                           "Endpoint Shutdown", &why, 1));
     m->on_read = NULL;
   }
   gpr_mu_unlock(&m->mu);
diff --git a/test/core/util/passthru_endpoint.c b/test/core/util/passthru_endpoint.c
index 5f27f9ae7336fdb7d28211d5770746c44ecaa1a0..6400845d23577ce394d41e9afa3db0a0b3370fb5 100644
--- a/test/core/util/passthru_endpoint.c
+++ b/test/core/util/passthru_endpoint.c
@@ -75,7 +75,8 @@ static void me_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   half *m = (half *)ep;
   gpr_mu_lock(&m->parent->mu);
   if (m->parent->shutdown) {
-    grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_CREATE("Already shutdown"));
+    grpc_closure_sched(
+        exec_ctx, cb, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Already shutdown"));
   } else if (m->read_buffer.count > 0) {
     grpc_slice_buffer_swap(&m->read_buffer, slices);
     grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_NONE);
@@ -98,16 +99,17 @@ static void me_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   grpc_error *error = GRPC_ERROR_NONE;
   m->parent->stats->num_writes++;
   if (m->parent->shutdown) {
-    error = GRPC_ERROR_CREATE("Endpoint already shutdown");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Endpoint already shutdown");
   } else if (m->on_read != NULL) {
     for (size_t i = 0; i < slices->count; i++) {
-      grpc_slice_buffer_add(m->on_read_out, grpc_slice_ref(slices->slices[i]));
+      grpc_slice_buffer_add(m->on_read_out, grpc_slice_copy(slices->slices[i]));
     }
     grpc_closure_sched(exec_ctx, m->on_read, GRPC_ERROR_NONE);
     m->on_read = NULL;
   } else {
     for (size_t i = 0; i < slices->count; i++) {
-      grpc_slice_buffer_add(&m->read_buffer, grpc_slice_ref(slices->slices[i]));
+      grpc_slice_buffer_add(&m->read_buffer,
+                            grpc_slice_copy(slices->slices[i]));
     }
   }
   gpr_mu_unlock(&m->parent->mu);
@@ -126,14 +128,16 @@ static void me_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   gpr_mu_lock(&m->parent->mu);
   m->parent->shutdown = true;
   if (m->on_read) {
-    grpc_closure_sched(exec_ctx, m->on_read,
-                       GRPC_ERROR_CREATE_REFERENCING("Shutdown", &why, 1));
+    grpc_closure_sched(
+        exec_ctx, m->on_read,
+        GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Shutdown", &why, 1));
     m->on_read = NULL;
   }
   m = other_half(m);
   if (m->on_read) {
-    grpc_closure_sched(exec_ctx, m->on_read,
-                       GRPC_ERROR_CREATE_REFERENCING("Shutdown", &why, 1));
+    grpc_closure_sched(
+        exec_ctx, m->on_read,
+        GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Shutdown", &why, 1));
     m->on_read = NULL;
   }
   gpr_mu_unlock(&m->parent->mu);
diff --git a/test/core/util/port_server_client.c b/test/core/util/port_server_client.c
index a851d01635523db8a0618604b30b46784fef318a..254c3a6b61387915441bfb9a6d7f716a79bfa3cc 100644
--- a/test/core/util/port_server_client.c
+++ b/test/core/util/port_server_client.c
@@ -103,7 +103,7 @@ void grpc_free_port_using_server(int port) {
   grpc_resource_quota *resource_quota =
       grpc_resource_quota_create("port_server_client/free");
   grpc_httpcli_get(&exec_ctx, &context, &pr.pops, resource_quota, &req,
-                   grpc_timeout_seconds_to_deadline(10),
+                   grpc_timeout_seconds_to_deadline(30),
                    grpc_closure_create(freed_port_from_server, &pr,
                                        grpc_schedule_on_exec_ctx),
                    &rsp);
@@ -162,6 +162,15 @@ static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
   if (failed) {
     grpc_httpcli_request req;
     memset(&req, 0, sizeof(req));
+    if (pr->retries >= 5) {
+      gpr_mu_lock(pr->mu);
+      pr->port = 0;
+      GRPC_LOG_IF_ERROR(
+          "pollset_kick",
+          grpc_pollset_kick(grpc_polling_entity_pollset(&pr->pops), NULL));
+      gpr_mu_unlock(pr->mu);
+      return;
+    }
     GPR_ASSERT(pr->retries < 10);
     gpr_sleep_until(gpr_time_add(
         gpr_now(GPR_CLOCK_REALTIME),
@@ -226,7 +235,7 @@ int grpc_pick_port_using_server(void) {
       grpc_resource_quota_create("port_server_client/pick");
   grpc_httpcli_get(
       &exec_ctx, &context, &pr.pops, resource_quota, &req,
-      grpc_timeout_seconds_to_deadline(10),
+      grpc_timeout_seconds_to_deadline(30),
       grpc_closure_create(got_port_from_server, &pr, grpc_schedule_on_exec_ctx),
       &pr.response);
   grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
diff --git a/test/core/util/reconnect_server.c b/test/core/util/reconnect_server.c
index 7fbd0ca6aaa60553b61747c746f2c24a384f07da..90af1c107bb46180bb426edeb104628696d3d85b 100644
--- a/test/core/util/reconnect_server.c
+++ b/test/core/util/reconnect_server.c
@@ -80,7 +80,8 @@ static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
   gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
   timestamp_list *new_tail;
   peer = grpc_endpoint_get_peer(tcp);
-  grpc_endpoint_shutdown(exec_ctx, tcp, GRPC_ERROR_CREATE("Connected"));
+  grpc_endpoint_shutdown(exec_ctx, tcp,
+                         GRPC_ERROR_CREATE_FROM_STATIC_STRING("Connected"));
   grpc_endpoint_destroy(exec_ctx, tcp);
   if (peer) {
     last_colon = strrchr(peer, ':');
diff --git a/test/core/util/test_config.c b/test/core/util/test_config.c
index 0180d6f08d446b5d83f40ea69fbc8421d8608bb8..9a400c54ca22f928b585f025b76aa3218f1343e9 100644
--- a/test/core/util/test_config.c
+++ b/test/core/util/test_config.c
@@ -348,6 +348,14 @@ bool BuiltUnderMsan() {
 #endif
 }
 
+bool BuiltUnderUbsan() {
+#ifdef GRPC_UBSAN
+  return true;
+#else
+  return false;
+#endif
+}
+
 int64_t grpc_test_sanitizer_slowdown_factor() {
   int64_t sanitizer_multiplier = 1;
   if (BuiltUnderValgrind()) {
@@ -358,6 +366,8 @@ int64_t grpc_test_sanitizer_slowdown_factor() {
     sanitizer_multiplier = 3;
   } else if (BuiltUnderMsan()) {
     sanitizer_multiplier = 4;
+  } else if (BuiltUnderUbsan()) {
+    sanitizer_multiplier = 5;
   }
   return sanitizer_multiplier;
 }
diff --git a/test/core/util/trickle_endpoint.c b/test/core/util/trickle_endpoint.c
index 7ab0488a6608abdcfe910eff6d2a7796ada882ad..58ac59711be1e3b79852de4e2c49890024707a5e 100644
--- a/test/core/util/trickle_endpoint.c
+++ b/test/core/util/trickle_endpoint.c
@@ -31,6 +31,8 @@
  *
  */
 
+#include "src/core/lib/iomgr/sockaddr.h"
+
 #include "test/core/util/passthru_endpoint.h"
 
 #include <inttypes.h>
@@ -40,9 +42,6 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
-
-#include "src/core/lib/iomgr/sockaddr.h"
-
 #include "src/core/lib/slice/slice_internal.h"
 
 typedef struct {
@@ -67,14 +66,14 @@ static void te_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
 static void te_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
                      grpc_slice_buffer *slices, grpc_closure *cb) {
   trickle_endpoint *te = (trickle_endpoint *)ep;
-  for (size_t i = 0; i < slices->count; i++) {
-    grpc_slice_ref_internal(slices->slices[i]);
-  }
   gpr_mu_lock(&te->mu);
   if (te->write_buffer.length == 0) {
     te->last_write = gpr_now(GPR_CLOCK_MONOTONIC);
   }
-  grpc_slice_buffer_addn(&te->write_buffer, slices->slices, slices->count);
+  for (size_t i = 0; i < slices->count; i++) {
+    grpc_slice_buffer_add(&te->write_buffer,
+                          grpc_slice_copy(slices->slices[i]));
+  }
   grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_REF(te->error));
   gpr_mu_unlock(&te->mu);
 }
diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc
index 418a54439a9585853b1036d66bc43d46c2839ffd..23b3b2ef3f17f99b2fa08e90826902437d456b28 100644
--- a/test/cpp/client/credentials_test.cc
+++ b/test/cpp/client/credentials_test.cc
@@ -50,6 +50,10 @@ TEST_F(CredentialsTest, InvalidGoogleRefreshToken) {
   EXPECT_EQ(static_cast<CallCredentials*>(nullptr), bad1.get());
 }
 
+TEST_F(CredentialsTest, DefaultCredentials) {
+  auto creds = GoogleDefaultCredentials();
+}
+
 }  // namespace testing
 }  // namespace grpc
 
diff --git a/test/cpp/codegen/BUILD b/test/cpp/codegen/BUILD
index 14d5733da2c8181ce641a2928f56a0e433df07c8..43d133fc342fe966b422f8f4b73b54e8bb859ab4 100644
--- a/test/cpp/codegen/BUILD
+++ b/test/cpp/codegen/BUILD
@@ -62,7 +62,7 @@ cc_test(
 cc_test(
     name = "golden_file_test",
     srcs = ["golden_file_test.cc"],
-    args = ["--generated_file_path=$(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.h"],
+    args = ["--generated_file_path=$(GENDIR)/src/proto/grpc/testing/"],
     data = [
         ":compiler_test_golden",
         "//src/proto/grpc/testing:_compiler_test_proto_grpc_codegen",
diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden
index 0b82f2a59f3e497db3558c8e403876e98c1af5de..eb12d371eaf456215c270f8861ebf00d8dafa71d 100644
--- a/test/cpp/codegen/compiler_test_golden
+++ b/test/cpp/codegen/compiler_test_golden
@@ -1,4 +1,4 @@
-// Generated by the gRPC protobuf plugin.
+// Generated by the gRPC C++ plugin.
 // If you make any local change, they will be lost.
 // source: src/proto/grpc/testing/compiler_test.proto
 // Original file comments:
@@ -69,6 +69,9 @@ namespace testing {
 // ServiceA leading comment 1
 class ServiceA final {
  public:
+  static constexpr char const* service_full_name() {
+    return "grpc.testing.ServiceA";
+  }
   class StubInterface {
    public:
     virtual ~StubInterface() {}
@@ -89,10 +92,30 @@ class ServiceA final {
       return std::unique_ptr< ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>>(AsyncMethodA2Raw(context, response, cq, tag));
     }
     // MethodA2 trailing comment 1
+    // Method A3 leading comment 1
+    std::unique_ptr< ::grpc::ClientReaderInterface< ::grpc::testing::Response>> MethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request) {
+      return std::unique_ptr< ::grpc::ClientReaderInterface< ::grpc::testing::Response>>(MethodA3Raw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>> AsyncMethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>>(AsyncMethodA3Raw(context, request, cq, tag));
+    }
+    // Method A3 trailing comment 1
+    // Method A4 leading comment 1
+    std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>> MethodA4(::grpc::ClientContext* context) {
+      return std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>>(MethodA4Raw(context));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>> AsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>>(AsyncMethodA4Raw(context, cq, tag));
+    }
+    // Method A4 trailing comment 1
   private:
     virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* AsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0;
     virtual ::grpc::ClientWriterInterface< ::grpc::testing::Request>* MethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response) = 0;
     virtual ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>* AsyncMethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) = 0;
+    virtual ::grpc::ClientReaderInterface< ::grpc::testing::Response>* MethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>* AsyncMethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag) = 0;
+    virtual ::grpc::ClientReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4Raw(::grpc::ClientContext* context) = 0;
+    virtual ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>* AsyncMethodA4Raw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) = 0;
   };
   class Stub final : public StubInterface {
    public:
@@ -107,14 +130,32 @@ class ServiceA final {
     std::unique_ptr< ::grpc::ClientAsyncWriter< ::grpc::testing::Request>> AsyncMethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) {
       return std::unique_ptr< ::grpc::ClientAsyncWriter< ::grpc::testing::Request>>(AsyncMethodA2Raw(context, response, cq, tag));
     }
+    std::unique_ptr< ::grpc::ClientReader< ::grpc::testing::Response>> MethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request) {
+      return std::unique_ptr< ::grpc::ClientReader< ::grpc::testing::Response>>(MethodA3Raw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< ::grpc::testing::Response>> AsyncMethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< ::grpc::testing::Response>>(AsyncMethodA3Raw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>> MethodA4(::grpc::ClientContext* context) {
+      return std::unique_ptr< ::grpc::ClientReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>>(MethodA4Raw(context));
+    }
+    std::unique_ptr<  ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>> AsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>>(AsyncMethodA4Raw(context, cq, tag));
+    }
 
    private:
     std::shared_ptr< ::grpc::ChannelInterface> channel_;
     ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* AsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override;
     ::grpc::ClientWriter< ::grpc::testing::Request>* MethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response) override;
     ::grpc::ClientAsyncWriter< ::grpc::testing::Request>* AsyncMethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) override;
+    ::grpc::ClientReader< ::grpc::testing::Response>* MethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request) override;
+    ::grpc::ClientAsyncReader< ::grpc::testing::Response>* AsyncMethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag) override;
+    ::grpc::ClientReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4Raw(::grpc::ClientContext* context) override;
+    ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* AsyncMethodA4Raw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) override;
     const ::grpc::RpcMethod rpcmethod_MethodA1_;
     const ::grpc::RpcMethod rpcmethod_MethodA2_;
+    const ::grpc::RpcMethod rpcmethod_MethodA3_;
+    const ::grpc::RpcMethod rpcmethod_MethodA4_;
   };
   static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
 
@@ -131,6 +172,12 @@ class ServiceA final {
     // Method A2 leading comment 2
     virtual ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response);
     // MethodA2 trailing comment 1
+    // Method A3 leading comment 1
+    virtual ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer);
+    // Method A3 trailing comment 1
+    // Method A4 leading comment 1
+    virtual ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream);
+    // Method A4 trailing comment 1
   };
   template <class BaseClass>
   class WithAsyncMethod_MethodA1 : public BaseClass {
@@ -172,7 +219,47 @@ class ServiceA final {
       ::grpc::Service::RequestAsyncClientStreaming(1, context, reader, new_call_cq, notification_cq, tag);
     }
   };
-  typedef WithAsyncMethod_MethodA1<WithAsyncMethod_MethodA2<Service > > AsyncService;
+  template <class BaseClass>
+  class WithAsyncMethod_MethodA3 : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithAsyncMethod_MethodA3() {
+      ::grpc::Service::MarkMethodAsync(2);
+    }
+    ~WithAsyncMethod_MethodA3() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestMethodA3(::grpc::ServerContext* context, ::grpc::testing::Request* request, ::grpc::ServerAsyncWriter< ::grpc::testing::Response>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(2, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_MethodA4 : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithAsyncMethod_MethodA4() {
+      ::grpc::Service::MarkMethodAsync(3);
+    }
+    ~WithAsyncMethod_MethodA4() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestMethodA4(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncBidiStreaming(3, context, stream, new_call_cq, notification_cq, tag);
+    }
+  };
+  typedef WithAsyncMethod_MethodA1<WithAsyncMethod_MethodA2<WithAsyncMethod_MethodA3<WithAsyncMethod_MethodA4<Service > > > > AsyncService;
   template <class BaseClass>
   class WithGenericMethod_MethodA1 : public BaseClass {
    private:
@@ -208,6 +295,40 @@ class ServiceA final {
     }
   };
   template <class BaseClass>
+  class WithGenericMethod_MethodA3 : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithGenericMethod_MethodA3() {
+      ::grpc::Service::MarkMethodGeneric(2);
+    }
+    ~WithGenericMethod_MethodA3() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_MethodA4 : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithGenericMethod_MethodA4() {
+      ::grpc::Service::MarkMethodGeneric(3);
+    }
+    ~WithGenericMethod_MethodA4() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
   class WithStreamedUnaryMethod_MethodA1 : public BaseClass {
    private:
     void BaseClassMustBeDerivedFromService(const Service *service) {}
@@ -228,13 +349,36 @@ class ServiceA final {
     virtual ::grpc::Status StreamedMethodA1(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_unary_streamer) = 0;
   };
   typedef WithStreamedUnaryMethod_MethodA1<Service > StreamedUnaryService;
-  typedef Service SplitStreamedService;
-  typedef WithStreamedUnaryMethod_MethodA1<Service > StreamedService;
+  template <class BaseClass>
+  class WithSplitStreamingMethod_MethodA3 : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithSplitStreamingMethod_MethodA3() {
+      ::grpc::Service::MarkMethodStreamed(2,
+        new ::grpc::SplitServerStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithSplitStreamingMethod_MethodA3<BaseClass>::StreamedMethodA3, this, std::placeholders::_1, std::placeholders::_2)));
+    }
+    ~WithSplitStreamingMethod_MethodA3() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with split streamed
+    virtual ::grpc::Status StreamedMethodA3(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_split_streamer) = 0;
+  };
+  typedef WithSplitStreamingMethod_MethodA3<Service > SplitStreamedService;
+  typedef WithStreamedUnaryMethod_MethodA1<WithSplitStreamingMethod_MethodA3<Service > > StreamedService;
 };
 
 // ServiceB leading comment 1
 class ServiceB final {
  public:
+  static constexpr char const* service_full_name() {
+    return "grpc.testing.ServiceB";
+  }
   class StubInterface {
    public:
     virtual ~StubInterface() {}
diff --git a/test/cpp/codegen/compiler_test_mock_golden b/test/cpp/codegen/compiler_test_mock_golden
new file mode 100644
index 0000000000000000000000000000000000000000..8e4b4d591125289a1f40d9efca66b06bc1ecb453
--- /dev/null
+++ b/test/cpp/codegen/compiler_test_mock_golden
@@ -0,0 +1,34 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: src/proto/grpc/testing/compiler_test.proto
+
+#include "src/proto/grpc/testing/compiler_test.pb.h"
+#include "src/proto/grpc/testing/compiler_test.grpc.pb.h"
+
+#include <grpc++/impl/codegen/async_stream.h>
+#include <grpc++/impl/codegen/sync_stream.h>
+#include <gmock/gmock.h>
+namespace grpc {
+namespace testing {
+
+class MockServiceAStub : public ServiceA::StubInterface {
+ public:
+  MOCK_METHOD3(MethodA1, ::grpc::Status(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::testing::Response* response));
+  MOCK_METHOD3(AsyncMethodA1Raw, ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>*(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq));
+  MOCK_METHOD2(MethodA2Raw, ::grpc::ClientWriterInterface< ::grpc::testing::Request>*(::grpc::ClientContext* context, ::grpc::testing::Response* response));
+  MOCK_METHOD4(AsyncMethodA2Raw, ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>*(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag));
+  MOCK_METHOD2(MethodA3Raw, ::grpc::ClientReaderInterface< ::grpc::testing::Response>*(::grpc::ClientContext* context, const ::grpc::testing::Request& request));
+  MOCK_METHOD4(AsyncMethodA3Raw, ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>*(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag));
+  MOCK_METHOD1(MethodA4Raw, ::grpc::ClientReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>*(::grpc::ClientContext* context));
+  MOCK_METHOD3(AsyncMethodA4Raw, ::grpc::ClientAsyncReaderWriterInterface<::grpc::testing::Request, ::grpc::testing::Response>*(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag));
+};
+
+class MockServiceBStub : public ServiceB::StubInterface {
+ public:
+  MOCK_METHOD3(MethodB1, ::grpc::Status(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::testing::Response* response));
+  MOCK_METHOD3(AsyncMethodB1Raw, ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>*(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq));
+};
+
+} // namespace grpc
+} // namespace testing
+
diff --git a/test/cpp/codegen/golden_file_test.cc b/test/cpp/codegen/golden_file_test.cc
index 158a4d933c9770d5ee4a18af62edcff1ef3ecacb..7789ac738b931485aa0b071343522320dcb81391 100644
--- a/test/cpp/codegen/golden_file_test.cc
+++ b/test/cpp/codegen/golden_file_test.cc
@@ -37,16 +37,18 @@
 #include <gflags/gflags.h>
 #include <gtest/gtest.h>
 
-DEFINE_string(generated_file_path, "",
-              "path to the generated compiler_test.grpc.pb.h file");
+DEFINE_string(
+    generated_file_path, "",
+    "path to the directory containing generated files compiler_test.grpc.pb.h"
+    "and compiler_test_mock.grpc.pb.h");
 
 const char kGoldenFilePath[] = "test/cpp/codegen/compiler_test_golden";
+const char kMockGoldenFilePath[] = "test/cpp/codegen/compiler_test_mock_golden";
 
-TEST(GoldenFileTest, TestGeneratedFile) {
-  ASSERT_FALSE(FLAGS_generated_file_path.empty());
-
-  std::ifstream generated(FLAGS_generated_file_path);
-  std::ifstream golden(kGoldenFilePath);
+void run_test(std::basic_string<char> generated_file,
+              std::basic_string<char> golden_file) {
+  std::ifstream generated(generated_file);
+  std::ifstream golden(golden_file);
 
   ASSERT_TRUE(generated.good());
   ASSERT_TRUE(golden.good());
@@ -61,8 +63,23 @@ TEST(GoldenFileTest, TestGeneratedFile) {
   golden.close();
 }
 
+TEST(GoldenFileTest, TestGeneratedFile) {
+  run_test(FLAGS_generated_file_path + "compiler_test.grpc.pb.h",
+           kGoldenFilePath);
+}
+
+TEST(GoldenMockFileTest, TestGeneratedMockFile) {
+  run_test(FLAGS_generated_file_path + "compiler_test_mock.grpc.pb.h",
+           kMockGoldenFilePath);
+}
+
 int main(int argc, char **argv) {
   ::testing::InitGoogleTest(&argc, argv);
   ::google::ParseCommandLineFlags(&argc, &argv, true);
+  if (FLAGS_generated_file_path.empty()) {
+    FLAGS_generated_file_path = "gens/src/proto/grpc/testing/";
+  }
+  if (FLAGS_generated_file_path.back() != '/')
+    FLAGS_generated_file_path.append("/");
   return RUN_ALL_TESTS();
 }
diff --git a/test/cpp/common/BUILD b/test/cpp/common/BUILD
index 0e2db00f0abbc92a7292fe6aff2992b5f2a3cec0..48ad5839813da282dbbca0745794e048e73ab97f 100644
--- a/test/cpp/common/BUILD
+++ b/test/cpp/common/BUILD
@@ -34,3 +34,27 @@ cc_test(
     srcs = ["alarm_cpp_test.cc"],
     deps = ["//:grpc++", "//external:gtest", "//test/core/util:gpr_test_util"],
 )
+
+cc_test(
+    name = "auth_property_iterator_test",
+    srcs = ["auth_property_iterator_test.cc"],
+    deps = ["//:grpc++", "//external:gtest", "//test/core/util:gpr_test_util", "//test/cpp/util:test_util"],
+)
+
+cc_test(
+    name = "channel_arguments_test",
+    srcs = ["channel_arguments_test.cc"],
+    deps = ["//:grpc++", "//external:gtest", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "channel_filter_test",
+    srcs = ["channel_filter_test.cc"],
+    deps = ["//:grpc++", "//external:gtest", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "secure_auth_context_test",
+    srcs = ["secure_auth_context_test.cc"],
+    deps = ["//:grpc++", "//external:gtest", "//test/core/util:gpr_test_util", "//test/cpp/util:test_util"],
+)
diff --git a/test/cpp/common/channel_arguments_test.cc b/test/cpp/common/channel_arguments_test.cc
index 190d32ce060b4c9c6af0d10c82d12df8362b54d8..8e7b56cbd61ab70852e6fdb6b8b7074a653f7a31 100644
--- a/test/cpp/common/channel_arguments_test.cc
+++ b/test/cpp/common/channel_arguments_test.cc
@@ -230,13 +230,6 @@ TEST_F(ChannelArgumentsTest, SetSocketMutator) {
   EXPECT_TRUE(HasArg(arg1));
   // arg0 is replaced by arg1
   EXPECT_FALSE(HasArg(arg0));
-
-  // arg0 is destroyed by grpc_socket_mutator_to_arg(mutator1)
-  {
-    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-    arg1.value.pointer.vtable->destroy(&exec_ctx, arg1.value.pointer.p);
-    grpc_exec_ctx_finish(&exec_ctx);
-  }
 }
 
 TEST_F(ChannelArgumentsTest, SetUserAgentPrefix) {
@@ -250,6 +243,22 @@ TEST_F(ChannelArgumentsTest, SetUserAgentPrefix) {
 
   channel_args_.SetUserAgentPrefix(prefix);
   EXPECT_TRUE(HasArg(arg0));
+
+  // Test if the user agent string is copied correctly
+  ChannelArguments new_channel_args(channel_args_);
+  grpc_channel_args args;
+  SetChannelArgs(new_channel_args, &args);
+  bool found = false;
+  for (size_t i = 0; i < args.num_args; i++) {
+    const grpc_arg& arg = args.args[i];
+    if (arg.type == GRPC_ARG_STRING &&
+        grpc::string(arg.key) == GRPC_ARG_PRIMARY_USER_AGENT_STRING) {
+      EXPECT_FALSE(found);
+      EXPECT_EQ(0, strcmp(arg.value.string, arg0.value.string));
+      found = true;
+    }
+  }
+  EXPECT_TRUE(found);
 }
 
 }  // namespace testing
diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD
index 0bf7948fcfe72ca2c999b76e4d387f1e6299e1a9..e867493fb9d0ee4c43ff15ff8d914c5bdd07cfde 100644
--- a/test/cpp/end2end/BUILD
+++ b/test/cpp/end2end/BUILD
@@ -48,6 +48,7 @@ cc_test(
         "//:grpc",
         "//:grpc++",
         "//external:gtest",
+        "//src/proto/grpc/health/v1:health_proto",
         "//src/proto/grpc/testing:echo_messages_proto",
         "//src/proto/grpc/testing:echo_proto",
         "//src/proto/grpc/testing/duplicate:echo_duplicate_proto",
@@ -197,6 +198,27 @@ cc_test(
     ],
 )
 
+
+cc_test(
+    name = "grpclb_end2end_test",
+    srcs = ["grpclb_end2end_test.cc"],
+    deps = [
+        ":test_service_impl",
+        "//:gpr",
+        "//:grpc",
+        "//:grpc++",
+        "//external:gtest",
+        "//src/proto/grpc/lb/v1:load_balancer_proto",
+        "//src/proto/grpc/testing:echo_messages_proto",
+        "//src/proto/grpc/testing:echo_proto",
+        "//src/proto/grpc/testing/duplicate:echo_duplicate_proto",
+        "//test/core/end2end:fake_resolver",
+        "//test/core/util:gpr_test_util",
+        "//test/core/util:grpc_test_util",
+        "//test/cpp/util:test_util",
+    ],
+)
+
 cc_test(
     name = "proto_server_reflection_test",
     srcs = ["proto_server_reflection_test.cc"],
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 32e8a417958075f896497dae8cbc9ccbb5fdd62e..cc3958bf13c0a24d0a0fb5dea0463a82919d32b6 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -38,6 +38,7 @@
 #include <grpc++/channel.h>
 #include <grpc++/client_context.h>
 #include <grpc++/create_channel.h>
+#include <grpc++/ext/health_check_service_server_builder_option.h>
 #include <grpc++/server.h>
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
@@ -49,6 +50,7 @@
 #include <gtest/gtest.h>
 
 #include "src/core/lib/iomgr/port.h"
+#include "src/proto/grpc/health/v1/health.grpc.pb.h"
 #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
 #include "test/core/util/port.h"
@@ -224,13 +226,15 @@ class ServerBuilderSyncPluginDisabler : public ::grpc::ServerBuilderOption {
 
 class TestScenario {
  public:
-  TestScenario(bool non_block, const grpc::string& creds_type,
+  TestScenario(bool non_block, const grpc::string& creds_type, bool hcs,
                const grpc::string& content)
       : disable_blocking(non_block),
+        health_check_service(hcs),
         credentials_type(creds_type),
         message_content(content) {}
   void Log() const;
   bool disable_blocking;
+  bool health_check_service;
   // Although the below grpc::string's are logically const, we can't declare
   // them const because of a limitation in the way old compilers (e.g., gcc-4.4)
   // manage vector insertion using a copy constructor
@@ -243,6 +247,8 @@ static std::ostream& operator<<(std::ostream& out,
   return out << "TestScenario{disable_blocking="
              << (scenario.disable_blocking ? "true" : "false")
              << ", credentials='" << scenario.credentials_type
+             << ", health_check_service="
+             << (scenario.health_check_service ? "true" : "false")
              << "', message_size=" << scenario.message_content.size() << "}";
 }
 
@@ -252,6 +258,8 @@ void TestScenario::Log() const {
   gpr_log(GPR_DEBUG, "%s", out.str().c_str());
 }
 
+class HealthCheck : public health::v1::Health::Service {};
+
 class AsyncEnd2endTest : public ::testing::TestWithParam<TestScenario> {
  protected:
   AsyncEnd2endTest() { GetParam().Log(); }
@@ -268,6 +276,9 @@ class AsyncEnd2endTest : public ::testing::TestWithParam<TestScenario> {
         GetParam().credentials_type);
     builder.AddListeningPort(server_address_.str(), server_creds);
     builder.RegisterService(&service_);
+    if (GetParam().health_check_service) {
+      builder.RegisterService(&health_check_);
+    }
     cq_ = builder.AddCompletionQueue();
 
     // TODO(zyc): make a test option to choose wheather sync plugins should be
@@ -340,6 +351,7 @@ class AsyncEnd2endTest : public ::testing::TestWithParam<TestScenario> {
   std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
   std::unique_ptr<Server> server_;
   grpc::testing::EchoTestService::AsyncService service_;
+  HealthCheck health_check_;
   std::ostringstream server_address_;
   int port_;
 
@@ -484,6 +496,81 @@ TEST_P(AsyncEnd2endTest, SimpleClientStreaming) {
   EXPECT_TRUE(recv_status.ok());
 }
 
+// Two pings and a final pong.
+TEST_P(AsyncEnd2endTest, SimpleClientStreamingWithCoalescingApi) {
+  ResetStub();
+
+  EchoRequest send_request;
+  EchoRequest recv_request;
+  EchoResponse send_response;
+  EchoResponse recv_response;
+  Status recv_status;
+  ClientContext cli_ctx;
+  ServerContext srv_ctx;
+  ServerAsyncReader<EchoResponse, EchoRequest> srv_stream(&srv_ctx);
+
+  send_request.set_message(GetParam().message_content);
+  cli_ctx.set_initial_metadata_corked(true);
+  // tag:1 never comes up since no op is performed
+  std::unique_ptr<ClientAsyncWriter<EchoRequest>> cli_stream(
+      stub_->AsyncRequestStream(&cli_ctx, &recv_response, cq_.get(), tag(1)));
+
+  service_.RequestRequestStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(),
+                                tag(2));
+
+  cli_stream->Write(send_request, tag(3));
+
+  // 65536(64KB) is the default flow control window size. Should change this
+  // number when default flow control window size changes. For the write of
+  // send_request larger than the flow control window size, tag:3 will not come
+  // up until server read is initiated. For write of send_request smaller than
+  // the flow control window size, the request can take the free ride with
+  // initial metadata due to coalescing, thus write tag:3 will come up here.
+  if (GetParam().message_content.length() < 65536) {
+    Verifier(GetParam().disable_blocking)
+        .Expect(2, true)
+        .Expect(3, true)
+        .Verify(cq_.get());
+  } else {
+    Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get());
+  }
+
+  srv_stream.Read(&recv_request, tag(4));
+
+  if (GetParam().message_content.length() < 65536) {
+    Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get());
+  } else {
+    Verifier(GetParam().disable_blocking)
+        .Expect(3, true)
+        .Expect(4, true)
+        .Verify(cq_.get());
+  }
+
+  EXPECT_EQ(send_request.message(), recv_request.message());
+
+  cli_stream->WriteLast(send_request, WriteOptions(), tag(5));
+  srv_stream.Read(&recv_request, tag(6));
+  Verifier(GetParam().disable_blocking)
+      .Expect(5, true)
+      .Expect(6, true)
+      .Verify(cq_.get());
+  EXPECT_EQ(send_request.message(), recv_request.message());
+
+  srv_stream.Read(&recv_request, tag(7));
+  Verifier(GetParam().disable_blocking).Expect(7, false).Verify(cq_.get());
+
+  send_response.set_message(recv_request.message());
+  srv_stream.Finish(send_response, Status::OK, tag(8));
+  cli_stream->Finish(&recv_status, tag(9));
+  Verifier(GetParam().disable_blocking)
+      .Expect(8, true)
+      .Expect(9, true)
+      .Verify(cq_.get());
+
+  EXPECT_EQ(send_response.message(), recv_response.message());
+  EXPECT_TRUE(recv_status.ok());
+}
+
 // One ping, two pongs.
 TEST_P(AsyncEnd2endTest, SimpleServerStreaming) {
   ResetStub();
@@ -540,6 +627,112 @@ TEST_P(AsyncEnd2endTest, SimpleServerStreaming) {
   EXPECT_TRUE(recv_status.ok());
 }
 
+// One ping, two pongs. Using WriteAndFinish API
+TEST_P(AsyncEnd2endTest, SimpleServerStreamingWithCoalescingApiWAF) {
+  ResetStub();
+
+  EchoRequest send_request;
+  EchoRequest recv_request;
+  EchoResponse send_response;
+  EchoResponse recv_response;
+  Status recv_status;
+  ClientContext cli_ctx;
+  ServerContext srv_ctx;
+  ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx);
+
+  send_request.set_message(GetParam().message_content);
+  std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream(
+      stub_->AsyncResponseStream(&cli_ctx, send_request, cq_.get(), tag(1)));
+
+  service_.RequestResponseStream(&srv_ctx, &recv_request, &srv_stream,
+                                 cq_.get(), cq_.get(), tag(2));
+
+  Verifier(GetParam().disable_blocking)
+      .Expect(1, true)
+      .Expect(2, true)
+      .Verify(cq_.get());
+  EXPECT_EQ(send_request.message(), recv_request.message());
+
+  send_response.set_message(recv_request.message());
+  srv_stream.Write(send_response, tag(3));
+  cli_stream->Read(&recv_response, tag(4));
+  Verifier(GetParam().disable_blocking)
+      .Expect(3, true)
+      .Expect(4, true)
+      .Verify(cq_.get());
+  EXPECT_EQ(send_response.message(), recv_response.message());
+
+  srv_stream.WriteAndFinish(send_response, WriteOptions(), Status::OK, tag(5));
+  cli_stream->Read(&recv_response, tag(6));
+  Verifier(GetParam().disable_blocking)
+      .Expect(5, true)
+      .Expect(6, true)
+      .Verify(cq_.get());
+  EXPECT_EQ(send_response.message(), recv_response.message());
+
+  cli_stream->Read(&recv_response, tag(7));
+  Verifier(GetParam().disable_blocking).Expect(7, false).Verify(cq_.get());
+
+  cli_stream->Finish(&recv_status, tag(8));
+  Verifier(GetParam().disable_blocking).Expect(8, true).Verify(cq_.get());
+
+  EXPECT_TRUE(recv_status.ok());
+}
+
+// One ping, two pongs. Using WriteLast API
+TEST_P(AsyncEnd2endTest, SimpleServerStreamingWithCoalescingApiWL) {
+  ResetStub();
+
+  EchoRequest send_request;
+  EchoRequest recv_request;
+  EchoResponse send_response;
+  EchoResponse recv_response;
+  Status recv_status;
+  ClientContext cli_ctx;
+  ServerContext srv_ctx;
+  ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx);
+
+  send_request.set_message(GetParam().message_content);
+  std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream(
+      stub_->AsyncResponseStream(&cli_ctx, send_request, cq_.get(), tag(1)));
+
+  service_.RequestResponseStream(&srv_ctx, &recv_request, &srv_stream,
+                                 cq_.get(), cq_.get(), tag(2));
+
+  Verifier(GetParam().disable_blocking)
+      .Expect(1, true)
+      .Expect(2, true)
+      .Verify(cq_.get());
+  EXPECT_EQ(send_request.message(), recv_request.message());
+
+  send_response.set_message(recv_request.message());
+  srv_stream.Write(send_response, tag(3));
+  cli_stream->Read(&recv_response, tag(4));
+  Verifier(GetParam().disable_blocking)
+      .Expect(3, true)
+      .Expect(4, true)
+      .Verify(cq_.get());
+  EXPECT_EQ(send_response.message(), recv_response.message());
+
+  srv_stream.WriteLast(send_response, WriteOptions(), tag(5));
+  cli_stream->Read(&recv_response, tag(6));
+  srv_stream.Finish(Status::OK, tag(7));
+  Verifier(GetParam().disable_blocking)
+      .Expect(5, true)
+      .Expect(6, true)
+      .Expect(7, true)
+      .Verify(cq_.get());
+  EXPECT_EQ(send_response.message(), recv_response.message());
+
+  cli_stream->Read(&recv_response, tag(8));
+  Verifier(GetParam().disable_blocking).Expect(8, false).Verify(cq_.get());
+
+  cli_stream->Finish(&recv_status, tag(9));
+  Verifier(GetParam().disable_blocking).Expect(9, true).Verify(cq_.get());
+
+  EXPECT_TRUE(recv_status.ok());
+}
+
 // One ping, one pong.
 TEST_P(AsyncEnd2endTest, SimpleBidiStreaming) {
   ResetStub();
@@ -599,6 +792,144 @@ TEST_P(AsyncEnd2endTest, SimpleBidiStreaming) {
   EXPECT_TRUE(recv_status.ok());
 }
 
+// One ping, one pong. Using server:WriteAndFinish api
+TEST_P(AsyncEnd2endTest, SimpleBidiStreamingWithCoalescingApiWAF) {
+  ResetStub();
+
+  EchoRequest send_request;
+  EchoRequest recv_request;
+  EchoResponse send_response;
+  EchoResponse recv_response;
+  Status recv_status;
+  ClientContext cli_ctx;
+  ServerContext srv_ctx;
+  ServerAsyncReaderWriter<EchoResponse, EchoRequest> srv_stream(&srv_ctx);
+
+  send_request.set_message(GetParam().message_content);
+  cli_ctx.set_initial_metadata_corked(true);
+  std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse>>
+      cli_stream(stub_->AsyncBidiStream(&cli_ctx, cq_.get(), tag(1)));
+
+  service_.RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(),
+                             tag(2));
+
+  cli_stream->WriteLast(send_request, WriteOptions(), tag(3));
+
+  // 65536(64KB) is the default flow control window size. Should change this
+  // number when default flow control window size changes. For the write of
+  // send_request larger than the flow control window size, tag:3 will not come
+  // up until server read is initiated. For write of send_request smaller than
+  // the flow control window size, the request can take the free ride with
+  // initial metadata due to coalescing, thus write tag:3 will come up here.
+  if (GetParam().message_content.length() < 65536) {
+    Verifier(GetParam().disable_blocking)
+        .Expect(2, true)
+        .Expect(3, true)
+        .Verify(cq_.get());
+  } else {
+    Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get());
+  }
+
+  srv_stream.Read(&recv_request, tag(4));
+
+  if (GetParam().message_content.length() < 65536) {
+    Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get());
+  } else {
+    Verifier(GetParam().disable_blocking)
+        .Expect(3, true)
+        .Expect(4, true)
+        .Verify(cq_.get());
+  }
+  EXPECT_EQ(send_request.message(), recv_request.message());
+
+  srv_stream.Read(&recv_request, tag(5));
+  Verifier(GetParam().disable_blocking).Expect(5, false).Verify(cq_.get());
+
+  send_response.set_message(recv_request.message());
+  srv_stream.WriteAndFinish(send_response, WriteOptions(), Status::OK, tag(6));
+  cli_stream->Read(&recv_response, tag(7));
+  Verifier(GetParam().disable_blocking)
+      .Expect(6, true)
+      .Expect(7, true)
+      .Verify(cq_.get());
+  EXPECT_EQ(send_response.message(), recv_response.message());
+
+  cli_stream->Finish(&recv_status, tag(8));
+  Verifier(GetParam().disable_blocking).Expect(8, true).Verify(cq_.get());
+
+  EXPECT_TRUE(recv_status.ok());
+}
+
+// One ping, one pong. Using server:WriteLast api
+TEST_P(AsyncEnd2endTest, SimpleBidiStreamingWithCoalescingApiWL) {
+  ResetStub();
+
+  EchoRequest send_request;
+  EchoRequest recv_request;
+  EchoResponse send_response;
+  EchoResponse recv_response;
+  Status recv_status;
+  ClientContext cli_ctx;
+  ServerContext srv_ctx;
+  ServerAsyncReaderWriter<EchoResponse, EchoRequest> srv_stream(&srv_ctx);
+
+  send_request.set_message(GetParam().message_content);
+  cli_ctx.set_initial_metadata_corked(true);
+  std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse>>
+      cli_stream(stub_->AsyncBidiStream(&cli_ctx, cq_.get(), tag(1)));
+
+  service_.RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(),
+                             tag(2));
+
+  cli_stream->WriteLast(send_request, WriteOptions(), tag(3));
+
+  // 65536(64KB) is the default flow control window size. Should change this
+  // number when default flow control window size changes. For the write of
+  // send_request larger than the flow control window size, tag:3 will not come
+  // up until server read is initiated. For write of send_request smaller than
+  // the flow control window size, the request can take the free ride with
+  // initial metadata due to coalescing, thus write tag:3 will come up here.
+  if (GetParam().message_content.length() < 65536) {
+    Verifier(GetParam().disable_blocking)
+        .Expect(2, true)
+        .Expect(3, true)
+        .Verify(cq_.get());
+  } else {
+    Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get());
+  }
+
+  srv_stream.Read(&recv_request, tag(4));
+
+  if (GetParam().message_content.length() < 65536) {
+    Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get());
+  } else {
+    Verifier(GetParam().disable_blocking)
+        .Expect(3, true)
+        .Expect(4, true)
+        .Verify(cq_.get());
+  }
+  EXPECT_EQ(send_request.message(), recv_request.message());
+
+  srv_stream.Read(&recv_request, tag(5));
+  Verifier(GetParam().disable_blocking).Expect(5, false).Verify(cq_.get());
+
+  send_response.set_message(recv_request.message());
+  srv_stream.WriteLast(send_response, WriteOptions(), tag(6));
+  srv_stream.Finish(Status::OK, tag(7));
+  cli_stream->Read(&recv_response, tag(8));
+  Verifier(GetParam().disable_blocking)
+      .Expect(6, true)
+      .Expect(7, true)
+      .Expect(8, true)
+      .Verify(cq_.get());
+  EXPECT_EQ(send_response.message(), recv_response.message());
+
+  cli_stream->Finish(&recv_status, tag(9));
+  Verifier(GetParam().disable_blocking).Expect(9, true).Verify(cq_.get());
+
+  EXPECT_TRUE(recv_status.ok());
+}
+
 // Metadata tests
 TEST_P(AsyncEnd2endTest, ClientInitialMetadataRpc) {
   ResetStub();
@@ -1435,12 +1766,14 @@ std::vector<TestScenario> CreateTestScenarios(bool test_disable_blocking,
     messages.push_back(big_msg);
   }
 
-  for (auto cred = credentials_types.begin(); cred != credentials_types.end();
-       ++cred) {
-    for (auto msg = messages.begin(); msg != messages.end(); msg++) {
-      scenarios.emplace_back(false, *cred, *msg);
-      if (test_disable_blocking) {
-        scenarios.emplace_back(true, *cred, *msg);
+  for (auto health_check_service : {false, true}) {
+    for (auto cred = credentials_types.begin(); cred != credentials_types.end();
+         ++cred) {
+      for (auto msg = messages.begin(); msg != messages.end(); msg++) {
+        scenarios.emplace_back(false, *cred, health_check_service, *msg);
+        if (test_disable_blocking) {
+          scenarios.emplace_back(true, *cred, health_check_service, *msg);
+        }
       }
     }
   }
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index df78557c43783cb73f40137217597e42c2f5c5ea..df71777e4bdb2e65ce4f67af036c1df8e41104e1 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -702,6 +702,21 @@ TEST_P(End2endTest, RequestStreamOneRequest) {
   EXPECT_TRUE(s.ok());
 }
 
+TEST_P(End2endTest, RequestStreamOneRequestWithCoalescingApi) {
+  ResetStub();
+  EchoRequest request;
+  EchoResponse response;
+  ClientContext context;
+
+  context.set_initial_metadata_corked(true);
+  auto stream = stub_->RequestStream(&context, &response);
+  request.set_message("hello");
+  stream->WriteLast(request, WriteOptions());
+  Status s = stream->Finish();
+  EXPECT_EQ(response.message(), request.message());
+  EXPECT_TRUE(s.ok());
+}
+
 TEST_P(End2endTest, RequestStreamTwoRequests) {
   ResetStub();
   EchoRequest request;
@@ -718,6 +733,22 @@ TEST_P(End2endTest, RequestStreamTwoRequests) {
   EXPECT_TRUE(s.ok());
 }
 
+TEST_P(End2endTest, RequestStreamTwoRequestsWithCoalescingApi) {
+  ResetStub();
+  EchoRequest request;
+  EchoResponse response;
+  ClientContext context;
+
+  context.set_initial_metadata_corked(true);
+  auto stream = stub_->RequestStream(&context, &response);
+  request.set_message("hello");
+  EXPECT_TRUE(stream->Write(request));
+  stream->WriteLast(request, WriteOptions());
+  Status s = stream->Finish();
+  EXPECT_EQ(response.message(), "hellohello");
+  EXPECT_TRUE(s.ok());
+}
+
 TEST_P(End2endTest, ResponseStream) {
   ResetStub();
   EchoRequest request;
@@ -738,6 +769,27 @@ TEST_P(End2endTest, ResponseStream) {
   EXPECT_TRUE(s.ok());
 }
 
+TEST_P(End2endTest, ResponseStreamWithCoalescingApi) {
+  ResetStub();
+  EchoRequest request;
+  EchoResponse response;
+  ClientContext context;
+  request.set_message("hello");
+  context.AddMetadata(kServerUseCoalescingApi, "1");
+
+  auto stream = stub_->ResponseStream(&context, request);
+  EXPECT_TRUE(stream->Read(&response));
+  EXPECT_EQ(response.message(), request.message() + "0");
+  EXPECT_TRUE(stream->Read(&response));
+  EXPECT_EQ(response.message(), request.message() + "1");
+  EXPECT_TRUE(stream->Read(&response));
+  EXPECT_EQ(response.message(), request.message() + "2");
+  EXPECT_FALSE(stream->Read(&response));
+
+  Status s = stream->Finish();
+  EXPECT_TRUE(s.ok());
+}
+
 TEST_P(End2endTest, BidiStream) {
   ResetStub();
   EchoRequest request;
@@ -770,6 +822,39 @@ TEST_P(End2endTest, BidiStream) {
   EXPECT_TRUE(s.ok());
 }
 
+TEST_P(End2endTest, BidiStreamWithCoalescingApi) {
+  ResetStub();
+  EchoRequest request;
+  EchoResponse response;
+  ClientContext context;
+  context.AddMetadata(kServerFinishAfterNReads, "3");
+  context.set_initial_metadata_corked(true);
+  grpc::string msg("hello");
+
+  auto stream = stub_->BidiStream(&context);
+
+  request.set_message(msg + "0");
+  EXPECT_TRUE(stream->Write(request));
+  EXPECT_TRUE(stream->Read(&response));
+  EXPECT_EQ(response.message(), request.message());
+
+  request.set_message(msg + "1");
+  EXPECT_TRUE(stream->Write(request));
+  EXPECT_TRUE(stream->Read(&response));
+  EXPECT_EQ(response.message(), request.message());
+
+  request.set_message(msg + "2");
+  stream->WriteLast(request, WriteOptions());
+  EXPECT_TRUE(stream->Read(&response));
+  EXPECT_EQ(response.message(), request.message());
+
+  EXPECT_FALSE(stream->Read(&response));
+  EXPECT_FALSE(stream->Read(&response));
+
+  Status s = stream->Finish();
+  EXPECT_TRUE(s.ok());
+}
+
 // Talk to the two services with the same name but different package names.
 // The two stubs are created on the same channel.
 TEST_P(End2endTest, DiffPackageServices) {
@@ -1045,6 +1130,39 @@ TEST_P(End2endTest, BinaryTrailerTest) {
   EXPECT_TRUE(returned_info.ParseFromString(ToString(iter->second)));
 }
 
+TEST_P(End2endTest, ExpectErrorTest) {
+  ResetStub();
+
+  std::vector<ErrorStatus> expected_status;
+  expected_status.emplace_back();
+  expected_status.back().set_code(13);  // INTERNAL
+  expected_status.back().set_error_message("text error message");
+  expected_status.back().set_binary_error_details("text error details");
+  expected_status.emplace_back();
+  expected_status.back().set_code(13);  // INTERNAL
+  expected_status.back().set_error_message("text error message");
+  expected_status.back().set_binary_error_details(
+      "\x0\x1\x2\x3\x4\x5\x6\x8\x9\xA\xB");
+
+  for (auto iter = expected_status.begin(); iter != expected_status.end();
+       ++iter) {
+    EchoRequest request;
+    EchoResponse response;
+    ClientContext context;
+    request.set_message("Hello");
+    auto* error = request.mutable_param()->mutable_expected_error();
+    error->set_code(iter->code());
+    error->set_error_message(iter->error_message());
+    error->set_binary_error_details(iter->binary_error_details());
+
+    Status s = stub_->Echo(&context, request, &response);
+    EXPECT_FALSE(s.ok());
+    EXPECT_EQ(iter->code(), s.error_code());
+    EXPECT_EQ(iter->error_message(), s.error_message());
+    EXPECT_EQ(iter->binary_error_details(), s.error_details());
+  }
+}
+
 //////////////////////////////////////////////////////////////////////////
 // Test with and without a proxy.
 class ProxyEnd2endTest : public End2endTest {
diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc
index bd384f68b40724e3dc996ccf03be4c5606aa75cd..2f873eeaa8ed9a8070ada4b08c8b84a74effcd5b 100644
--- a/test/cpp/end2end/filter_end2end_test.cc
+++ b/test/cpp/end2end/filter_end2end_test.cc
@@ -122,8 +122,9 @@ class ChannelDataImpl : public ChannelData {
 
 class CallDataImpl : public CallData {
  public:
-  void StartTransportStreamOp(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
-                              TransportStreamOp* op) override {
+  void StartTransportStreamOpBatch(grpc_exec_ctx* exec_ctx,
+                                   grpc_call_element* elem,
+                                   TransportStreamOpBatch* op) override {
     // Incrementing the counter could be done from Init(), but we want
     // to test that the individual methods are actually called correctly.
     if (op->recv_initial_metadata() != nullptr) IncrementCallCounter();
diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8417f1a99c811428e46e5efeb5e1017771692c62
--- /dev/null
+++ b/test/cpp/end2end/grpclb_end2end_test.cc
@@ -0,0 +1,639 @@
+/*
+ *
+ * Copyright 2017, 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 <memory>
+#include <mutex>
+#include <sstream>
+#include <thread>
+
+#include <grpc++/channel.h>
+#include <grpc++/client_context.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/time.h>
+#include <gtest/gtest.h>
+
+extern "C" {
+#include "src/core/lib/iomgr/sockaddr.h"
+#include "test/core/end2end/fake_resolver.h"
+}
+
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+#include "test/cpp/end2end/test_service_impl.h"
+
+#include "src/proto/grpc/lb/v1/load_balancer.grpc.pb.h"
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+
+// TODO(dgq): Other scenarios in need of testing:
+// - Send a serverlist with faulty ip:port addresses (port > 2^16, etc).
+// - Test reception of invalid serverlist
+// - Test pinging
+// - Test against a non-LB server.
+// - Random LB server closing the stream unexpectedly.
+// - Test using DNS-resolvable names (localhost?)
+// - Test handling of creation of faulty RR instance by having the LB return a
+//   serverlist with non-existent backends after having initially returned a
+//   valid one.
+//
+// Findings from end to end testing to be covered here:
+// - Handling of LB servers restart, including reconnection after backing-off
+//   retries.
+// - Destruction of load balanced channel (and therefore of grpclb instance)
+//   while:
+//   1) the internal LB call is still active. This should work by virtue
+//   of the weak reference the LB call holds. The call should be terminated as
+//   part of the grpclb shutdown process.
+//   2) the retry timer is active. Again, the weak reference it holds should
+//   prevent a premature call to \a glb_destroy.
+// - Restart of backend servers with no changes to serverlist. This exercises
+//   the RR handover mechanism.
+
+using std::chrono::system_clock;
+
+using grpc::lb::v1::LoadBalanceResponse;
+using grpc::lb::v1::LoadBalanceRequest;
+using grpc::lb::v1::LoadBalancer;
+
+namespace grpc {
+namespace testing {
+namespace {
+
+template <typename ServiceType>
+class CountedService : public ServiceType {
+ public:
+  int request_count() {
+    std::unique_lock<std::mutex> lock(mu_);
+    return request_count_;
+  }
+
+  int response_count() {
+    std::unique_lock<std::mutex> lock(mu_);
+    return response_count_;
+  }
+
+  void IncreaseResponseCount() {
+    std::unique_lock<std::mutex> lock(mu_);
+    ++response_count_;
+  }
+  void IncreaseRequestCount() {
+    std::unique_lock<std::mutex> lock(mu_);
+    ++request_count_;
+  }
+
+ protected:
+  std::mutex mu_;
+
+ private:
+  int request_count_ = 0;
+  int response_count_ = 0;
+};
+
+using BackendService = CountedService<TestServiceImpl>;
+using BalancerService = CountedService<LoadBalancer::Service>;
+
+class BackendServiceImpl : public BackendService {
+ public:
+  BackendServiceImpl() {}
+
+  Status Echo(ServerContext* context, const EchoRequest* request,
+              EchoResponse* response) override {
+    IncreaseRequestCount();
+    const auto status = TestServiceImpl::Echo(context, request, response);
+    IncreaseResponseCount();
+    return status;
+  }
+};
+
+grpc::string Ip4ToPackedString(const char* ip_str) {
+  struct in_addr ip4;
+  GPR_ASSERT(inet_pton(AF_INET, ip_str, &ip4) == 1);
+  return grpc::string(reinterpret_cast<const char*>(&ip4), sizeof(ip4));
+}
+
+struct ClientStats {
+  size_t num_calls_started = 0;
+  size_t num_calls_finished = 0;
+  size_t num_calls_finished_with_drop_for_rate_limiting = 0;
+  size_t num_calls_finished_with_drop_for_load_balancing = 0;
+  size_t num_calls_finished_with_client_failed_to_send = 0;
+  size_t num_calls_finished_known_received = 0;
+
+  ClientStats& operator+=(const ClientStats& other) {
+    num_calls_started += other.num_calls_started;
+    num_calls_finished += other.num_calls_finished;
+    num_calls_finished_with_drop_for_rate_limiting +=
+        other.num_calls_finished_with_drop_for_rate_limiting;
+    num_calls_finished_with_drop_for_load_balancing +=
+        other.num_calls_finished_with_drop_for_load_balancing;
+    num_calls_finished_with_client_failed_to_send +=
+        other.num_calls_finished_with_client_failed_to_send;
+    num_calls_finished_known_received +=
+        other.num_calls_finished_known_received;
+    return *this;
+  }
+};
+
+class BalancerServiceImpl : public BalancerService {
+ public:
+  using Stream = ServerReaderWriter<LoadBalanceResponse, LoadBalanceRequest>;
+  using ResponseDelayPair = std::pair<LoadBalanceResponse, int>;
+
+  explicit BalancerServiceImpl(int client_load_reporting_interval_seconds)
+      : client_load_reporting_interval_seconds_(
+            client_load_reporting_interval_seconds),
+        shutdown_(false) {}
+
+  Status BalanceLoad(ServerContext* context, Stream* stream) override {
+    LoadBalanceRequest request;
+    stream->Read(&request);
+    IncreaseRequestCount();
+    gpr_log(GPR_INFO, "LB: recv msg '%s'", request.DebugString().c_str());
+
+    if (client_load_reporting_interval_seconds_ > 0) {
+      LoadBalanceResponse initial_response;
+      initial_response.mutable_initial_response()
+          ->mutable_client_stats_report_interval()
+          ->set_seconds(client_load_reporting_interval_seconds_);
+      stream->Write(initial_response);
+    }
+
+    std::vector<ResponseDelayPair> responses_and_delays;
+    {
+      std::unique_lock<std::mutex> lock(mu_);
+      responses_and_delays = responses_and_delays_;
+    }
+    for (const auto& response_and_delay : responses_and_delays) {
+      if (shutdown_) break;
+      SendResponse(stream, response_and_delay.first, response_and_delay.second);
+    }
+
+    if (client_load_reporting_interval_seconds_ > 0) {
+      request.Clear();
+      stream->Read(&request);
+      gpr_log(GPR_INFO, "LB: recv client load report msg: '%s'",
+              request.DebugString().c_str());
+      GPR_ASSERT(request.has_client_stats());
+      client_stats_.num_calls_started +=
+          request.client_stats().num_calls_started();
+      client_stats_.num_calls_finished +=
+          request.client_stats().num_calls_finished();
+      client_stats_.num_calls_finished_with_drop_for_rate_limiting +=
+          request.client_stats()
+              .num_calls_finished_with_drop_for_rate_limiting();
+      client_stats_.num_calls_finished_with_drop_for_load_balancing +=
+          request.client_stats()
+              .num_calls_finished_with_drop_for_load_balancing();
+      client_stats_.num_calls_finished_with_client_failed_to_send +=
+          request.client_stats()
+              .num_calls_finished_with_client_failed_to_send();
+      client_stats_.num_calls_finished_known_received +=
+          request.client_stats().num_calls_finished_known_received();
+      std::lock_guard<std::mutex> lock(mu_);
+      cond_.notify_one();
+    }
+
+    return Status::OK;
+  }
+
+  void add_response(const LoadBalanceResponse& response, int send_after_ms) {
+    std::unique_lock<std::mutex> lock(mu_);
+    responses_and_delays_.push_back(std::make_pair(response, send_after_ms));
+  }
+
+  void Shutdown() {
+    std::unique_lock<std::mutex> lock(mu_);
+    shutdown_ = true;
+  }
+
+  static LoadBalanceResponse BuildResponseForBackends(
+      const std::vector<int>& backend_ports) {
+    LoadBalanceResponse response;
+    for (const int backend_port : backend_ports) {
+      auto* server = response.mutable_server_list()->add_servers();
+      server->set_ip_address(Ip4ToPackedString("127.0.0.1"));
+      server->set_port(backend_port);
+    }
+    return response;
+  }
+
+  const ClientStats& WaitForLoadReport() {
+    std::unique_lock<std::mutex> lock(mu_);
+    cond_.wait(lock);
+    return client_stats_;
+  }
+
+ private:
+  void SendResponse(Stream* stream, const LoadBalanceResponse& response,
+                    int delay_ms) {
+    gpr_log(GPR_INFO, "LB: sleeping for %d ms...", delay_ms);
+    gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+                                 gpr_time_from_millis(delay_ms, GPR_TIMESPAN)));
+    gpr_log(GPR_INFO, "LB: Woke up! Sending response '%s'",
+            response.DebugString().c_str());
+    stream->Write(response);
+    IncreaseResponseCount();
+  }
+
+  const int client_load_reporting_interval_seconds_;
+  std::vector<ResponseDelayPair> responses_and_delays_;
+  std::mutex mu_;
+  std::condition_variable cond_;
+  ClientStats client_stats_;
+  bool shutdown_;
+};
+
+class GrpclbEnd2endTest : public ::testing::Test {
+ protected:
+  GrpclbEnd2endTest(int num_backends, int num_balancers,
+                    int client_load_reporting_interval_seconds)
+      : server_host_("localhost"),
+        num_backends_(num_backends),
+        num_balancers_(num_balancers),
+        client_load_reporting_interval_seconds_(
+            client_load_reporting_interval_seconds) {}
+
+  void SetUp() override {
+    response_generator_ = grpc_fake_resolver_response_generator_create();
+    // Start the backends.
+    for (size_t i = 0; i < num_backends_; ++i) {
+      backends_.emplace_back(new BackendServiceImpl());
+      backend_servers_.emplace_back(ServerThread<BackendService>(
+          "backend", server_host_, backends_.back().get()));
+    }
+    // Start the load balancers.
+    for (size_t i = 0; i < num_balancers_; ++i) {
+      balancers_.emplace_back(
+          new BalancerServiceImpl(client_load_reporting_interval_seconds_));
+      balancer_servers_.emplace_back(ServerThread<BalancerService>(
+          "balancer", server_host_, balancers_.back().get()));
+    }
+    ResetStub();
+    std::vector<AddressData> addresses;
+    for (size_t i = 0; i < balancer_servers_.size(); ++i) {
+      addresses.emplace_back(AddressData{balancer_servers_[i].port_, true, ""});
+    }
+    SetNextResolution(addresses);
+  }
+
+  void TearDown() override {
+    for (size_t i = 0; i < backends_.size(); ++i) {
+      backend_servers_[i].Shutdown();
+    }
+    for (size_t i = 0; i < balancers_.size(); ++i) {
+      balancers_[i]->Shutdown();
+      balancer_servers_[i].Shutdown();
+    }
+    grpc_fake_resolver_response_generator_unref(response_generator_);
+  }
+
+  void ResetStub() {
+    ChannelArguments args;
+    args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR,
+                    response_generator_);
+    std::ostringstream uri;
+    uri << "test:///servername_not_used";
+    channel_ =
+        CreateCustomChannel(uri.str(), InsecureChannelCredentials(), args);
+    stub_ = grpc::testing::EchoTestService::NewStub(channel_);
+  }
+
+  ClientStats WaitForLoadReports() {
+    ClientStats client_stats;
+    for (const auto& balancer : balancers_) {
+      client_stats += balancer->WaitForLoadReport();
+    }
+    return client_stats;
+  }
+
+  struct AddressData {
+    int port;
+    bool is_balancer;
+    grpc::string balancer_name;
+  };
+
+  void SetNextResolution(const std::vector<AddressData>& address_data) {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_lb_addresses* addresses =
+        grpc_lb_addresses_create(address_data.size(), nullptr);
+    for (size_t i = 0; i < address_data.size(); ++i) {
+      char* lb_uri_str;
+      gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", address_data[i].port);
+      grpc_uri* lb_uri = grpc_uri_parse(&exec_ctx, lb_uri_str, true);
+      GPR_ASSERT(lb_uri != nullptr);
+      grpc_lb_addresses_set_address_from_uri(
+          addresses, i, lb_uri, address_data[i].is_balancer,
+          address_data[i].balancer_name.c_str(), nullptr);
+      grpc_uri_destroy(lb_uri);
+      gpr_free(lb_uri_str);
+    }
+    grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses);
+    grpc_channel_args fake_result = {1, &fake_addresses};
+    grpc_fake_resolver_response_generator_set_response(
+        &exec_ctx, response_generator_, &fake_result);
+    grpc_lb_addresses_destroy(&exec_ctx, addresses);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
+
+  const std::vector<int> GetBackendPorts() const {
+    std::vector<int> backend_ports;
+    for (const auto& bs : backend_servers_) {
+      backend_ports.push_back(bs.port_);
+    }
+    return backend_ports;
+  }
+
+  void ScheduleResponseForBalancer(size_t i,
+                                   const LoadBalanceResponse& response,
+                                   int delay_ms) {
+    balancers_.at(i)->add_response(response, delay_ms);
+  }
+
+  std::vector<std::pair<Status, EchoResponse>> SendRpc(const string& message,
+                                                       int num_rpcs,
+                                                       int timeout_ms = 1000) {
+    std::vector<std::pair<Status, EchoResponse>> results;
+    EchoRequest request;
+    EchoResponse response;
+    request.set_message(message);
+    for (int i = 0; i < num_rpcs; i++) {
+      ClientContext context;
+      context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms));
+      Status status = stub_->Echo(&context, request, &response);
+      results.push_back(std::make_pair(status, response));
+    }
+    return results;
+  }
+
+  template <typename T>
+  struct ServerThread {
+    explicit ServerThread(const grpc::string& type,
+                          const grpc::string& server_host, T* service)
+        : type_(type), service_(service) {
+      port_ = grpc_pick_unused_port_or_die();
+      gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_);
+      std::mutex mu;
+      std::condition_variable cond;
+      thread_.reset(new std::thread(
+          std::bind(&ServerThread::Start, this, server_host, &mu, &cond)));
+      std::unique_lock<std::mutex> lock(mu);
+      cond.wait(lock);
+      gpr_log(GPR_INFO, "%s server startup complete", type_.c_str());
+    }
+
+    void Start(const grpc::string& server_host, std::mutex* mu,
+               std::condition_variable* cond) {
+      std::ostringstream server_address;
+      server_address << server_host << ":" << port_;
+      ServerBuilder builder;
+      builder.AddListeningPort(server_address.str(),
+                               InsecureServerCredentials());
+      builder.RegisterService(service_);
+      server_ = builder.BuildAndStart();
+      std::lock_guard<std::mutex> lock(*mu);
+      cond->notify_one();
+    }
+
+    void Shutdown() {
+      gpr_log(GPR_INFO, "%s about to shutdown", type_.c_str());
+      server_->Shutdown();
+      thread_->join();
+      gpr_log(GPR_INFO, "%s shutdown completed", type_.c_str());
+    }
+
+    int port_;
+    grpc::string type_;
+    std::unique_ptr<Server> server_;
+    T* service_;
+    std::unique_ptr<std::thread> thread_;
+  };
+
+  const grpc::string kMessage_ = "Live long and prosper.";
+  const grpc::string server_host_;
+  const size_t num_backends_;
+  const size_t num_balancers_;
+  const int client_load_reporting_interval_seconds_;
+  std::shared_ptr<Channel> channel_;
+  std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
+
+  std::vector<std::unique_ptr<BackendServiceImpl>> backends_;
+  std::vector<std::unique_ptr<BalancerServiceImpl>> balancers_;
+
+  std::vector<ServerThread<BackendService>> backend_servers_;
+  std::vector<ServerThread<BalancerService>> balancer_servers_;
+
+  grpc_fake_resolver_response_generator* response_generator_;
+};
+
+class SingleBalancerTest : public GrpclbEnd2endTest {
+ public:
+  SingleBalancerTest() : GrpclbEnd2endTest(4, 1, 0) {}
+};
+
+TEST_F(SingleBalancerTest, Vanilla) {
+  ScheduleResponseForBalancer(
+      0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts()), 0);
+  // Make sure that trying to connect works without a call.
+  channel_->GetState(true /* try_to_connect */);
+  // Start servers and send 100 RPCs per server.
+  const auto& statuses_and_responses = SendRpc(kMessage_, 100 * num_backends_);
+
+  for (const auto& status_and_response : statuses_and_responses) {
+    EXPECT_TRUE(status_and_response.first.ok());
+    EXPECT_EQ(status_and_response.second.message(), kMessage_);
+  }
+
+  // Each backend should have gotten 100 requests.
+  for (size_t i = 0; i < backends_.size(); ++i) {
+    EXPECT_EQ(100, backend_servers_[i].service_->request_count());
+  }
+  // The balancer got a single request.
+  EXPECT_EQ(1, balancer_servers_[0].service_->request_count());
+  // and sent a single response.
+  EXPECT_EQ(1, balancer_servers_[0].service_->response_count());
+
+  // Check LB policy name for the channel.
+  EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName());
+}
+
+TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) {
+  const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor();
+  const int kCallDeadlineMs = 1000 * grpc_test_slowdown_factor();
+
+  // First response is an empty serverlist, sent right away.
+  ScheduleResponseForBalancer(0, LoadBalanceResponse(), 0);
+  // Send non-empty serverlist only after kServerlistDelayMs
+  ScheduleResponseForBalancer(
+      0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts()),
+      kServerlistDelayMs);
+
+  const auto t0 = system_clock::now();
+  // Client will block: LB will initially send empty serverlist.
+  const auto& statuses_and_responses =
+      SendRpc(kMessage_, num_backends_, kCallDeadlineMs);
+  const auto ellapsed_ms =
+      std::chrono::duration_cast<std::chrono::milliseconds>(
+          system_clock::now() - t0);
+  // but eventually, the LB sends a serverlist update that allows the call to
+  // proceed. The call delay must be larger than the delay in sending the
+  // populated serverlist but under the call's deadline.
+  EXPECT_GT(ellapsed_ms.count(), kServerlistDelayMs);
+  EXPECT_LT(ellapsed_ms.count(), kCallDeadlineMs);
+
+  // Each backend should have gotten 1 request.
+  for (size_t i = 0; i < backends_.size(); ++i) {
+    EXPECT_EQ(1, backend_servers_[i].service_->request_count());
+  }
+  for (const auto& status_and_response : statuses_and_responses) {
+    EXPECT_TRUE(status_and_response.first.ok());
+    EXPECT_EQ(status_and_response.second.message(), kMessage_);
+  }
+
+  // The balancer got a single request.
+  EXPECT_EQ(1, balancer_servers_[0].service_->request_count());
+  // and sent two responses.
+  EXPECT_EQ(2, balancer_servers_[0].service_->response_count());
+
+  // Check LB policy name for the channel.
+  EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName());
+}
+
+TEST_F(SingleBalancerTest, RepeatedServerlist) {
+  constexpr int kServerlistDelayMs = 100;
+
+  // Send a serverlist right away.
+  ScheduleResponseForBalancer(
+      0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts()), 0);
+  // ... and the same one a bit later.
+  ScheduleResponseForBalancer(
+      0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts()),
+      kServerlistDelayMs);
+
+  // Send num_backends/2 requests.
+  auto statuses_and_responses = SendRpc(kMessage_, num_backends_ / 2);
+  // only the first half of the backends will receive them.
+  for (size_t i = 0; i < backends_.size(); ++i) {
+    if (i < backends_.size() / 2)
+      EXPECT_EQ(1, backend_servers_[i].service_->request_count());
+    else
+      EXPECT_EQ(0, backend_servers_[i].service_->request_count());
+  }
+  EXPECT_EQ(statuses_and_responses.size(), num_backends_ / 2);
+  for (const auto& status_and_response : statuses_and_responses) {
+    EXPECT_TRUE(status_and_response.first.ok());
+    EXPECT_EQ(status_and_response.second.message(), kMessage_);
+  }
+
+  // Wait for the (duplicated) serverlist update.
+  gpr_sleep_until(gpr_time_add(
+      gpr_now(GPR_CLOCK_REALTIME),
+      gpr_time_from_millis(kServerlistDelayMs * 1.1, GPR_TIMESPAN)));
+
+  // Verify the LB has sent two responses.
+  EXPECT_EQ(2, balancer_servers_[0].service_->response_count());
+
+  // Some more calls to complete the total number of backends.
+  statuses_and_responses = SendRpc(
+      kMessage_,
+      num_backends_ / 2 + (num_backends_ & 0x1) /* extra one if num_bes odd */);
+  // Because a duplicated serverlist should have no effect, all backends must
+  // have been hit once now.
+  for (size_t i = 0; i < backends_.size(); ++i) {
+    EXPECT_EQ(1, backend_servers_[i].service_->request_count());
+  }
+  EXPECT_EQ(statuses_and_responses.size(), num_backends_ / 2);
+  for (const auto& status_and_response : statuses_and_responses) {
+    EXPECT_TRUE(status_and_response.first.ok());
+    EXPECT_EQ(status_and_response.second.message(), kMessage_);
+  }
+
+  // The balancer got a single request.
+  EXPECT_EQ(1, balancer_servers_[0].service_->request_count());
+  // Check LB policy name for the channel.
+  EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName());
+}
+
+class SingleBalancerWithClientLoadReportingTest : public GrpclbEnd2endTest {
+ public:
+  SingleBalancerWithClientLoadReportingTest() : GrpclbEnd2endTest(4, 1, 2) {}
+};
+
+TEST_F(SingleBalancerWithClientLoadReportingTest, Vanilla) {
+  ScheduleResponseForBalancer(
+      0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts()), 0);
+  // Start servers and send 100 RPCs per server.
+  const auto& statuses_and_responses = SendRpc(kMessage_, 100 * num_backends_);
+
+  for (const auto& status_and_response : statuses_and_responses) {
+    EXPECT_TRUE(status_and_response.first.ok());
+    EXPECT_EQ(status_and_response.second.message(), kMessage_);
+  }
+
+  // Each backend should have gotten 100 requests.
+  for (size_t i = 0; i < backends_.size(); ++i) {
+    EXPECT_EQ(100, backend_servers_[i].service_->request_count());
+  }
+  // The balancer got a single request.
+  EXPECT_EQ(1, balancer_servers_[0].service_->request_count());
+  // and sent a single response.
+  EXPECT_EQ(1, balancer_servers_[0].service_->response_count());
+
+  const ClientStats client_stats = WaitForLoadReports();
+  EXPECT_EQ(100 * num_backends_, client_stats.num_calls_started);
+  EXPECT_EQ(100 * num_backends_, client_stats.num_calls_finished);
+  EXPECT_EQ(0U, client_stats.num_calls_finished_with_drop_for_rate_limiting);
+  EXPECT_EQ(0U, client_stats.num_calls_finished_with_drop_for_load_balancing);
+  EXPECT_EQ(0U, client_stats.num_calls_finished_with_client_failed_to_send);
+  EXPECT_EQ(100 * num_backends_,
+            client_stats.num_calls_finished_known_received);
+}
+
+}  // namespace
+}  // namespace testing
+}  // namespace grpc
+
+int main(int argc, char** argv) {
+  grpc_init();
+  grpc_test_init(argc, argv);
+  grpc_fake_resolver_init();
+  ::testing::InitGoogleTest(&argc, argv);
+  const auto result = RUN_ALL_TESTS();
+  grpc_shutdown();
+  return result;
+}
diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc
index d6664da5a0f9c2a7fc3c6628170b567bc1dacaae..7e330063ed3bec95f7f9ef99e3d5f23fb9e1344f 100644
--- a/test/cpp/end2end/mock_test.cc
+++ b/test/cpp/end2end/mock_test.cc
@@ -34,6 +34,7 @@
 #include <climits>
 #include <thread>
 
+#include <gmock/gmock.h>
 #include <grpc++/channel.h>
 #include <grpc++/client_context.h>
 #include <grpc++/create_channel.h>
@@ -46,120 +47,35 @@
 #include <grpc/support/time.h>
 #include <gtest/gtest.h>
 
+#include <grpc++/test/mock_stream.h>
+
 #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "src/proto/grpc/testing/echo_mock.grpc.pb.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
+#include <iostream>
+
+using namespace std;
 using grpc::testing::EchoRequest;
 using grpc::testing::EchoResponse;
 using grpc::testing::EchoTestService;
+using grpc::testing::MockClientReaderWriter;
 using std::chrono::system_clock;
+using ::testing::AtLeast;
+using ::testing::SetArgPointee;
+using ::testing::SaveArg;
+using ::testing::_;
+using ::testing::Return;
+using ::testing::Invoke;
+using ::testing::WithArg;
+using ::testing::DoAll;
 
 namespace grpc {
 namespace testing {
 
 namespace {
-template <class W, class R>
-class MockClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
- public:
-  void WaitForInitialMetadata() override {}
-  bool NextMessageSize(uint32_t* sz) override {
-    *sz = UINT_MAX;
-    return true;
-  }
-  bool Read(R* msg) override { return true; }
-  bool Write(const W& msg) override { return true; }
-  bool WritesDone() override { return true; }
-  Status Finish() override { return Status::OK; }
-};
-template <>
-class MockClientReaderWriter<EchoRequest, EchoResponse> final
-    : public ClientReaderWriterInterface<EchoRequest, EchoResponse> {
- public:
-  MockClientReaderWriter() : writes_done_(false) {}
-  void WaitForInitialMetadata() override {}
-  bool NextMessageSize(uint32_t* sz) override {
-    *sz = UINT_MAX;
-    return true;
-  }
-  bool Read(EchoResponse* msg) override {
-    if (writes_done_) return false;
-    msg->set_message(last_message_);
-    return true;
-  }
-
-  bool Write(const EchoRequest& msg, const WriteOptions& options) override {
-    gpr_log(GPR_INFO, "mock recv msg %s", msg.message().c_str());
-    last_message_ = msg.message();
-    return true;
-  }
-  bool WritesDone() override {
-    writes_done_ = true;
-    return true;
-  }
-  Status Finish() override { return Status::OK; }
-
- private:
-  bool writes_done_;
-  grpc::string last_message_;
-};
-
-// Mocked stub.
-class MockStub : public EchoTestService::StubInterface {
- public:
-  MockStub() {}
-  ~MockStub() {}
-  Status Echo(ClientContext* context, const EchoRequest& request,
-              EchoResponse* response) override {
-    response->set_message(request.message());
-    return Status::OK;
-  }
-  Status Unimplemented(ClientContext* context, const EchoRequest& request,
-                       EchoResponse* response) override {
-    return Status::OK;
-  }
-
- private:
-  ClientAsyncResponseReaderInterface<EchoResponse>* AsyncEchoRaw(
-      ClientContext* context, const EchoRequest& request,
-      CompletionQueue* cq) override {
-    return nullptr;
-  }
-  ClientWriterInterface<EchoRequest>* RequestStreamRaw(
-      ClientContext* context, EchoResponse* response) override {
-    return nullptr;
-  }
-  ClientAsyncWriterInterface<EchoRequest>* AsyncRequestStreamRaw(
-      ClientContext* context, EchoResponse* response, CompletionQueue* cq,
-      void* tag) override {
-    return nullptr;
-  }
-  ClientReaderInterface<EchoResponse>* ResponseStreamRaw(
-      ClientContext* context, const EchoRequest& request) override {
-    return nullptr;
-  }
-  ClientAsyncReaderInterface<EchoResponse>* AsyncResponseStreamRaw(
-      ClientContext* context, const EchoRequest& request, CompletionQueue* cq,
-      void* tag) override {
-    return nullptr;
-  }
-  ClientReaderWriterInterface<EchoRequest, EchoResponse>* BidiStreamRaw(
-      ClientContext* context) override {
-    return new MockClientReaderWriter<EchoRequest, EchoResponse>();
-  }
-  ClientAsyncReaderWriterInterface<EchoRequest, EchoResponse>*
-  AsyncBidiStreamRaw(ClientContext* context, CompletionQueue* cq,
-                     void* tag) override {
-    return nullptr;
-  }
-  ClientAsyncResponseReaderInterface<EchoResponse>* AsyncUnimplementedRaw(
-      ClientContext* context, const EchoRequest& request,
-      CompletionQueue* cq) override {
-    return nullptr;
-  }
-};
-
 class FakeClient {
  public:
   explicit FakeClient(EchoTestService::StubInterface* stub) : stub_(stub) {}
@@ -174,6 +90,55 @@ class FakeClient {
     EXPECT_TRUE(s.ok());
   }
 
+  void DoRequestStream() {
+    EchoRequest request;
+    EchoResponse response;
+
+    ClientContext context;
+    grpc::string msg("hello");
+    grpc::string exp(msg);
+
+    std::unique_ptr<ClientWriterInterface<EchoRequest>> cstream =
+        stub_->RequestStream(&context, &response);
+
+    request.set_message(msg);
+    EXPECT_TRUE(cstream->Write(request));
+
+    msg = ", world";
+    request.set_message(msg);
+    exp.append(msg);
+    EXPECT_TRUE(cstream->Write(request));
+
+    cstream->WritesDone();
+    Status s = cstream->Finish();
+
+    EXPECT_EQ(exp, response.message());
+    EXPECT_TRUE(s.ok());
+  }
+
+  void DoResponseStream() {
+    EchoRequest request;
+    EchoResponse response;
+    request.set_message("hello world");
+
+    ClientContext context;
+    std::unique_ptr<ClientReaderInterface<EchoResponse>> cstream =
+        stub_->ResponseStream(&context, request);
+
+    grpc::string exp = "";
+    EXPECT_TRUE(cstream->Read(&response));
+    exp.append(response.message() + " ");
+
+    EXPECT_TRUE(cstream->Read(&response));
+    exp.append(response.message());
+
+    EXPECT_FALSE(cstream->Read(&response));
+    EXPECT_EQ(request.message(), exp);
+
+    Status s = cstream->Finish();
+    EXPECT_TRUE(s.ok());
+  }
+
   void DoBidiStream() {
     EchoRequest request;
     EchoResponse response;
@@ -219,6 +184,30 @@ class TestServiceImpl : public EchoTestService::Service {
     return Status::OK;
   }
 
+  Status RequestStream(ServerContext* context,
+                       ServerReader<EchoRequest>* reader,
+                       EchoResponse* response) override {
+    EchoRequest request;
+    grpc::string resp("");
+    while (reader->Read(&request)) {
+      gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
+      resp.append(request.message());
+    }
+    response->set_message(resp);
+    return Status::OK;
+  }
+
+  Status ResponseStream(ServerContext* context, const EchoRequest* request,
+                        ServerWriter<EchoResponse>* writer) override {
+    EchoResponse response;
+    vector<grpc::string> tokens = split(request->message());
+    for (grpc::string token : tokens) {
+      response.set_message(token);
+      writer->Write(response);
+    }
+    return Status::OK;
+  }
+
   Status BidiStream(
       ServerContext* context,
       ServerReaderWriter<EchoResponse, EchoRequest>* stream) override {
@@ -231,6 +220,25 @@ class TestServiceImpl : public EchoTestService::Service {
     }
     return Status::OK;
   }
+
+ private:
+  const vector<grpc::string> split(const grpc::string& input) {
+    grpc::string buff("");
+    vector<grpc::string> result;
+
+    for (auto n : input) {
+      if (n != ' ') {
+        buff += n;
+        continue;
+      }
+      if (buff == "") continue;
+      result.push_back(buff);
+      buff = "";
+    }
+    if (buff != "") result.push_back(buff);
+
+    return result;
+  }
 };
 
 class MockTest : public ::testing::Test {
@@ -267,16 +275,82 @@ TEST_F(MockTest, SimpleRpc) {
   ResetStub();
   FakeClient client(stub_.get());
   client.DoEcho();
-  MockStub stub;
+  MockEchoTestServiceStub stub;
+  EchoResponse resp;
+  resp.set_message("hello world");
+  EXPECT_CALL(stub, Echo(_, _, _))
+      .Times(AtLeast(1))
+      .WillOnce(DoAll(SetArgPointee<2>(resp), Return(Status::OK)));
   client.ResetStub(&stub);
   client.DoEcho();
 }
 
+TEST_F(MockTest, ClientStream) {
+  ResetStub();
+  FakeClient client(stub_.get());
+  client.DoRequestStream();
+
+  MockEchoTestServiceStub stub;
+  auto w = new MockClientWriter<EchoRequest>();
+  EchoResponse resp;
+  resp.set_message("hello, world");
+
+  EXPECT_CALL(*w, Write(_, _)).Times(2).WillRepeatedly(Return(true));
+  EXPECT_CALL(*w, WritesDone());
+  EXPECT_CALL(*w, Finish()).WillOnce(Return(Status::OK));
+
+  EXPECT_CALL(stub, RequestStreamRaw(_, _))
+      .WillOnce(DoAll(SetArgPointee<1>(resp), Return(w)));
+  client.ResetStub(&stub);
+  client.DoRequestStream();
+}
+
+TEST_F(MockTest, ServerStream) {
+  ResetStub();
+  FakeClient client(stub_.get());
+  client.DoResponseStream();
+
+  MockEchoTestServiceStub stub;
+  auto r = new MockClientReader<EchoResponse>();
+  EchoResponse resp1;
+  resp1.set_message("hello");
+  EchoResponse resp2;
+  resp2.set_message("world");
+
+  EXPECT_CALL(*r, Read(_))
+      .WillOnce(DoAll(SetArgPointee<0>(resp1), Return(true)))
+      .WillOnce(DoAll(SetArgPointee<0>(resp2), Return(true)))
+      .WillOnce(Return(false));
+  EXPECT_CALL(*r, Finish()).WillOnce(Return(Status::OK));
+
+  EXPECT_CALL(stub, ResponseStreamRaw(_, _)).WillOnce(Return(r));
+
+  client.ResetStub(&stub);
+  client.DoResponseStream();
+}
+
+ACTION_P(copy, msg) { arg0->set_message(msg->message()); }
+
 TEST_F(MockTest, BidiStream) {
   ResetStub();
   FakeClient client(stub_.get());
   client.DoBidiStream();
-  MockStub stub;
+  MockEchoTestServiceStub stub;
+  auto rw = new MockClientReaderWriter<EchoRequest, EchoResponse>();
+  EchoRequest msg;
+
+  EXPECT_CALL(*rw, Write(_, _))
+      .Times(3)
+      .WillRepeatedly(DoAll(SaveArg<0>(&msg), Return(true)));
+  EXPECT_CALL(*rw, Read(_))
+      .WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true)))
+      .WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true)))
+      .WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true)))
+      .WillOnce(Return(false));
+  EXPECT_CALL(*rw, WritesDone());
+  EXPECT_CALL(*rw, Finish()).WillOnce(Return(Status::OK));
+
+  EXPECT_CALL(stub, BidiStreamRaw(_)).WillOnce(Return(rw));
   client.ResetStub(&stub);
   client.DoBidiStream();
 }
diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc
index 59d36e9cb56a51c44b2777867348cd84a59c2b47..b473dd1f52ee5091d84dc55b0f910d7ded5f6a3d 100644
--- a/test/cpp/end2end/test_service_impl.cc
+++ b/test/cpp/end2end/test_service_impl.cc
@@ -92,6 +92,11 @@ Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request,
     gpr_log(GPR_ERROR, "The request should not reach application handler.");
     GPR_ASSERT(0);
   }
+  if (request->has_param() && request->param().has_expected_error()) {
+    const auto& error = request->param().expected_error();
+    return Status(static_cast<StatusCode>(error.code()), error.error_message(),
+                  error.binary_error_details());
+  }
   int server_try_cancel = GetIntValueFromMetadata(
       kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL);
   if (server_try_cancel > DO_NOT_CANCEL) {
@@ -246,6 +251,9 @@ Status TestServiceImpl::ResponseStream(ServerContext* context,
   int server_try_cancel = GetIntValueFromMetadata(
       kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL);
 
+  int server_coalescing_api = GetIntValueFromMetadata(
+      kServerUseCoalescingApi, context->client_metadata(), 0);
+
   if (server_try_cancel == CANCEL_BEFORE_PROCESSING) {
     ServerTryCancel(context);
     return Status::CANCELLED;
@@ -260,7 +268,11 @@ Status TestServiceImpl::ResponseStream(ServerContext* context,
 
   for (int i = 0; i < kNumResponseStreamsMsgs; i++) {
     response.set_message(request->message() + grpc::to_string(i));
-    writer->Write(response);
+    if (i == kNumResponseStreamsMsgs - 1 && server_coalescing_api != 0) {
+      writer->WriteLast(response, WriteOptions());
+    } else {
+      writer->Write(response);
+    }
   }
 
   if (server_try_cancel_thd != nullptr) {
@@ -305,10 +317,21 @@ Status TestServiceImpl::BidiStream(
         new std::thread(&TestServiceImpl::ServerTryCancel, this, context);
   }
 
+  // kServerFinishAfterNReads suggests after how many reads, the server should
+  // write the last message and send status (coalesced using WriteLast)
+  int server_write_last = GetIntValueFromMetadata(
+      kServerFinishAfterNReads, context->client_metadata(), 0);
+
+  int read_counts = 0;
   while (stream->Read(&request)) {
+    read_counts++;
     gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
     response.set_message(request.message());
-    stream->Write(response);
+    if (read_counts == server_write_last) {
+      stream->WriteLast(response, WriteOptions());
+    } else {
+      stream->Write(response);
+    }
   }
 
   if (server_try_cancel_thd != nullptr) {
diff --git a/test/cpp/end2end/test_service_impl.h b/test/cpp/end2end/test_service_impl.h
index 88e0be7bca77369f78c5a2db25e9b241b8e26492..b1f02f93f658ee7f9cfb0d13318b23f35b28ec18 100644
--- a/test/cpp/end2end/test_service_impl.h
+++ b/test/cpp/end2end/test_service_impl.h
@@ -48,6 +48,8 @@ const int kNumResponseStreamsMsgs = 3;
 const char* const kServerCancelAfterReads = "cancel_after_reads";
 const char* const kServerTryCancelRequest = "server_try_cancel";
 const char* const kDebugInfoTrailerKey = "debug-info-bin";
+const char* const kServerFinishAfterNReads = "server_finish_after_n_reads";
+const char* const kServerUseCoalescingApi = "server_use_coalescing_api";
 
 typedef enum {
   DO_NOT_CANCEL = 0,
diff --git a/test/cpp/grpclb/grpclb_api_test.cc b/test/cpp/grpclb/grpclb_api_test.cc
index 82ccf436f828da0bdffd1264e35223464407c25d..0b569f1415704c5c217b4d3f07323e06e156124a 100644
--- a/test/cpp/grpclb/grpclb_api_test.cc
+++ b/test/cpp/grpclb/grpclb_api_test.cc
@@ -34,7 +34,7 @@
 #include <grpc++/impl/codegen/config.h>
 #include <gtest/gtest.h>
 
-#include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h"
 #include "src/core/lib/iomgr/sockaddr.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/proto/grpc/lb/v1/load_balancer.pb.h"  // C++ version
@@ -106,11 +106,13 @@ TEST_F(GrpclbTest, ParseResponseServerList) {
   auto* server = serverlist->add_servers();
   server->set_ip_address(Ip4ToPackedString("127.0.0.1"));
   server->set_port(12345);
-  server->set_drop_request(true);
+  server->set_drop_for_rate_limiting(true);
+  server->set_drop_for_load_balancing(false);
   server = response.mutable_server_list()->add_servers();
   server->set_ip_address(Ip4ToPackedString("10.0.0.1"));
   server->set_port(54321);
-  server->set_drop_request(false);
+  server->set_drop_for_rate_limiting(false);
+  server->set_drop_for_load_balancing(true);
   auto* expiration_interval = serverlist->mutable_expiration_interval();
   expiration_interval->set_seconds(888);
   expiration_interval->set_nanos(999);
@@ -125,12 +127,14 @@ TEST_F(GrpclbTest, ParseResponseServerList) {
   EXPECT_EQ(PackedStringToIp(c_serverlist->servers[0]->ip_address),
             "127.0.0.1");
   EXPECT_EQ(c_serverlist->servers[0]->port, 12345);
-  EXPECT_TRUE(c_serverlist->servers[0]->drop_request);
+  EXPECT_TRUE(c_serverlist->servers[0]->drop_for_rate_limiting);
+  EXPECT_FALSE(c_serverlist->servers[0]->drop_for_load_balancing);
   EXPECT_TRUE(c_serverlist->servers[1]->has_ip_address);
 
   EXPECT_EQ(PackedStringToIp(c_serverlist->servers[1]->ip_address), "10.0.0.1");
   EXPECT_EQ(c_serverlist->servers[1]->port, 54321);
-  EXPECT_FALSE(c_serverlist->servers[1]->drop_request);
+  EXPECT_FALSE(c_serverlist->servers[1]->drop_for_rate_limiting);
+  EXPECT_TRUE(c_serverlist->servers[1]->drop_for_load_balancing);
 
   EXPECT_TRUE(c_serverlist->expiration_interval.has_seconds);
   EXPECT_EQ(c_serverlist->expiration_interval.seconds, 888);
diff --git a/test/cpp/grpclb/grpclb_test.cc b/test/cpp/grpclb/grpclb_test.cc
index 89ed9249adce77b4e15eb1a3cc4a65d257f2a978..a002c7f77dce7dde2f9d879a07cd9d2c8f3c6f12 100644
--- a/test/cpp/grpclb/grpclb_test.cc
+++ b/test/cpp/grpclb/grpclb_test.cc
@@ -51,7 +51,7 @@
 
 #include <grpc++/impl/codegen/config.h>
 extern "C" {
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/iomgr/sockaddr.h"
@@ -310,7 +310,7 @@ static void start_lb_server(server_fixture *sf, int *ports, size_t nports,
   gpr_log(GPR_INFO, "LB Server[%s](%s) after tag 204. All done. LB server out",
           sf->servers_hostport, sf->balancer_name);
 
-  grpc_call_destroy(s);
+  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
@@ -457,7 +457,7 @@ static void start_backend_server(server_fixture *sf) {
     gpr_log(GPR_INFO, "Server[%s] DONE. After servicing %d calls",
             sf->servers_hostport, sf->num_calls_serviced);
 
-    grpc_call_destroy(s);
+    grpc_call_unref(s);
     cq_verifier_destroy(cqv);
     grpc_metadata_array_destroy(&request_metadata_recv);
     grpc_call_details_destroy(&call_details);
@@ -557,7 +557,7 @@ static void perform_request(client_fixture *cf) {
   peer = grpc_call_get_peer(c);
   gpr_log(GPR_INFO, "Client DONE WITH SERVER %s ", peer);
 
-  grpc_call_destroy(c);
+  grpc_call_unref(c);
 
   cq_verify_empty_timeout(cqv, 1 /* seconds */);
   cq_verifier_destroy(cqv);
@@ -573,34 +573,51 @@ static void perform_request(client_fixture *cf) {
 static void setup_client(const server_fixture *lb_server,
                          const server_fixture *backends, client_fixture *cf) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  char *lb_uri;
-  // The grpclb LB policy will be automatically selected by virtue of
-  // the fact that the returned addresses are balancer addresses.
-  gpr_asprintf(&lb_uri, "test:///%s?lb_enabled=1&balancer_names=%s",
-               lb_server->servers_hostport, lb_server->balancer_name);
-
-  grpc_arg expected_target_arg;
-  expected_target_arg.type = GRPC_ARG_STRING;
-  expected_target_arg.key =
-      const_cast<char *>(GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS);
 
   char *expected_target_names = NULL;
   const char *backends_name = lb_server->servers_hostport;
   gpr_asprintf(&expected_target_names, "%s;%s", backends_name, BALANCERS_NAME);
 
-  expected_target_arg.value.string = const_cast<char *>(expected_target_names);
+  grpc_fake_resolver_response_generator *response_generator =
+      grpc_fake_resolver_response_generator_create();
+
+  grpc_lb_addresses *addresses = grpc_lb_addresses_create(1, NULL);
+  char *lb_uri_str;
+  gpr_asprintf(&lb_uri_str, "ipv4:%s", lb_server->servers_hostport);
+  grpc_uri *lb_uri = grpc_uri_parse(&exec_ctx, lb_uri_str, true);
+  GPR_ASSERT(lb_uri != NULL);
+  grpc_lb_addresses_set_address_from_uri(addresses, 0, lb_uri, true,
+                                         lb_server->balancer_name, NULL);
+  grpc_uri_destroy(lb_uri);
+  gpr_free(lb_uri_str);
+
+  gpr_asprintf(&cf->server_uri, "test:///%s", lb_server->servers_hostport);
+  const grpc_arg fake_addresses =
+      grpc_lb_addresses_create_channel_arg(addresses);
+  grpc_channel_args *fake_result =
+      grpc_channel_args_copy_and_add(NULL, &fake_addresses, 1);
+  grpc_lb_addresses_destroy(&exec_ctx, addresses);
+
+  const grpc_arg new_args[] = {
+      grpc_fake_transport_expected_targets_arg(expected_target_names),
+      grpc_fake_resolver_response_generator_arg(response_generator)};
+
   grpc_channel_args *args =
-      grpc_channel_args_copy_and_add(NULL, &expected_target_arg, 1);
+      grpc_channel_args_copy_and_add(NULL, new_args, GPR_ARRAY_SIZE(new_args));
   gpr_free(expected_target_names);
 
-  cf->cq = grpc_completion_queue_create(NULL);
-  cf->server_uri = lb_uri;
+  cf->cq = grpc_completion_queue_create_for_next(NULL);
   grpc_channel_credentials *fake_creds =
       grpc_fake_transport_security_credentials_create();
   cf->client =
       grpc_secure_channel_create(fake_creds, cf->server_uri, args, NULL);
+  grpc_fake_resolver_response_generator_set_response(
+      &exec_ctx, response_generator, fake_result);
+  grpc_channel_args_destroy(&exec_ctx, fake_result);
   grpc_channel_credentials_unref(&exec_ctx, fake_creds);
   grpc_channel_args_destroy(&exec_ctx, args);
+  grpc_fake_resolver_response_generator_unref(response_generator);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void teardown_client(client_fixture *cf) {
@@ -616,7 +633,7 @@ static void teardown_client(client_fixture *cf) {
 static void setup_server(const char *host, server_fixture *sf) {
   int assigned_port;
 
-  sf->cq = grpc_completion_queue_create(NULL);
+  sf->cq = grpc_completion_queue_create_for_next(NULL);
   const char *colon_idx = strchr(host, ':');
   if (colon_idx) {
     const char *port_str = colon_idx + 1;
@@ -643,10 +660,15 @@ static void teardown_server(server_fixture *sf) {
   if (!sf->server) return;
 
   gpr_log(GPR_INFO, "Server[%s] shutting down", sf->servers_hostport);
-  grpc_server_shutdown_and_notify(sf->server, sf->cq, tag(1000));
-  GPR_ASSERT(grpc_completion_queue_pluck(
-                 sf->cq, tag(1000), grpc_timeout_seconds_to_deadline(5), NULL)
+
+  grpc_completion_queue *shutdown_cq =
+      grpc_completion_queue_create_for_pluck(NULL);
+  grpc_server_shutdown_and_notify(sf->server, shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         NULL)
                  .type == GRPC_OP_COMPLETE);
+  grpc_completion_queue_destroy(shutdown_cq);
   grpc_server_destroy(sf->server);
   gpr_thd_join(sf->tid);
 
@@ -782,8 +804,8 @@ TEST(GrpclbTest, InvalidAddressInServerlist) {}
 
 int main(int argc, char **argv) {
   ::testing::InitGoogleTest(&argc, argv);
-  grpc_test_init(argc, argv);
   grpc_fake_resolver_init();
+  grpc_test_init(argc, argv);
   grpc_init();
   const auto result = RUN_ALL_TESTS();
   grpc_shutdown();
diff --git a/test/cpp/interop/BUILD b/test/cpp/interop/BUILD
new file mode 100644
index 0000000000000000000000000000000000000000..1a3e8d916fa243f1e79509d5b85ee6121d180687
--- /dev/null
+++ b/test/cpp/interop/BUILD
@@ -0,0 +1,90 @@
+# Copyright 2017, 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.
+
+licenses(["notice"])  # 3-clause BSD
+
+cc_library(
+    name = "server_helper_lib",
+    srcs = [
+        "server_helper.cc",
+    ],
+    hdrs = [
+        "server_helper.h",
+    ],
+    deps = [
+        "//test/cpp/util:test_util",
+        "//external:gflags",
+    ],
+)
+
+cc_binary(
+    name = "interop_server",
+    srcs = [
+        "interop_server.cc",
+        "interop_server_bootstrap.cc",
+    ],
+    deps = [
+        ":server_helper_lib",
+        "//:grpc++",
+        "//src/proto/grpc/testing:empty_proto",
+        "//src/proto/grpc/testing:messages_proto",
+        "//src/proto/grpc/testing:test_proto",
+        "//test/cpp/util:test_config",
+    ],
+)
+
+cc_library(
+    name = "client_helper_lib",
+    srcs = [
+        "client_helper.cc",
+        "interop_client.cc",
+    ],
+    hdrs = [
+        "client_helper.h",
+        "interop_client.h",
+    ],
+    deps = [
+        "//test/cpp/util:test_util",
+        "//src/proto/grpc/testing:empty_proto",
+        "//src/proto/grpc/testing:messages_proto",
+        "//src/proto/grpc/testing:test_proto",
+        "//test/core/security:oauth2_utils",
+        "//test/cpp/util:test_config",
+    ],
+)
+
+cc_binary(
+    name = "interop_client",
+    srcs = [
+        "client.cc",
+    ],
+    deps = [
+        ":client_helper_lib",
+    ],
+)
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index 5688ab7971622238258a7dffa5626b1b26cec1b8..6f1d910304c52e07326b5aeff147983f082fe896 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -99,6 +99,7 @@ DEFINE_bool(do_not_abort_on_transient_failures, false,
 
 using grpc::testing::CreateChannelForTestCase;
 using grpc::testing::GetServiceAccountJsonKey;
+using grpc::testing::UpdateActions;
 
 int main(int argc, char** argv) {
   grpc::testing::InitTest(&argc, &argv, true);
@@ -162,8 +163,10 @@ int main(int argc, char** argv) {
       std::bind(&grpc::testing::InteropClient::DoUnimplementedMethod, &client);
   actions["unimplemented_service"] =
       std::bind(&grpc::testing::InteropClient::DoUnimplementedService, &client);
-  // actions["cacheable_unary"] =
-  //    std::bind(&grpc::testing::InteropClient::DoCacheableUnary, &client);
+  actions["cacheable_unary"] =
+      std::bind(&grpc::testing::InteropClient::DoCacheableUnary, &client);
+
+  UpdateActions(&actions);
 
   if (FLAGS_test_case == "all") {
     for (const auto& action : actions) {
diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc
index d3192ad0c93b5e905063112e103fb4c558561146..784cd2826d62e908cce79c8f44c549f6887f8e3e 100644
--- a/test/cpp/interop/client_helper.cc
+++ b/test/cpp/interop/client_helper.cc
@@ -89,6 +89,9 @@ grpc::string GetOauth2AccessToken() {
   return access_token;
 }
 
+void UpdateActions(
+    std::unordered_map<grpc::string, std::function<bool()>>* actions) {}
+
 std::shared_ptr<Channel> CreateChannelForTestCase(
     const grpc::string& test_case) {
   GPR_ASSERT(FLAGS_server_port);
diff --git a/test/cpp/interop/client_helper.h b/test/cpp/interop/client_helper.h
index 622b96e4fbfd04010d1b80935a8d420e1c16bebb..387530a21c7f184bb1f0553c0f8933054b3ff42c 100644
--- a/test/cpp/interop/client_helper.h
+++ b/test/cpp/interop/client_helper.h
@@ -35,6 +35,7 @@
 #define GRPC_TEST_CPP_INTEROP_CLIENT_HELPER_H
 
 #include <memory>
+#include <unordered_map>
 
 #include <grpc++/channel.h>
 
@@ -47,6 +48,9 @@ grpc::string GetServiceAccountJsonKey();
 
 grpc::string GetOauth2AccessToken();
 
+void UpdateActions(
+    std::unordered_map<grpc::string, std::function<bool()>>* actions);
+
 std::shared_ptr<Channel> CreateChannelForTestCase(
     const grpc::string& test_case);
 
diff --git a/test/cpp/interop/http2_client.cc b/test/cpp/interop/http2_client.cc
index 01c07823cfe9664711fdfbcd3382e3d262d4bbe2..2109e346164cd3c7d8553274ae18ba793c5a3544 100644
--- a/test/cpp/interop/http2_client.cc
+++ b/test/cpp/interop/http2_client.cc
@@ -41,7 +41,7 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/transport/byte_stream.h"
-#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/messages.pb.h"
 #include "src/proto/grpc/testing/test.grpc.pb.h"
 #include "test/cpp/interop/http2_client.h"
 
@@ -108,7 +108,7 @@ bool Http2Client::DoRstAfterData() {
 
   SimpleResponse response;
   AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL);
-  GPR_ASSERT(response.has_payload());  // data should be received
+  // There is no guarantee that data would be received.
 
   gpr_log(GPR_DEBUG, "Done testing reset stream after data");
   return true;
diff --git a/test/cpp/interop/http2_client.h b/test/cpp/interop/http2_client.h
index 12df5d26bc27a67a42dde78b0ff22bd4960e6a49..e57d695205bf919c9b887b7c04fab0121fd03218 100644
--- a/test/cpp/interop/http2_client.h
+++ b/test/cpp/interop/http2_client.h
@@ -38,7 +38,7 @@
 
 #include <grpc++/channel.h>
 #include <grpc/grpc.h>
-#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/messages.pb.h"
 #include "src/proto/grpc/testing/test.grpc.pb.h"
 
 namespace grpc {
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index b7f2723c39bd302862d5e746eda95985434c839f..0e79c5e4b44a418c833eab3a1353772aff9f2dfb 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -46,8 +46,8 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/transport/byte_stream.h"
-#include "src/proto/grpc/testing/empty.grpc.pb.h"
-#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/empty.pb.h"
+#include "src/proto/grpc/testing/messages.pb.h"
 #include "src/proto/grpc/testing/test.grpc.pb.h"
 #include "test/cpp/interop/client_helper.h"
 #include "test/cpp/interop/interop_client.h"
@@ -918,6 +918,26 @@ bool InteropClient::DoCacheableUnary() {
   // second response is a cached copy of the first response
   GPR_ASSERT(response2.payload().body() == response1.payload().body());
 
+  // Request 3
+  // Modify the request body so it will not get a cache hit
+  ts = gpr_now(GPR_CLOCK_PRECISE);
+  timestamp = std::to_string((long long unsigned)ts.tv_nsec);
+  SimpleRequest request1;
+  request1.mutable_payload()->set_body(timestamp.c_str(), timestamp.size());
+  ClientContext context3;
+  SimpleResponse response3;
+  context3.set_cacheable(true);
+  context3.AddMetadata("x-user-ip", "1.2.3.4");
+  Status s3 =
+      serviceStub_.Get()->CacheableUnaryCall(&context3, request1, &response3);
+  if (!AssertStatusOk(s3)) {
+    return false;
+  }
+  gpr_log(GPR_DEBUG, "response 3 payload: %s",
+          response3.payload().body().c_str());
+
+  // Check that the response is different from the previous response.
+  GPR_ASSERT(response3.payload().body() != response1.payload().body());
   return true;
 }
 
diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h
index 74f4db6b78903f37c80e679b1667bcba0490e8ae..efcb7d286085b0e22273c55c9def3b558a5aee40 100644
--- a/test/cpp/interop/interop_client.h
+++ b/test/cpp/interop/interop_client.h
@@ -38,7 +38,7 @@
 
 #include <grpc++/channel.h>
 #include <grpc/grpc.h>
-#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/messages.pb.h"
 #include "src/proto/grpc/testing/test.grpc.pb.h"
 
 namespace grpc {
diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc
index 5a810b45ef4f132c3694c0a53c68ddfec669ed27..1cbca179287aa20b1a4730eaaac4d33e74812952 100644
--- a/test/cpp/interop/interop_server.cc
+++ b/test/cpp/interop/interop_server.cc
@@ -48,8 +48,8 @@
 
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/byte_stream.h"
-#include "src/proto/grpc/testing/empty.grpc.pb.h"
-#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/empty.pb.h"
+#include "src/proto/grpc/testing/messages.pb.h"
 #include "src/proto/grpc/testing/test.grpc.pb.h"
 #include "test/cpp/interop/server_helper.h"
 #include "test/cpp/util/test_config.h"
diff --git a/test/cpp/interop/reconnect_interop_client.cc b/test/cpp/interop/reconnect_interop_client.cc
index 1c2f6066377b1c652fe0e7be41722d3801b29c5f..01d985068dcb05662cf1f0d251bd8ffcbfd2246d 100644
--- a/test/cpp/interop/reconnect_interop_client.cc
+++ b/test/cpp/interop/reconnect_interop_client.cc
@@ -40,8 +40,8 @@
 #include <grpc++/support/channel_arguments.h>
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
-#include "src/proto/grpc/testing/empty.grpc.pb.h"
-#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/empty.pb.h"
+#include "src/proto/grpc/testing/messages.pb.h"
 #include "src/proto/grpc/testing/test.grpc.pb.h"
 #include "test/cpp/util/create_test_channel.h"
 #include "test/cpp/util/test_config.h"
diff --git a/test/cpp/interop/reconnect_interop_server.cc b/test/cpp/interop/reconnect_interop_server.cc
index 634d0a90fceb85e5834f85968254652522ef2b53..8d1b884af91d6976a7d783146ad62b6cc7781e72 100644
--- a/test/cpp/interop/reconnect_interop_server.cc
+++ b/test/cpp/interop/reconnect_interop_server.cc
@@ -47,8 +47,8 @@
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
 
-#include "src/proto/grpc/testing/empty.grpc.pb.h"
-#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/empty.pb.h"
+#include "src/proto/grpc/testing/messages.pb.h"
 #include "src/proto/grpc/testing/test.grpc.pb.h"
 #include "test/core/util/reconnect_server.h"
 #include "test/cpp/util/test_config.h"
diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD
new file mode 100644
index 0000000000000000000000000000000000000000..cae3fa1a1461bcb30837cdcf7fb9a81b8e0f5ebc
--- /dev/null
+++ b/test/cpp/microbenchmarks/BUILD
@@ -0,0 +1,108 @@
+# Copyright 2017, 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.
+
+licenses(["notice"])  # 3-clause BSD
+
+cc_test(
+    name = "noop-benchmark",
+    srcs = ["noop-benchmark.cc"],
+    linkopts = ["-pthread"],
+    deps = ["//external:benchmark"],
+)
+
+cc_library(
+    name = "helpers",
+    srcs = ["helpers.cc"],
+    hdrs = [
+        "fullstack_context_mutators.h",
+        "fullstack_fixtures.h",
+        "helpers.h",
+    ],
+    linkopts = ["-pthread"],
+    deps = [
+        "//:grpc++",
+        "//external:benchmark",
+        "//src/proto/grpc/testing:echo_proto",
+        "//test/core/util:grpc_test_util",
+    ],
+)
+
+cc_test(
+    name = "bm_closure",
+    srcs = ["bm_closure.cc"],
+    deps = [":helpers"],
+)
+
+cc_test(
+    name = "bm_cq",
+    srcs = ["bm_cq.cc"],
+    deps = [":helpers"],
+)
+
+cc_test(
+    name = "bm_cq_multiple_threads",
+    srcs = ["bm_cq_multiple_threads.cc"],
+    deps = [":helpers"],
+)
+
+cc_test(
+    name = "bm_error",
+    srcs = ["bm_error.cc"],
+    deps = [":helpers"],
+)
+
+cc_test(
+    name = "bm_fullstack_streaming_ping_pong",
+    srcs = ["bm_fullstack_streaming_ping_pong.cc"],
+    deps = [":helpers"],
+)
+
+cc_test(
+    name = "bm_fullstack_streaming_pump",
+    srcs = ["bm_fullstack_streaming_pump.cc"],
+    deps = [":helpers"],
+)
+
+cc_test(
+    name = "bm_fullstack_trickle",
+    srcs = ["bm_fullstack_trickle.cc"],
+    deps = [":helpers"],
+)
+
+cc_test(
+    name = "bm_fullstack_unary_ping_pong",
+    srcs = ["bm_fullstack_unary_ping_pong.cc"],
+    deps = [":helpers"],
+)
+
+cc_test(
+    name = "bm_metadata",
+    srcs = ["bm_metadata.cc"],
+    deps = [":helpers"],
+)
diff --git a/test/cpp/microbenchmarks/bm_arena.cc b/test/cpp/microbenchmarks/bm_arena.cc
new file mode 100644
index 0000000000000000000000000000000000000000..770c0b6d4741d4e1a42524e64a3a947d568733c2
--- /dev/null
+++ b/test/cpp/microbenchmarks/bm_arena.cc
@@ -0,0 +1,76 @@
+/*
+ *
+ * Copyright 2017, 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.
+ *
+ */
+
+/* Benchmark arenas */
+
+extern "C" {
+#include "src/core/lib/support/arena.h"
+}
+#include "test/cpp/microbenchmarks/helpers.h"
+#include "third_party/benchmark/include/benchmark/benchmark.h"
+
+static void BM_Arena_NoOp(benchmark::State& state) {
+  while (state.KeepRunning()) {
+    gpr_arena_destroy(gpr_arena_create(state.range(0)));
+  }
+}
+BENCHMARK(BM_Arena_NoOp)->Range(1, 1024 * 1024);
+
+static void BM_Arena_ManyAlloc(benchmark::State& state) {
+  gpr_arena* a = gpr_arena_create(state.range(0));
+  const size_t realloc_after =
+      1024 * 1024 * 1024 / ((state.range(1) + 15) & 0xffffff0u);
+  while (state.KeepRunning()) {
+    gpr_arena_alloc(a, state.range(1));
+    // periodically recreate arena to avoid OOM
+    if (state.iterations() % realloc_after == 0) {
+      gpr_arena_destroy(a);
+      a = gpr_arena_create(state.range(0));
+    }
+  }
+  gpr_arena_destroy(a);
+}
+BENCHMARK(BM_Arena_ManyAlloc)->Ranges({{1, 1024 * 1024}, {1, 32 * 1024}});
+
+static void BM_Arena_Batch(benchmark::State& state) {
+  while (state.KeepRunning()) {
+    gpr_arena* a = gpr_arena_create(state.range(0));
+    for (int i = 0; i < state.range(1); i++) {
+      gpr_arena_alloc(a, state.range(2));
+    }
+    gpr_arena_destroy(a);
+  }
+}
+BENCHMARK(BM_Arena_Batch)->Ranges({{1, 64 * 1024}, {1, 64}, {1, 1024}});
+
+BENCHMARK_MAIN();
diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc
index 76d5030276934d1a3aaffb1b204f3d2f366d829b..c91219e98c8ce3467f9e7d5429f7201feb8843f5 100644
--- a/test/cpp/microbenchmarks/bm_call_create.cc
+++ b/test/cpp/microbenchmarks/bm_call_create.cc
@@ -34,49 +34,298 @@
 /* This benchmark exists to ensure that the benchmark integration is
  * working */
 
+#include <benchmark/benchmark.h>
 #include <string.h>
 #include <sstream>
 
+#include <grpc++/channel.h>
 #include <grpc++/support/channel_arguments.h>
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
 
 extern "C" {
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/load_reporting/load_reporting_filter.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/deadline/deadline_filter.h"
+#include "src/core/ext/filters/http/client/http_client_filter.h"
+#include "src/core/ext/filters/http/message_compress/message_compress_filter.h"
+#include "src/core/ext/filters/http/server/http_server_filter.h"
+#include "src/core/ext/filters/load_reporting/load_reporting_filter.h"
+#include "src/core/ext/filters/message_size/message_size_filter.h"
 #include "src/core/lib/channel/channel_stack.h"
-#include "src/core/lib/channel/compress_filter.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/deadline_filter.h"
-#include "src/core/lib/channel/http_client_filter.h"
-#include "src/core/lib/channel/http_server_filter.h"
-#include "src/core/lib/channel/message_size_filter.h"
+#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/surface/channel.h"
 #include "src/core/lib/transport/transport_impl.h"
 }
 
-#include "third_party/benchmark/include/benchmark/benchmark.h"
+#include "src/cpp/client/create_channel_internal.h"
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/cpp/microbenchmarks/helpers.h"
 
-static struct Init {
-  Init() { grpc_init(); }
-  ~Init() { grpc_shutdown(); }
-} g_init;
+auto &force_library_initialization = Library::get();
 
-static void BM_InsecureChannelWithDefaults(benchmark::State &state) {
-  grpc_channel *channel =
-      grpc_insecure_channel_create("localhost:12345", NULL, NULL);
-  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
-  grpc_slice method = grpc_slice_from_static_string("/foo/bar");
+void BM_Zalloc(benchmark::State &state) {
+  // speed of light for call creation is zalloc, so benchmark a few interesting
+  // sizes
+  TrackCounters track_counters;
+  size_t sz = state.range(0);
+  while (state.KeepRunning()) {
+    gpr_free(gpr_zalloc(sz));
+  }
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_Zalloc)
+    ->Arg(64)
+    ->Arg(128)
+    ->Arg(256)
+    ->Arg(512)
+    ->Arg(1024)
+    ->Arg(1536)
+    ->Arg(2048)
+    ->Arg(3072)
+    ->Arg(4096)
+    ->Arg(5120)
+    ->Arg(6144)
+    ->Arg(7168);
+
+////////////////////////////////////////////////////////////////////////////////
+// Benchmarks creating full stacks
+
+class BaseChannelFixture {
+ public:
+  BaseChannelFixture(grpc_channel *channel) : channel_(channel) {}
+  ~BaseChannelFixture() { grpc_channel_destroy(channel_); }
+
+  grpc_channel *channel() const { return channel_; }
+
+ private:
+  grpc_channel *const channel_;
+};
+
+class InsecureChannel : public BaseChannelFixture {
+ public:
+  InsecureChannel()
+      : BaseChannelFixture(
+            grpc_insecure_channel_create("localhost:1234", NULL, NULL)) {}
+};
+
+class LameChannel : public BaseChannelFixture {
+ public:
+  LameChannel()
+      : BaseChannelFixture(grpc_lame_client_channel_create(
+            "localhost:1234", GRPC_STATUS_UNAUTHENTICATED, "blah")) {}
+};
+
+template <class Fixture>
+static void BM_CallCreateDestroy(benchmark::State &state) {
+  TrackCounters track_counters;
+  Fixture fixture;
+  grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
   gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
+  void *method_hdl =
+      grpc_channel_register_call(fixture.channel(), "/foo/bar", NULL, NULL);
+  while (state.KeepRunning()) {
+    grpc_call_unref(grpc_channel_create_registered_call(
+        fixture.channel(), NULL, GRPC_PROPAGATE_DEFAULTS, cq, method_hdl,
+        deadline, NULL));
+  }
+  grpc_completion_queue_destroy(cq);
+  track_counters.Finish(state);
+}
+
+BENCHMARK_TEMPLATE(BM_CallCreateDestroy, InsecureChannel);
+BENCHMARK_TEMPLATE(BM_CallCreateDestroy, LameChannel);
+
+////////////////////////////////////////////////////////////////////////////////
+// Benchmarks isolating individual filters
+
+static void *tag(int i) {
+  return reinterpret_cast<void *>(static_cast<intptr_t>(i));
+}
+
+static void BM_LameChannelCallCreateCpp(benchmark::State &state) {
+  TrackCounters track_counters;
+  auto stub =
+      grpc::testing::EchoTestService::NewStub(grpc::CreateChannelInternal(
+          "", grpc_lame_client_channel_create(
+                  "localhost:1234", GRPC_STATUS_UNAUTHENTICATED, "blah")));
+  grpc::CompletionQueue cq;
+  grpc::testing::EchoRequest send_request;
+  grpc::testing::EchoResponse recv_response;
+  grpc::Status recv_status;
   while (state.KeepRunning()) {
-    grpc_call_destroy(grpc_channel_create_call(channel, NULL,
-                                               GRPC_PROPAGATE_DEFAULTS, cq,
-                                               method, NULL, deadline, NULL));
+    GPR_TIMER_SCOPE("BenchmarkCycle", 0);
+    grpc::ClientContext cli_ctx;
+    auto reader = stub->AsyncEcho(&cli_ctx, send_request, &cq);
+    reader->Finish(&recv_response, &recv_status, tag(0));
+    void *t;
+    bool ok;
+    GPR_ASSERT(cq.Next(&t, &ok));
+    GPR_ASSERT(ok);
+  }
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_LameChannelCallCreateCpp);
+
+static void do_nothing(void *ignored) {}
+
+static void BM_LameChannelCallCreateCore(benchmark::State &state) {
+  TrackCounters track_counters;
+
+  grpc_channel *channel;
+  grpc_completion_queue *cq;
+  grpc_metadata_array initial_metadata_recv;
+  grpc_metadata_array trailing_metadata_recv;
+  grpc_byte_buffer *response_payload_recv = NULL;
+  grpc_status_code status;
+  grpc_slice details;
+  grpc::testing::EchoRequest send_request;
+  grpc_slice send_request_slice =
+      grpc_slice_new(&send_request, sizeof(send_request), do_nothing);
+
+  channel = grpc_lame_client_channel_create(
+      "localhost:1234", GRPC_STATUS_UNAUTHENTICATED, "blah");
+  cq = grpc_completion_queue_create_for_next(NULL);
+  void *rc = grpc_channel_register_call(
+      channel, "/grpc.testing.EchoTestService/Echo", NULL, NULL);
+  while (state.KeepRunning()) {
+    GPR_TIMER_SCOPE("BenchmarkCycle", 0);
+    grpc_call *call = grpc_channel_create_registered_call(
+        channel, NULL, GRPC_PROPAGATE_DEFAULTS, cq, rc,
+        gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+    grpc_metadata_array_init(&initial_metadata_recv);
+    grpc_metadata_array_init(&trailing_metadata_recv);
+    grpc_byte_buffer *request_payload_send =
+        grpc_raw_byte_buffer_create(&send_request_slice, 1);
+
+    // Fill in call ops
+    grpc_op ops[6];
+    memset(ops, 0, sizeof(ops));
+    grpc_op *op = ops;
+    op->op = GRPC_OP_SEND_INITIAL_METADATA;
+    op->data.send_initial_metadata.count = 0;
+    op++;
+    op->op = GRPC_OP_SEND_MESSAGE;
+    op->data.send_message.send_message = request_payload_send;
+    op++;
+    op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+    op++;
+    op->op = GRPC_OP_RECV_INITIAL_METADATA;
+    op->data.recv_initial_metadata.recv_initial_metadata =
+        &initial_metadata_recv;
+    op++;
+    op->op = GRPC_OP_RECV_MESSAGE;
+    op->data.recv_message.recv_message = &response_payload_recv;
+    op++;
+    op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+    op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+    op->data.recv_status_on_client.status = &status;
+    op->data.recv_status_on_client.status_details = &details;
+    op++;
+
+    GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(call, ops,
+                                                     (size_t)(op - ops),
+                                                     (void *)1, NULL));
+    grpc_event ev = grpc_completion_queue_next(
+        cq, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+    GPR_ASSERT(ev.type != GRPC_QUEUE_SHUTDOWN);
+    GPR_ASSERT(ev.success != 0);
+    grpc_call_unref(call);
+    grpc_byte_buffer_destroy(request_payload_send);
+    grpc_byte_buffer_destroy(response_payload_recv);
+    grpc_metadata_array_destroy(&initial_metadata_recv);
+    grpc_metadata_array_destroy(&trailing_metadata_recv);
   }
   grpc_channel_destroy(channel);
   grpc_completion_queue_destroy(cq);
+  grpc_slice_unref(send_request_slice);
+  track_counters.Finish(state);
 }
-BENCHMARK(BM_InsecureChannelWithDefaults);
+BENCHMARK(BM_LameChannelCallCreateCore);
+
+static void BM_LameChannelCallCreateCoreSeparateBatch(benchmark::State &state) {
+  TrackCounters track_counters;
+
+  grpc_channel *channel;
+  grpc_completion_queue *cq;
+  grpc_metadata_array initial_metadata_recv;
+  grpc_metadata_array trailing_metadata_recv;
+  grpc_byte_buffer *response_payload_recv = NULL;
+  grpc_status_code status;
+  grpc_slice details;
+  grpc::testing::EchoRequest send_request;
+  grpc_slice send_request_slice =
+      grpc_slice_new(&send_request, sizeof(send_request), do_nothing);
+
+  channel = grpc_lame_client_channel_create(
+      "localhost:1234", GRPC_STATUS_UNAUTHENTICATED, "blah");
+  cq = grpc_completion_queue_create_for_next(NULL);
+  void *rc = grpc_channel_register_call(
+      channel, "/grpc.testing.EchoTestService/Echo", NULL, NULL);
+  while (state.KeepRunning()) {
+    GPR_TIMER_SCOPE("BenchmarkCycle", 0);
+    grpc_call *call = grpc_channel_create_registered_call(
+        channel, NULL, GRPC_PROPAGATE_DEFAULTS, cq, rc,
+        gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+    grpc_metadata_array_init(&initial_metadata_recv);
+    grpc_metadata_array_init(&trailing_metadata_recv);
+    grpc_byte_buffer *request_payload_send =
+        grpc_raw_byte_buffer_create(&send_request_slice, 1);
+
+    // Fill in call ops
+    grpc_op ops[3];
+    memset(ops, 0, sizeof(ops));
+    grpc_op *op = ops;
+    op->op = GRPC_OP_SEND_INITIAL_METADATA;
+    op->data.send_initial_metadata.count = 0;
+    op++;
+    op->op = GRPC_OP_SEND_MESSAGE;
+    op->data.send_message.send_message = request_payload_send;
+    op++;
+    op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+    op++;
+    GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(call, ops,
+                                                     (size_t)(op - ops),
+                                                     (void *)0, NULL));
+    memset(ops, 0, sizeof(ops));
+    op = ops;
+    op->op = GRPC_OP_RECV_INITIAL_METADATA;
+    op->data.recv_initial_metadata.recv_initial_metadata =
+        &initial_metadata_recv;
+    op++;
+    op->op = GRPC_OP_RECV_MESSAGE;
+    op->data.recv_message.recv_message = &response_payload_recv;
+    op++;
+    op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+    op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+    op->data.recv_status_on_client.status = &status;
+    op->data.recv_status_on_client.status_details = &details;
+    op++;
+
+    GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(call, ops,
+                                                     (size_t)(op - ops),
+                                                     (void *)1, NULL));
+    grpc_event ev = grpc_completion_queue_next(
+        cq, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+    GPR_ASSERT(ev.type != GRPC_QUEUE_SHUTDOWN);
+    GPR_ASSERT(ev.success == 0);
+    ev = grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME),
+                                    NULL);
+    GPR_ASSERT(ev.type != GRPC_QUEUE_SHUTDOWN);
+    GPR_ASSERT(ev.success != 0);
+    grpc_call_unref(call);
+    grpc_byte_buffer_destroy(request_payload_send);
+    grpc_byte_buffer_destroy(response_payload_recv);
+    grpc_metadata_array_destroy(&initial_metadata_recv);
+    grpc_metadata_array_destroy(&trailing_metadata_recv);
+  }
+  grpc_channel_destroy(channel);
+  grpc_completion_queue_destroy(cq);
+  grpc_slice_unref(send_request_slice);
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_LameChannelCallCreateCoreSeparateBatch);
 
 static void FilterDestroy(grpc_exec_ctx *exec_ctx, void *arg,
                           grpc_error *error) {
@@ -135,7 +384,7 @@ namespace dummy_filter {
 
 static void StartTransportStreamOp(grpc_exec_ctx *exec_ctx,
                                    grpc_call_element *elem,
-                                   grpc_transport_stream_op *op) {}
+                                   grpc_transport_stream_op_batch *op) {}
 
 static void StartTransportOp(grpc_exec_ctx *exec_ctx,
                              grpc_channel_element *elem,
@@ -153,7 +402,7 @@ static void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx,
 
 static void DestroyCallElem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                             const grpc_call_final_info *final_info,
-                            void *and_free_memory) {}
+                            grpc_closure *then_sched_closure) {}
 
 grpc_error *InitChannelElem(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem,
                             grpc_channel_element_args *args) {
@@ -196,7 +445,7 @@ const char *name;
 /* implementation of grpc_transport_init_stream */
 int InitStream(grpc_exec_ctx *exec_ctx, grpc_transport *self,
                grpc_stream *stream, grpc_stream_refcount *refcount,
-               const void *server_data) {
+               const void *server_data, gpr_arena *arena) {
   return 0;
 }
 
@@ -210,7 +459,7 @@ void SetPollsetSet(grpc_exec_ctx *exec_ctx, grpc_transport *self,
 
 /* implementation of grpc_transport_perform_stream_op */
 void PerformStreamOp(grpc_exec_ctx *exec_ctx, grpc_transport *self,
-                     grpc_stream *stream, grpc_transport_stream_op *op) {
+                     grpc_stream *stream, grpc_transport_stream_op_batch *op) {
   grpc_closure_sched(exec_ctx, op->on_complete, GRPC_ERROR_NONE);
 }
 
@@ -220,7 +469,7 @@ void PerformOp(grpc_exec_ctx *exec_ctx, grpc_transport *self,
 
 /* implementation of grpc_transport_destroy_stream */
 void DestroyStream(grpc_exec_ctx *exec_ctx, grpc_transport *self,
-                   grpc_stream *stream, void *and_free_memory) {}
+                   grpc_stream *stream, grpc_closure *then_sched_closure) {}
 
 /* implementation of grpc_transport_destroy */
 void Destroy(grpc_exec_ctx *exec_ctx, grpc_transport *self) {}
@@ -260,13 +509,15 @@ class SendEmptyMetadata {
     memset(&op_, 0, sizeof(op_));
     op_.on_complete = grpc_closure_init(&closure_, DoNothing, nullptr,
                                         grpc_schedule_on_exec_ctx);
+    op_.send_initial_metadata = true;
+    op_.payload = &op_payload_;
   }
 
   class Op {
    public:
     Op(grpc_exec_ctx *exec_ctx, SendEmptyMetadata *p, grpc_call_stack *s) {
       grpc_metadata_batch_init(&batch_);
-      p->op_.send_initial_metadata = &batch_;
+      p->op_payload_.send_initial_metadata.send_initial_metadata = &batch_;
     }
     void Finish(grpc_exec_ctx *exec_ctx) {
       grpc_metadata_batch_destroy(exec_ctx, &batch_);
@@ -280,7 +531,8 @@ class SendEmptyMetadata {
   const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC);
   const gpr_timespec start_time_ = gpr_now(GPR_CLOCK_MONOTONIC);
   const grpc_slice method_ = grpc_slice_from_static_string("/foo/bar");
-  grpc_transport_stream_op op_;
+  grpc_transport_stream_op_batch op_;
+  grpc_transport_stream_op_batch_payload op_payload_;
   grpc_closure closure_;
 };
 
@@ -289,6 +541,7 @@ class SendEmptyMetadata {
 // perform on said filter.
 template <class Fixture, class TestOp>
 static void BM_IsolatedFilter(benchmark::State &state) {
+  TrackCounters track_counters;
   Fixture fixture;
   std::ostringstream label;
 
@@ -314,7 +567,7 @@ static void BM_IsolatedFilter(benchmark::State &state) {
   grpc_channel_stack *channel_stack =
       static_cast<grpc_channel_stack *>(gpr_zalloc(channel_size));
   GPR_ASSERT(GRPC_LOG_IF_ERROR(
-      "call_stack_init",
+      "channel_stack_init",
       grpc_channel_stack_init(&exec_ctx, 1, FilterDestroy, channel_stack,
                               &filters[0], filters.size(), &channel_args,
                               fixture.flags & REQUIRES_TRANSPORT
@@ -329,21 +582,37 @@ static void BM_IsolatedFilter(benchmark::State &state) {
   grpc_slice method = grpc_slice_from_static_string("/foo/bar");
   grpc_call_final_info final_info;
   TestOp test_op_data;
+  grpc_call_element_args call_args;
+  call_args.call_stack = call_stack;
+  call_args.server_transport_data = NULL;
+  call_args.context = NULL;
+  call_args.path = method;
+  call_args.start_time = start_time;
+  call_args.deadline = deadline;
+  const int kArenaSize = 4096;
+  call_args.arena = gpr_arena_create(kArenaSize);
   while (state.KeepRunning()) {
+    GPR_TIMER_SCOPE("BenchmarkCycle", 0);
     GRPC_ERROR_UNREF(grpc_call_stack_init(&exec_ctx, channel_stack, 1,
-                                          DoNothing, NULL, NULL, NULL, method,
-                                          start_time, deadline, call_stack));
+                                          DoNothing, NULL, &call_args));
     typename TestOp::Op op(&exec_ctx, &test_op_data, call_stack);
     grpc_call_stack_destroy(&exec_ctx, call_stack, &final_info, NULL);
     op.Finish(&exec_ctx);
     grpc_exec_ctx_flush(&exec_ctx);
+    // recreate arena every 64k iterations to avoid oom
+    if (0 == (state.iterations() & 0xffff)) {
+      gpr_arena_destroy(call_args.arena);
+      call_args.arena = gpr_arena_create(kArenaSize);
+    }
   }
+  gpr_arena_destroy(call_args.arena);
   grpc_channel_stack_destroy(&exec_ctx, channel_stack);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(channel_stack);
   gpr_free(call_stack);
 
   state.SetLabel(label.str());
+  track_counters.Finish(state);
 }
 
 typedef Fixture<nullptr, 0> NoFilter;
@@ -353,7 +622,7 @@ BENCHMARK_TEMPLATE(BM_IsolatedFilter, DummyFilter, NoOp);
 BENCHMARK_TEMPLATE(BM_IsolatedFilter, DummyFilter, SendEmptyMetadata);
 typedef Fixture<&grpc_client_channel_filter, 0> ClientChannelFilter;
 BENCHMARK_TEMPLATE(BM_IsolatedFilter, ClientChannelFilter, NoOp);
-typedef Fixture<&grpc_compress_filter, CHECKS_NOT_LAST> CompressFilter;
+typedef Fixture<&grpc_message_compress_filter, CHECKS_NOT_LAST> CompressFilter;
 BENCHMARK_TEMPLATE(BM_IsolatedFilter, CompressFilter, NoOp);
 BENCHMARK_TEMPLATE(BM_IsolatedFilter, CompressFilter, SendEmptyMetadata);
 typedef Fixture<&grpc_client_deadline_filter, CHECKS_NOT_LAST>
@@ -379,4 +648,211 @@ typedef Fixture<&grpc_load_reporting_filter, CHECKS_NOT_LAST>
 BENCHMARK_TEMPLATE(BM_IsolatedFilter, LoadReportingFilter, NoOp);
 BENCHMARK_TEMPLATE(BM_IsolatedFilter, LoadReportingFilter, SendEmptyMetadata);
 
+////////////////////////////////////////////////////////////////////////////////
+// Benchmarks isolating grpc_call
+
+namespace isolated_call_filter {
+
+static void StartTransportStreamOp(grpc_exec_ctx *exec_ctx,
+                                   grpc_call_element *elem,
+                                   grpc_transport_stream_op_batch *op) {
+  if (op->recv_initial_metadata) {
+    grpc_closure_sched(
+        exec_ctx,
+        op->payload->recv_initial_metadata.recv_initial_metadata_ready,
+        GRPC_ERROR_NONE);
+  }
+  if (op->recv_message) {
+    grpc_closure_sched(exec_ctx, op->payload->recv_message.recv_message_ready,
+                       GRPC_ERROR_NONE);
+  }
+  grpc_closure_sched(exec_ctx, op->on_complete, GRPC_ERROR_NONE);
+}
+
+static void StartTransportOp(grpc_exec_ctx *exec_ctx,
+                             grpc_channel_element *elem,
+                             grpc_transport_op *op) {
+  if (op->disconnect_with_error != GRPC_ERROR_NONE) {
+    GRPC_ERROR_UNREF(op->disconnect_with_error);
+  }
+  grpc_closure_sched(exec_ctx, op->on_consumed, GRPC_ERROR_NONE);
+}
+
+static grpc_error *InitCallElem(grpc_exec_ctx *exec_ctx,
+                                grpc_call_element *elem,
+                                const grpc_call_element_args *args) {
+  return GRPC_ERROR_NONE;
+}
+
+static void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx,
+                                   grpc_call_element *elem,
+                                   grpc_polling_entity *pollent) {}
+
+static void DestroyCallElem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+                            const grpc_call_final_info *final_info,
+                            grpc_closure *then_sched_closure) {
+  grpc_closure_sched(exec_ctx, then_sched_closure, GRPC_ERROR_NONE);
+}
+
+grpc_error *InitChannelElem(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem,
+                            grpc_channel_element_args *args) {
+  return GRPC_ERROR_NONE;
+}
+
+void DestroyChannelElem(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem) {}
+
+char *GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
+  return gpr_strdup("peer");
+}
+
+void GetChannelInfo(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem,
+                    const grpc_channel_info *channel_info) {}
+
+static const grpc_channel_filter isolated_call_filter = {
+    StartTransportStreamOp,
+    StartTransportOp,
+    0,
+    InitCallElem,
+    SetPollsetOrPollsetSet,
+    DestroyCallElem,
+    0,
+    InitChannelElem,
+    DestroyChannelElem,
+    GetPeer,
+    GetChannelInfo,
+    "isolated_call_filter"};
+}  // namespace isolated_call_filter
+
+class IsolatedCallFixture : public TrackCounters {
+ public:
+  IsolatedCallFixture() {
+    grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create();
+    grpc_channel_stack_builder_set_name(builder, "dummy");
+    grpc_channel_stack_builder_set_target(builder, "dummy_target");
+    GPR_ASSERT(grpc_channel_stack_builder_append_filter(
+        builder, &isolated_call_filter::isolated_call_filter, NULL, NULL));
+    {
+      grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+      channel_ = grpc_channel_create_with_builder(&exec_ctx, builder,
+                                                  GRPC_CLIENT_CHANNEL);
+      grpc_exec_ctx_finish(&exec_ctx);
+    }
+    cq_ = grpc_completion_queue_create_for_next(NULL);
+  }
+
+  void Finish(benchmark::State &state) {
+    grpc_completion_queue_destroy(cq_);
+    grpc_channel_destroy(channel_);
+    TrackCounters::Finish(state);
+  }
+
+  grpc_channel *channel() const { return channel_; }
+  grpc_completion_queue *cq() const { return cq_; }
+
+ private:
+  grpc_completion_queue *cq_;
+  grpc_channel *channel_;
+};
+
+static void BM_IsolatedCall_NoOp(benchmark::State &state) {
+  IsolatedCallFixture fixture;
+  gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
+  void *method_hdl =
+      grpc_channel_register_call(fixture.channel(), "/foo/bar", NULL, NULL);
+  while (state.KeepRunning()) {
+    GPR_TIMER_SCOPE("BenchmarkCycle", 0);
+    grpc_call_unref(grpc_channel_create_registered_call(
+        fixture.channel(), nullptr, GRPC_PROPAGATE_DEFAULTS, fixture.cq(),
+        method_hdl, deadline, NULL));
+  }
+  fixture.Finish(state);
+}
+BENCHMARK(BM_IsolatedCall_NoOp);
+
+static void BM_IsolatedCall_Unary(benchmark::State &state) {
+  IsolatedCallFixture fixture;
+  gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
+  void *method_hdl =
+      grpc_channel_register_call(fixture.channel(), "/foo/bar", NULL, NULL);
+  grpc_slice slice = grpc_slice_from_static_string("hello world");
+  grpc_byte_buffer *send_message = grpc_raw_byte_buffer_create(&slice, 1);
+  grpc_byte_buffer *recv_message = NULL;
+  grpc_status_code status_code;
+  grpc_slice status_details = grpc_empty_slice();
+  grpc_metadata_array recv_initial_metadata;
+  grpc_metadata_array_init(&recv_initial_metadata);
+  grpc_metadata_array recv_trailing_metadata;
+  grpc_metadata_array_init(&recv_trailing_metadata);
+  grpc_op ops[6];
+  memset(ops, 0, sizeof(ops));
+  ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
+  ops[1].op = GRPC_OP_SEND_MESSAGE;
+  ops[1].data.send_message.send_message = send_message;
+  ops[2].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+  ops[3].op = GRPC_OP_RECV_INITIAL_METADATA;
+  ops[3].data.recv_initial_metadata.recv_initial_metadata =
+      &recv_initial_metadata;
+  ops[4].op = GRPC_OP_RECV_MESSAGE;
+  ops[4].data.recv_message.recv_message = &recv_message;
+  ops[5].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  ops[5].data.recv_status_on_client.status = &status_code;
+  ops[5].data.recv_status_on_client.status_details = &status_details;
+  ops[5].data.recv_status_on_client.trailing_metadata = &recv_trailing_metadata;
+  while (state.KeepRunning()) {
+    GPR_TIMER_SCOPE("BenchmarkCycle", 0);
+    grpc_call *call = grpc_channel_create_registered_call(
+        fixture.channel(), nullptr, GRPC_PROPAGATE_DEFAULTS, fixture.cq(),
+        method_hdl, deadline, NULL);
+    grpc_call_start_batch(call, ops, 6, tag(1), NULL);
+    grpc_completion_queue_next(fixture.cq(),
+                               gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL);
+    grpc_call_unref(call);
+  }
+  fixture.Finish(state);
+  grpc_metadata_array_destroy(&recv_initial_metadata);
+  grpc_metadata_array_destroy(&recv_trailing_metadata);
+  grpc_byte_buffer_destroy(send_message);
+}
+BENCHMARK(BM_IsolatedCall_Unary);
+
+static void BM_IsolatedCall_StreamingSend(benchmark::State &state) {
+  IsolatedCallFixture fixture;
+  gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
+  void *method_hdl =
+      grpc_channel_register_call(fixture.channel(), "/foo/bar", NULL, NULL);
+  grpc_slice slice = grpc_slice_from_static_string("hello world");
+  grpc_byte_buffer *send_message = grpc_raw_byte_buffer_create(&slice, 1);
+  grpc_metadata_array recv_initial_metadata;
+  grpc_metadata_array_init(&recv_initial_metadata);
+  grpc_metadata_array recv_trailing_metadata;
+  grpc_metadata_array_init(&recv_trailing_metadata);
+  grpc_op ops[2];
+  memset(ops, 0, sizeof(ops));
+  ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
+  ops[1].op = GRPC_OP_RECV_INITIAL_METADATA;
+  ops[1].data.recv_initial_metadata.recv_initial_metadata =
+      &recv_initial_metadata;
+  grpc_call *call = grpc_channel_create_registered_call(
+      fixture.channel(), nullptr, GRPC_PROPAGATE_DEFAULTS, fixture.cq(),
+      method_hdl, deadline, NULL);
+  grpc_call_start_batch(call, ops, 2, tag(1), NULL);
+  grpc_completion_queue_next(fixture.cq(), gpr_inf_future(GPR_CLOCK_MONOTONIC),
+                             NULL);
+  memset(ops, 0, sizeof(ops));
+  ops[0].op = GRPC_OP_SEND_MESSAGE;
+  ops[0].data.send_message.send_message = send_message;
+  while (state.KeepRunning()) {
+    GPR_TIMER_SCOPE("BenchmarkCycle", 0);
+    grpc_call_start_batch(call, ops, 1, tag(2), NULL);
+    grpc_completion_queue_next(fixture.cq(),
+                               gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL);
+  }
+  grpc_call_unref(call);
+  fixture.Finish(state);
+  grpc_metadata_array_destroy(&recv_initial_metadata);
+  grpc_metadata_array_destroy(&recv_trailing_metadata);
+  grpc_byte_buffer_destroy(send_message);
+}
+BENCHMARK(BM_IsolatedCall_StreamingSend);
+
 BENCHMARK_MAIN();
diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
index 5fb3f37130653dc483fba77b5592e4cd9809607f..581440682aa0887d4bf386a5b9752855d1c0e112 100644
--- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
+++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
@@ -33,6 +33,7 @@
 
 /* Microbenchmarks around CHTTP2 HPACK operations */
 
+#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <string.h>
 #include <sstream>
@@ -40,20 +41,20 @@ extern "C" {
 #include "src/core/ext/transport/chttp2/transport/hpack_encoder.h"
 #include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
 #include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/transport/static_metadata.h"
 }
+#include "test/cpp/microbenchmarks/helpers.h"
 #include "third_party/benchmark/include/benchmark/benchmark.h"
 
-static struct Init {
-  Init() { grpc_init(); }
-  ~Init() { grpc_shutdown(); }
-} g_init;
+auto &force_library_initialization = Library::get();
 
 ////////////////////////////////////////////////////////////////////////////////
 // HPACK encoder
 //
 
 static void BM_HpackEncoderInitDestroy(benchmark::State &state) {
+  TrackCounters track_counters;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_chttp2_hpack_compressor c;
   while (state.KeepRunning()) {
@@ -62,12 +63,15 @@ static void BM_HpackEncoderInitDestroy(benchmark::State &state) {
     grpc_exec_ctx_flush(&exec_ctx);
   }
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_HpackEncoderInitDestroy);
 
 template <class Fixture>
 static void BM_HpackEncoderEncodeHeader(benchmark::State &state) {
+  TrackCounters track_counters;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  static bool logged_representative_output = false;
 
   grpc_metadata_batch b;
   grpc_metadata_batch_init(&b);
@@ -86,8 +90,22 @@ static void BM_HpackEncoderEncodeHeader(benchmark::State &state) {
   grpc_slice_buffer outbuf;
   grpc_slice_buffer_init(&outbuf);
   while (state.KeepRunning()) {
-    grpc_chttp2_encode_header(&exec_ctx, &c, (uint32_t)state.iterations(), &b,
-                              state.range(0), state.range(1), &stats, &outbuf);
+    grpc_encode_header_options hopt = {
+        static_cast<uint32_t>(state.iterations()),
+        state.range(0) != 0,
+        Fixture::kEnableTrueBinary,
+        (size_t)state.range(1),
+        &stats,
+    };
+    grpc_chttp2_encode_header(&exec_ctx, &c, &b, &hopt, &outbuf);
+    if (!logged_representative_output && state.iterations() > 3) {
+      logged_representative_output = true;
+      for (size_t i = 0; i < outbuf.count; i++) {
+        char *s = grpc_dump_slice(outbuf.slices[i], GPR_DUMP_HEX);
+        gpr_log(GPR_DEBUG, "%" PRIdPTR ": %s", i, s);
+        gpr_free(s);
+      }
+    }
     grpc_slice_buffer_reset_and_unref_internal(&exec_ctx, &outbuf);
     grpc_exec_ctx_flush(&exec_ctx);
   }
@@ -102,12 +120,14 @@ static void BM_HpackEncoderEncodeHeader(benchmark::State &state) {
         << " header_bytes/iter:" << (static_cast<double>(stats.header_bytes) /
                                      static_cast<double>(state.iterations()));
   state.SetLabel(label.str());
+  track_counters.Finish(state);
 }
 
 namespace hpack_encoder_fixtures {
 
 class EmptyBatch {
  public:
+  static constexpr bool kEnableTrueBinary = false;
   static std::vector<grpc_mdelem> GetElems(grpc_exec_ctx *exec_ctx) {
     return {};
   }
@@ -115,6 +135,7 @@ class EmptyBatch {
 
 class SingleStaticElem {
  public:
+  static constexpr bool kEnableTrueBinary = false;
   static std::vector<grpc_mdelem> GetElems(grpc_exec_ctx *exec_ctx) {
     return {GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE};
   }
@@ -122,6 +143,7 @@ class SingleStaticElem {
 
 class SingleInternedElem {
  public:
+  static constexpr bool kEnableTrueBinary = false;
   static std::vector<grpc_mdelem> GetElems(grpc_exec_ctx *exec_ctx) {
     return {grpc_mdelem_from_slices(
         exec_ctx, grpc_slice_intern(grpc_slice_from_static_string("abc")),
@@ -129,8 +151,32 @@ class SingleInternedElem {
   }
 };
 
+template <int kLength, bool kTrueBinary>
+class SingleInternedBinaryElem {
+ public:
+  static constexpr bool kEnableTrueBinary = kTrueBinary;
+  static std::vector<grpc_mdelem> GetElems(grpc_exec_ctx *exec_ctx) {
+    grpc_slice bytes = MakeBytes();
+    std::vector<grpc_mdelem> out = {grpc_mdelem_from_slices(
+        exec_ctx, grpc_slice_intern(grpc_slice_from_static_string("abc-bin")),
+        grpc_slice_intern(bytes))};
+    grpc_slice_unref(bytes);
+    return out;
+  }
+
+ private:
+  static grpc_slice MakeBytes() {
+    std::vector<char> v;
+    for (int i = 0; i < kLength; i++) {
+      v.push_back(static_cast<char>(rand()));
+    }
+    return grpc_slice_from_copied_buffer(v.data(), v.size());
+  }
+};
+
 class SingleInternedKeyElem {
  public:
+  static constexpr bool kEnableTrueBinary = false;
   static std::vector<grpc_mdelem> GetElems(grpc_exec_ctx *exec_ctx) {
     return {grpc_mdelem_from_slices(
         exec_ctx, grpc_slice_intern(grpc_slice_from_static_string("abc")),
@@ -140,6 +186,7 @@ class SingleInternedKeyElem {
 
 class SingleNonInternedElem {
  public:
+  static constexpr bool kEnableTrueBinary = false;
   static std::vector<grpc_mdelem> GetElems(grpc_exec_ctx *exec_ctx) {
     return {grpc_mdelem_from_slices(exec_ctx,
                                     grpc_slice_from_static_string("abc"),
@@ -147,8 +194,28 @@ class SingleNonInternedElem {
   }
 };
 
+template <int kLength, bool kTrueBinary>
+class SingleNonInternedBinaryElem {
+ public:
+  static constexpr bool kEnableTrueBinary = kTrueBinary;
+  static std::vector<grpc_mdelem> GetElems(grpc_exec_ctx *exec_ctx) {
+    return {grpc_mdelem_from_slices(
+        exec_ctx, grpc_slice_from_static_string("abc-bin"), MakeBytes())};
+  }
+
+ private:
+  static grpc_slice MakeBytes() {
+    std::vector<char> v;
+    for (int i = 0; i < kLength; i++) {
+      v.push_back(static_cast<char>(rand()));
+    }
+    return grpc_slice_from_copied_buffer(v.data(), v.size());
+  }
+};
+
 class RepresentativeClientInitialMetadata {
  public:
+  static constexpr bool kEnableTrueBinary = true;
   static std::vector<grpc_mdelem> GetElems(grpc_exec_ctx *exec_ctx) {
     return {
         GRPC_MDELEM_SCHEME_HTTP, GRPC_MDELEM_METHOD_POST,
@@ -170,6 +237,7 @@ class RepresentativeClientInitialMetadata {
 
 class RepresentativeServerInitialMetadata {
  public:
+  static constexpr bool kEnableTrueBinary = true;
   static std::vector<grpc_mdelem> GetElems(grpc_exec_ctx *exec_ctx) {
     return {GRPC_MDELEM_STATUS_200,
             GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC,
@@ -179,6 +247,7 @@ class RepresentativeServerInitialMetadata {
 
 class RepresentativeServerTrailingMetadata {
  public:
+  static constexpr bool kEnableTrueBinary = true;
   static std::vector<grpc_mdelem> GetElems(grpc_exec_ctx *exec_ctx) {
     return {GRPC_MDELEM_GRPC_STATUS_0};
   }
@@ -193,8 +262,68 @@ BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleInternedKeyElem)
     ->Args({0, 16384});
 BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleInternedElem)
     ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleInternedBinaryElem<1, false>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleInternedBinaryElem<3, false>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleInternedBinaryElem<10, false>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleInternedBinaryElem<31, false>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleInternedBinaryElem<100, false>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleInternedBinaryElem<1, true>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleInternedBinaryElem<3, true>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleInternedBinaryElem<10, true>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleInternedBinaryElem<31, true>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleInternedBinaryElem<100, true>)
+    ->Args({0, 16384});
 BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleNonInternedElem)
     ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleNonInternedBinaryElem<1, false>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleNonInternedBinaryElem<3, false>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleNonInternedBinaryElem<10, false>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleNonInternedBinaryElem<31, false>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleNonInternedBinaryElem<100, false>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleNonInternedBinaryElem<1, true>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleNonInternedBinaryElem<3, true>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleNonInternedBinaryElem<10, true>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleNonInternedBinaryElem<31, true>)
+    ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+                   SingleNonInternedBinaryElem<100, true>)
+    ->Args({0, 16384});
 // test with a tiny frame size, to highlight continuation costs
 BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleNonInternedElem)
     ->Args({0, 1});
@@ -216,6 +345,7 @@ BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
 //
 
 static void BM_HpackParserInitDestroy(benchmark::State &state) {
+  TrackCounters track_counters;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_chttp2_hpack_parser p;
   while (state.KeepRunning()) {
@@ -224,6 +354,7 @@ static void BM_HpackParserInitDestroy(benchmark::State &state) {
     grpc_exec_ctx_flush(&exec_ctx);
   }
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_HpackParserInitDestroy);
 
@@ -234,6 +365,7 @@ static void UnrefHeader(grpc_exec_ctx *exec_ctx, void *user_data,
 
 template <class Fixture>
 static void BM_HpackParserParseHeader(benchmark::State &state) {
+  TrackCounters track_counters;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   std::vector<grpc_slice> init_slices = Fixture::GetInitSlices();
   std::vector<grpc_slice> benchmark_slices = Fixture::GetBenchmarkSlices();
@@ -250,13 +382,16 @@ static void BM_HpackParserParseHeader(benchmark::State &state) {
     }
     grpc_exec_ctx_flush(&exec_ctx);
   }
+  for (auto slice : init_slices) grpc_slice_unref(slice);
+  for (auto slice : benchmark_slices) grpc_slice_unref(slice);
   grpc_chttp2_hpack_parser_destroy(&exec_ctx, &p);
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 
 namespace hpack_parser_fixtures {
 
-static grpc_slice MakeSlice(std::initializer_list<uint8_t> bytes) {
+static grpc_slice MakeSlice(std::vector<uint8_t> bytes) {
   grpc_slice s = grpc_slice_malloc(bytes.size());
   uint8_t *p = GRPC_SLICE_START_PTR(s);
   for (auto b : bytes) {
@@ -340,6 +475,88 @@ class NonIndexedElem {
   }
 };
 
+template <int kLength, bool kTrueBinary>
+class NonIndexedBinaryElem;
+
+template <int kLength>
+class NonIndexedBinaryElem<kLength, true> {
+ public:
+  static std::vector<grpc_slice> GetInitSlices() { return {}; }
+  static std::vector<grpc_slice> GetBenchmarkSlices() {
+    std::vector<uint8_t> v = {
+        0x00, 0x07, 'a', 'b', 'c',
+        '-',  'b',  'i', 'n', static_cast<uint8_t>(kLength + 1),
+        0};
+    for (int i = 0; i < kLength; i++) {
+      v.push_back(static_cast<uint8_t>(i));
+    }
+    return {MakeSlice(v)};
+  }
+};
+
+template <>
+class NonIndexedBinaryElem<1, false> {
+ public:
+  static std::vector<grpc_slice> GetInitSlices() { return {}; }
+  static std::vector<grpc_slice> GetBenchmarkSlices() {
+    return {MakeSlice(
+        {0x00, 0x07, 'a', 'b', 'c', '-', 'b', 'i', 'n', 0x82, 0xf7, 0xb3})};
+  }
+};
+
+template <>
+class NonIndexedBinaryElem<3, false> {
+ public:
+  static std::vector<grpc_slice> GetInitSlices() { return {}; }
+  static std::vector<grpc_slice> GetBenchmarkSlices() {
+    return {MakeSlice({0x00, 0x07, 'a', 'b', 'c', '-', 'b', 'i', 'n', 0x84,
+                       0x7f, 0x4e, 0x29, 0x3f})};
+  }
+};
+
+template <>
+class NonIndexedBinaryElem<10, false> {
+ public:
+  static std::vector<grpc_slice> GetInitSlices() { return {}; }
+  static std::vector<grpc_slice> GetBenchmarkSlices() {
+    return {MakeSlice({0x00, 0x07, 'a',  'b',  'c',  '-',  'b',
+                       'i',  'n',  0x8b, 0x71, 0x0c, 0xa5, 0x81,
+                       0x73, 0x7b, 0x47, 0x13, 0xe9, 0xf7, 0xe3})};
+  }
+};
+
+template <>
+class NonIndexedBinaryElem<31, false> {
+ public:
+  static std::vector<grpc_slice> GetInitSlices() { return {}; }
+  static std::vector<grpc_slice> GetBenchmarkSlices() {
+    return {MakeSlice({0x00, 0x07, 'a',  'b',  'c',  '-',  'b',  'i',  'n',
+                       0xa3, 0x92, 0x43, 0x7f, 0xbe, 0x7c, 0xea, 0x6f, 0xf3,
+                       0x3d, 0xa7, 0xa7, 0x67, 0xfb, 0xe2, 0x82, 0xf7, 0xf2,
+                       0x8f, 0x1f, 0x9d, 0xdf, 0xf1, 0x7e, 0xb3, 0xef, 0xb2,
+                       0x8f, 0x53, 0x77, 0xce, 0x0c, 0x13, 0xe3, 0xfd, 0x87})};
+  }
+};
+
+template <>
+class NonIndexedBinaryElem<100, false> {
+ public:
+  static std::vector<grpc_slice> GetInitSlices() { return {}; }
+  static std::vector<grpc_slice> GetBenchmarkSlices() {
+    return {MakeSlice(
+        {0x00, 0x07, 'a',  'b',  'c',  '-',  'b',  'i',  'n',  0xeb, 0x1d, 0x4d,
+         0xe8, 0x96, 0x8c, 0x14, 0x20, 0x06, 0xc1, 0xc3, 0xdf, 0x6e, 0x1f, 0xef,
+         0xde, 0x2f, 0xde, 0xb7, 0xf2, 0xfe, 0x6d, 0xd4, 0xe4, 0x7d, 0xf5, 0x55,
+         0x46, 0x52, 0x3d, 0x91, 0xf2, 0xd4, 0x6f, 0xca, 0x34, 0xcd, 0xd9, 0x39,
+         0xbd, 0x03, 0x27, 0xe3, 0x9c, 0x74, 0xcc, 0x17, 0x34, 0xed, 0xa6, 0x6a,
+         0x77, 0x73, 0x10, 0xcd, 0x8e, 0x4e, 0x5c, 0x7c, 0x72, 0x39, 0xd8, 0xe6,
+         0x78, 0x6b, 0xdb, 0xa5, 0xb7, 0xab, 0xe7, 0x46, 0xae, 0x21, 0xab, 0x7f,
+         0x01, 0x89, 0x13, 0xd7, 0xca, 0x17, 0x6e, 0xcb, 0xd6, 0x79, 0x71, 0x68,
+         0xbf, 0x8a, 0x3f, 0x32, 0xe8, 0xba, 0xf5, 0xbe, 0xb3, 0xbc, 0xde, 0x28,
+         0xc7, 0xcf, 0x62, 0x7a, 0x58, 0x2c, 0xcf, 0x4d, 0xe3})};
+  }
+};
+
 class RepresentativeClientInitialMetadata {
  public:
   static std::vector<grpc_slice> GetInitSlices() {
@@ -431,6 +648,16 @@ BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, IndexedSingleInternedElem);
 BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, AddIndexedSingleInternedElem);
 BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, KeyIndexedSingleInternedElem);
 BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedElem);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<1, false>);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<3, false>);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<10, false>);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<31, false>);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<100, false>);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<1, true>);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<3, true>);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<10, true>);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<31, true>);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<100, true>);
 BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
                    RepresentativeClientInitialMetadata);
 BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8c5413b5fda57651254062bffc172581de948535
--- /dev/null
+++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc
@@ -0,0 +1,625 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/* Microbenchmarks around CHTTP2 transport operations */
+
+#include <grpc++/support/channel_arguments.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <string.h>
+#include <memory>
+#include <queue>
+#include <sstream>
+extern "C" {
+#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
+#include "src/core/ext/transport/chttp2/transport/internal.h"
+#include "src/core/lib/iomgr/resource_quota.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/transport/static_metadata.h"
+}
+#include "test/cpp/microbenchmarks/helpers.h"
+#include "third_party/benchmark/include/benchmark/benchmark.h"
+
+auto &force_library_initialization = Library::get();
+
+////////////////////////////////////////////////////////////////////////////////
+// Helper classes
+//
+
+class DummyEndpoint : public grpc_endpoint {
+ public:
+  DummyEndpoint() {
+    static const grpc_endpoint_vtable my_vtable = {read,
+                                                   write,
+                                                   get_workqueue,
+                                                   add_to_pollset,
+                                                   add_to_pollset_set,
+                                                   shutdown,
+                                                   destroy,
+                                                   get_resource_user,
+                                                   get_peer,
+                                                   get_fd};
+    grpc_endpoint::vtable = &my_vtable;
+    ru_ = grpc_resource_user_create(Library::get().rq(), "dummy_endpoint");
+  }
+
+  void PushInput(grpc_exec_ctx *exec_ctx, grpc_slice slice) {
+    if (read_cb_ == nullptr) {
+      GPR_ASSERT(!have_slice_);
+      buffered_slice_ = slice;
+      have_slice_ = true;
+      return;
+    }
+    grpc_slice_buffer_add(slices_, slice);
+    grpc_closure_sched(exec_ctx, read_cb_, GRPC_ERROR_NONE);
+    read_cb_ = nullptr;
+  }
+
+ private:
+  grpc_resource_user *ru_;
+  grpc_closure *read_cb_ = nullptr;
+  grpc_slice_buffer *slices_ = nullptr;
+  bool have_slice_ = false;
+  grpc_slice buffered_slice_;
+
+  void QueueRead(grpc_exec_ctx *exec_ctx, grpc_slice_buffer *slices,
+                 grpc_closure *cb) {
+    GPR_ASSERT(read_cb_ == nullptr);
+    if (have_slice_) {
+      have_slice_ = false;
+      grpc_slice_buffer_add(slices, buffered_slice_);
+      grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_NONE);
+      return;
+    }
+    read_cb_ = cb;
+    slices_ = slices;
+  }
+
+  static void read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
+                   grpc_slice_buffer *slices, grpc_closure *cb) {
+    static_cast<DummyEndpoint *>(ep)->QueueRead(exec_ctx, slices, cb);
+  }
+
+  static void write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
+                    grpc_slice_buffer *slices, grpc_closure *cb) {
+    grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_NONE);
+  }
+
+  static grpc_workqueue *get_workqueue(grpc_endpoint *ep) { return NULL; }
+
+  static void add_to_pollset(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
+                             grpc_pollset *pollset) {}
+
+  static void add_to_pollset_set(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
+                                 grpc_pollset_set *pollset) {}
+
+  static void shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
+                       grpc_error *why) {
+    grpc_resource_user_shutdown(exec_ctx,
+                                static_cast<DummyEndpoint *>(ep)->ru_);
+    grpc_closure_sched(exec_ctx, static_cast<DummyEndpoint *>(ep)->read_cb_,
+                       why);
+  }
+
+  static void destroy(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
+    grpc_resource_user_unref(exec_ctx, static_cast<DummyEndpoint *>(ep)->ru_);
+    delete static_cast<DummyEndpoint *>(ep);
+  }
+
+  static grpc_resource_user *get_resource_user(grpc_endpoint *ep) {
+    return static_cast<DummyEndpoint *>(ep)->ru_;
+  }
+  static char *get_peer(grpc_endpoint *ep) { return gpr_strdup("test"); }
+  static int get_fd(grpc_endpoint *ep) { return 0; }
+};
+
+class Fixture {
+ public:
+  Fixture(const grpc::ChannelArguments &args, bool client) {
+    grpc_channel_args c_args = args.c_channel_args();
+    ep_ = new DummyEndpoint;
+    t_ = grpc_create_chttp2_transport(exec_ctx(), &c_args, ep_, client);
+    grpc_chttp2_transport_start_reading(exec_ctx(), t_, NULL);
+    FlushExecCtx();
+  }
+
+  void FlushExecCtx() { grpc_exec_ctx_flush(&exec_ctx_); }
+
+  ~Fixture() {
+    grpc_transport_destroy(&exec_ctx_, t_);
+    grpc_exec_ctx_finish(&exec_ctx_);
+  }
+
+  grpc_chttp2_transport *chttp2_transport() {
+    return reinterpret_cast<grpc_chttp2_transport *>(t_);
+  }
+  grpc_transport *transport() { return t_; }
+  grpc_exec_ctx *exec_ctx() { return &exec_ctx_; }
+
+  void PushInput(grpc_slice slice) { ep_->PushInput(exec_ctx(), slice); }
+
+ private:
+  DummyEndpoint *ep_;
+  grpc_exec_ctx exec_ctx_ = GRPC_EXEC_CTX_INIT;
+  grpc_transport *t_;
+};
+
+static void DoNothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {}
+
+class Stream {
+ public:
+  Stream(Fixture *f) : f_(f) {
+    GRPC_STREAM_REF_INIT(&refcount_, 1, DoNothing, nullptr, "test_stream");
+    stream_size_ = grpc_transport_stream_size(f->transport());
+    stream_ = gpr_malloc(stream_size_);
+    arena_ = gpr_arena_create(4096);
+  }
+
+  ~Stream() {
+    gpr_free(stream_);
+    gpr_arena_destroy(arena_);
+  }
+
+  void Init(benchmark::State &state) {
+    memset(stream_, 0, stream_size_);
+    if ((state.iterations() & 0xffff) == 0) {
+      gpr_arena_destroy(arena_);
+      arena_ = gpr_arena_create(4096);
+    }
+    grpc_transport_init_stream(f_->exec_ctx(), f_->transport(),
+                               static_cast<grpc_stream *>(stream_), &refcount_,
+                               NULL, arena_);
+  }
+
+  void DestroyThen(grpc_closure *closure) {
+    grpc_transport_destroy_stream(f_->exec_ctx(), f_->transport(),
+                                  static_cast<grpc_stream *>(stream_), closure);
+  }
+
+  void Op(grpc_transport_stream_op_batch *op) {
+    grpc_transport_perform_stream_op(f_->exec_ctx(), f_->transport(),
+                                     static_cast<grpc_stream *>(stream_), op);
+  }
+
+  grpc_chttp2_stream *chttp2_stream() {
+    return static_cast<grpc_chttp2_stream *>(stream_);
+  }
+
+ private:
+  Fixture *f_;
+  grpc_stream_refcount refcount_;
+  gpr_arena *arena_;
+  size_t stream_size_;
+  void *stream_;
+};
+
+class Closure : public grpc_closure {
+ public:
+  virtual ~Closure() {}
+};
+
+template <class F>
+std::unique_ptr<Closure> MakeClosure(
+    F f, grpc_closure_scheduler *sched = grpc_schedule_on_exec_ctx) {
+  struct C : public Closure {
+    C(const F &f, grpc_closure_scheduler *sched) : f_(f) {
+      grpc_closure_init(this, Execute, this, sched);
+    }
+    F f_;
+    static void Execute(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+      static_cast<C *>(arg)->f_(exec_ctx, error);
+    }
+  };
+  return std::unique_ptr<Closure>(new C(f, sched));
+}
+
+template <class F>
+grpc_closure *MakeOnceClosure(
+    F f, grpc_closure_scheduler *sched = grpc_schedule_on_exec_ctx) {
+  struct C : public grpc_closure {
+    C(const F &f) : f_(f) {}
+    F f_;
+    static void Execute(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+      static_cast<C *>(arg)->f_(exec_ctx, error);
+      delete static_cast<C *>(arg);
+    }
+  };
+  auto *c = new C{f};
+  return grpc_closure_init(c, C::Execute, c, sched);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Benchmarks
+//
+
+static void BM_StreamCreateDestroy(benchmark::State &state) {
+  TrackCounters track_counters;
+  Fixture f(grpc::ChannelArguments(), true);
+  Stream s(&f);
+  std::unique_ptr<Closure> next =
+      MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) {
+        if (!state.KeepRunning()) return;
+        s.Init(state);
+        s.DestroyThen(next.get());
+      });
+  grpc_closure_run(f.exec_ctx(), next.get(), GRPC_ERROR_NONE);
+  f.FlushExecCtx();
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_StreamCreateDestroy);
+
+class RepresentativeClientInitialMetadata {
+ public:
+  static std::vector<grpc_mdelem> GetElems(grpc_exec_ctx *exec_ctx) {
+    return {
+        GRPC_MDELEM_SCHEME_HTTP, GRPC_MDELEM_METHOD_POST,
+        grpc_mdelem_from_slices(
+            exec_ctx, GRPC_MDSTR_PATH,
+            grpc_slice_intern(grpc_slice_from_static_string("/foo/bar"))),
+        grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_AUTHORITY,
+                                grpc_slice_intern(grpc_slice_from_static_string(
+                                    "foo.test.google.fr:1234"))),
+        GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP,
+        GRPC_MDELEM_TE_TRAILERS,
+        GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC,
+        grpc_mdelem_from_slices(
+            exec_ctx, GRPC_MDSTR_USER_AGENT,
+            grpc_slice_intern(grpc_slice_from_static_string(
+                "grpc-c/3.0.0-dev (linux; chttp2; green)")))};
+  }
+};
+
+template <class Metadata>
+static void BM_StreamCreateSendInitialMetadataDestroy(benchmark::State &state) {
+  TrackCounters track_counters;
+  Fixture f(grpc::ChannelArguments(), true);
+  Stream s(&f);
+  grpc_transport_stream_op_batch op;
+  grpc_transport_stream_op_batch_payload op_payload;
+  std::unique_ptr<Closure> start;
+  std::unique_ptr<Closure> done;
+
+  auto reset_op = [&]() {
+    memset(&op, 0, sizeof(op));
+    op.payload = &op_payload;
+  };
+
+  grpc_metadata_batch b;
+  grpc_metadata_batch_init(&b);
+  b.deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
+  std::vector<grpc_mdelem> elems = Metadata::GetElems(f.exec_ctx());
+  std::vector<grpc_linked_mdelem> storage(elems.size());
+  for (size_t i = 0; i < elems.size(); i++) {
+    GPR_ASSERT(GRPC_LOG_IF_ERROR(
+        "addmd",
+        grpc_metadata_batch_add_tail(f.exec_ctx(), &b, &storage[i], elems[i])));
+  }
+
+  f.FlushExecCtx();
+  start = MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) {
+    if (!state.KeepRunning()) return;
+    s.Init(state);
+    reset_op();
+    op.on_complete = done.get();
+    op.send_initial_metadata = true;
+    op.payload->send_initial_metadata.send_initial_metadata = &b;
+    s.Op(&op);
+  });
+  done = MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) {
+    reset_op();
+    op.cancel_stream = true;
+    op.payload->cancel_stream.cancel_error = GRPC_ERROR_CANCELLED;
+    s.Op(&op);
+    s.DestroyThen(start.get());
+  });
+  grpc_closure_sched(f.exec_ctx(), start.get(), GRPC_ERROR_NONE);
+  f.FlushExecCtx();
+  grpc_metadata_batch_destroy(f.exec_ctx(), &b);
+  track_counters.Finish(state);
+}
+BENCHMARK_TEMPLATE(BM_StreamCreateSendInitialMetadataDestroy,
+                   RepresentativeClientInitialMetadata);
+
+static void BM_TransportEmptyOp(benchmark::State &state) {
+  TrackCounters track_counters;
+  Fixture f(grpc::ChannelArguments(), true);
+  Stream s(&f);
+  s.Init(state);
+  grpc_transport_stream_op_batch op;
+  grpc_transport_stream_op_batch_payload op_payload;
+  auto reset_op = [&]() {
+    memset(&op, 0, sizeof(op));
+    op.payload = &op_payload;
+  };
+  std::unique_ptr<Closure> c =
+      MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) {
+        if (!state.KeepRunning()) return;
+        reset_op();
+        op.on_complete = c.get();
+        s.Op(&op);
+      });
+  grpc_closure_sched(f.exec_ctx(), c.get(), GRPC_ERROR_NONE);
+  f.FlushExecCtx();
+  s.DestroyThen(
+      MakeOnceClosure([](grpc_exec_ctx *exec_ctx, grpc_error *error) {}));
+  f.FlushExecCtx();
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_TransportEmptyOp);
+
+static void BM_TransportStreamSend(benchmark::State &state) {
+  TrackCounters track_counters;
+  Fixture f(grpc::ChannelArguments(), true);
+  Stream s(&f);
+  s.Init(state);
+  grpc_transport_stream_op_batch op;
+  grpc_transport_stream_op_batch_payload op_payload;
+  auto reset_op = [&]() {
+    memset(&op, 0, sizeof(op));
+    op.payload = &op_payload;
+  };
+  grpc_slice_buffer_stream send_stream;
+  grpc_slice_buffer send_buffer;
+  grpc_slice_buffer_init(&send_buffer);
+  grpc_slice_buffer_add(&send_buffer, gpr_slice_malloc(state.range(0)));
+  memset(GRPC_SLICE_START_PTR(send_buffer.slices[0]), 0,
+         GRPC_SLICE_LENGTH(send_buffer.slices[0]));
+
+  grpc_metadata_batch b;
+  grpc_metadata_batch_init(&b);
+  b.deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
+  std::vector<grpc_mdelem> elems =
+      RepresentativeClientInitialMetadata::GetElems(f.exec_ctx());
+  std::vector<grpc_linked_mdelem> storage(elems.size());
+  for (size_t i = 0; i < elems.size(); i++) {
+    GPR_ASSERT(GRPC_LOG_IF_ERROR(
+        "addmd",
+        grpc_metadata_batch_add_tail(f.exec_ctx(), &b, &storage[i], elems[i])));
+  }
+
+  std::unique_ptr<Closure> c =
+      MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) {
+        if (!state.KeepRunning()) return;
+        // force outgoing window to be yuge
+        s.chttp2_stream()->outgoing_window_delta = 1024 * 1024 * 1024;
+        f.chttp2_transport()->outgoing_window = 1024 * 1024 * 1024;
+        grpc_slice_buffer_stream_init(&send_stream, &send_buffer, 0);
+        reset_op();
+        op.on_complete = c.get();
+        op.send_message = true;
+        op.payload->send_message.send_message = &send_stream.base;
+        s.Op(&op);
+      });
+
+  reset_op();
+  op.send_initial_metadata = true;
+  op.payload->send_initial_metadata.send_initial_metadata = &b;
+  op.on_complete = c.get();
+  s.Op(&op);
+
+  f.FlushExecCtx();
+  reset_op();
+  op.cancel_stream = true;
+  op.payload->cancel_stream.cancel_error = GRPC_ERROR_CANCELLED;
+  s.Op(&op);
+  s.DestroyThen(
+      MakeOnceClosure([](grpc_exec_ctx *exec_ctx, grpc_error *error) {}));
+  f.FlushExecCtx();
+  track_counters.Finish(state);
+  grpc_metadata_batch_destroy(f.exec_ctx(), &b);
+  grpc_slice_buffer_destroy(&send_buffer);
+}
+BENCHMARK(BM_TransportStreamSend)->Range(0, 128 * 1024 * 1024);
+
+#define SLICE_FROM_BUFFER(s) grpc_slice_from_static_buffer(s, sizeof(s) - 1)
+
+static grpc_slice CreateIncomingDataSlice(size_t length, size_t frame_size) {
+  std::queue<char> unframed;
+
+  unframed.push(static_cast<uint8_t>(0));
+  unframed.push(static_cast<uint8_t>(length >> 24));
+  unframed.push(static_cast<uint8_t>(length >> 16));
+  unframed.push(static_cast<uint8_t>(length >> 8));
+  unframed.push(static_cast<uint8_t>(length));
+  for (size_t i = 0; i < length; i++) {
+    unframed.push('a');
+  }
+
+  std::vector<char> framed;
+  while (unframed.size() > frame_size) {
+    // frame size
+    framed.push_back(static_cast<uint8_t>(frame_size >> 16));
+    framed.push_back(static_cast<uint8_t>(frame_size >> 8));
+    framed.push_back(static_cast<uint8_t>(frame_size));
+    // data frame
+    framed.push_back(0);
+    // no flags
+    framed.push_back(0);
+    // stream id
+    framed.push_back(0);
+    framed.push_back(0);
+    framed.push_back(0);
+    framed.push_back(1);
+    // frame data
+    for (size_t i = 0; i < frame_size; i++) {
+      framed.push_back(unframed.front());
+      unframed.pop();
+    }
+  }
+
+  // frame size
+  framed.push_back(static_cast<uint8_t>(unframed.size() >> 16));
+  framed.push_back(static_cast<uint8_t>(unframed.size() >> 8));
+  framed.push_back(static_cast<uint8_t>(unframed.size()));
+  // data frame
+  framed.push_back(0);
+  // no flags
+  framed.push_back(0);
+  // stream id
+  framed.push_back(0);
+  framed.push_back(0);
+  framed.push_back(0);
+  framed.push_back(1);
+  while (!unframed.empty()) {
+    framed.push_back(unframed.front());
+    unframed.pop();
+  }
+
+  return grpc_slice_from_copied_buffer(framed.data(), framed.size());
+}
+
+static void BM_TransportStreamRecv(benchmark::State &state) {
+  TrackCounters track_counters;
+  Fixture f(grpc::ChannelArguments(), true);
+  Stream s(&f);
+  s.Init(state);
+  grpc_transport_stream_op_batch_payload op_payload;
+  grpc_transport_stream_op_batch op;
+  grpc_byte_stream *recv_stream;
+  grpc_slice incoming_data = CreateIncomingDataSlice(state.range(0), 16384);
+
+  auto reset_op = [&]() {
+    memset(&op, 0, sizeof(op));
+    op.payload = &op_payload;
+  };
+
+  grpc_metadata_batch b;
+  grpc_metadata_batch_init(&b);
+  grpc_metadata_batch b_recv;
+  grpc_metadata_batch_init(&b_recv);
+  b.deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
+  std::vector<grpc_mdelem> elems =
+      RepresentativeClientInitialMetadata::GetElems(f.exec_ctx());
+  std::vector<grpc_linked_mdelem> storage(elems.size());
+  for (size_t i = 0; i < elems.size(); i++) {
+    GPR_ASSERT(GRPC_LOG_IF_ERROR(
+        "addmd",
+        grpc_metadata_batch_add_tail(f.exec_ctx(), &b, &storage[i], elems[i])));
+  }
+
+  std::unique_ptr<Closure> do_nothing =
+      MakeClosure([](grpc_exec_ctx *exec_ctx, grpc_error *error) {});
+
+  uint32_t received;
+
+  std::unique_ptr<Closure> drain_start;
+  std::unique_ptr<Closure> drain;
+  std::unique_ptr<Closure> drain_continue;
+  grpc_slice recv_slice;
+
+  std::unique_ptr<Closure> c =
+      MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) {
+        if (!state.KeepRunning()) return;
+        // force outgoing window to be yuge
+        s.chttp2_stream()->incoming_window_delta = 1024 * 1024 * 1024;
+        f.chttp2_transport()->incoming_window = 1024 * 1024 * 1024;
+        received = 0;
+        reset_op();
+        op.on_complete = do_nothing.get();
+        op.recv_message = true;
+        op.payload->recv_message.recv_message = &recv_stream;
+        op.payload->recv_message.recv_message_ready = drain_start.get();
+        s.Op(&op);
+        f.PushInput(grpc_slice_ref(incoming_data));
+      });
+
+  drain_start = MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) {
+    if (recv_stream == NULL) {
+      GPR_ASSERT(!state.KeepRunning());
+      return;
+    }
+    grpc_closure_run(exec_ctx, drain.get(), GRPC_ERROR_NONE);
+  });
+
+  drain = MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) {
+    do {
+      if (received == recv_stream->length) {
+        grpc_byte_stream_destroy(exec_ctx, recv_stream);
+        grpc_closure_sched(exec_ctx, c.get(), GRPC_ERROR_NONE);
+        return;
+      }
+    } while (grpc_byte_stream_next(exec_ctx, recv_stream,
+                                   recv_stream->length - received,
+                                   drain_continue.get()) &&
+             GRPC_ERROR_NONE ==
+                 grpc_byte_stream_pull(exec_ctx, recv_stream, &recv_slice) &&
+             (received += GRPC_SLICE_LENGTH(recv_slice),
+              grpc_slice_unref_internal(exec_ctx, recv_slice), true));
+  });
+
+  drain_continue = MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) {
+    grpc_byte_stream_pull(exec_ctx, recv_stream, &recv_slice);
+    received += GRPC_SLICE_LENGTH(recv_slice);
+    grpc_slice_unref_internal(exec_ctx, recv_slice);
+    grpc_closure_run(exec_ctx, drain.get(), GRPC_ERROR_NONE);
+  });
+
+  reset_op();
+  op.send_initial_metadata = true;
+  op.payload->send_initial_metadata.send_initial_metadata = &b;
+  op.recv_initial_metadata = true;
+  op.payload->recv_initial_metadata.recv_initial_metadata = &b_recv;
+  op.payload->recv_initial_metadata.recv_initial_metadata_ready =
+      do_nothing.get();
+  op.on_complete = c.get();
+  s.Op(&op);
+  f.PushInput(SLICE_FROM_BUFFER(
+      "\x00\x00\x00\x04\x00\x00\x00\x00\x00"
+      // Generated using:
+      // tools/codegen/core/gen_header_frame.py <
+      // test/cpp/microbenchmarks/representative_server_initial_metadata.headers
+      "\x00\x00X\x01\x04\x00\x00\x00\x01"
+      "\x10\x07:status\x03"
+      "200"
+      "\x10\x0c"
+      "content-type\x10"
+      "application/grpc"
+      "\x10\x14grpc-accept-encoding\x15identity,deflate,gzip"));
+
+  f.FlushExecCtx();
+  reset_op();
+  op.cancel_stream = true;
+  op.payload->cancel_stream.cancel_error = GRPC_ERROR_CANCELLED;
+  s.Op(&op);
+  s.DestroyThen(
+      MakeOnceClosure([](grpc_exec_ctx *exec_ctx, grpc_error *error) {}));
+  f.FlushExecCtx();
+  track_counters.Finish(state);
+  grpc_metadata_batch_destroy(f.exec_ctx(), &b);
+  grpc_metadata_batch_destroy(f.exec_ctx(), &b_recv);
+  grpc_slice_unref(incoming_data);
+}
+BENCHMARK(BM_TransportStreamRecv)->Range(0, 128 * 1024 * 1024);
+
+BENCHMARK_MAIN();
diff --git a/test/cpp/microbenchmarks/bm_closure.cc b/test/cpp/microbenchmarks/bm_closure.cc
index 1f54e8c8b17629d1be20e695981ebeab1a06b38f..d52fe4ee309cb34f8c138e114f8fb71516b782ac 100644
--- a/test/cpp/microbenchmarks/bm_closure.cc
+++ b/test/cpp/microbenchmarks/bm_closure.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2017, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,9 @@
 
 /* Test various closure related operations */
 
+#include <benchmark/benchmark.h>
 #include <grpc/grpc.h>
+#include <sstream>
 
 extern "C" {
 #include "src/core/lib/iomgr/closure.h"
@@ -42,86 +44,46 @@ extern "C" {
 #include "src/core/lib/support/spinlock.h"
 }
 
-#include "third_party/benchmark/include/benchmark/benchmark.h"
-
-#include <sstream>
-
-#ifdef GPR_LOW_LEVEL_COUNTERS
-extern "C" gpr_atm gpr_mu_locks;
-#endif
-
-static class InitializeStuff {
- public:
-  InitializeStuff() { grpc_init(); }
-  ~InitializeStuff() { grpc_shutdown(); }
-} initialize_stuff;
-
-class TrackCounters {
- public:
-  TrackCounters(benchmark::State& state) : state_(state) {}
-
-  ~TrackCounters() {
-    std::ostringstream out;
-#ifdef GPR_LOW_LEVEL_COUNTERS
-    out << " locks/iter:" << ((double)(gpr_atm_no_barrier_load(&gpr_mu_locks) -
-                                       mu_locks_at_start_) /
-                              (double)state_.iterations())
-        << " atm_cas/iter:"
-        << ((double)(gpr_atm_no_barrier_load(&gpr_counter_atm_cas) -
-                     atm_cas_at_start_) /
-            (double)state_.iterations())
-        << " atm_add/iter:"
-        << ((double)(gpr_atm_no_barrier_load(&gpr_counter_atm_add) -
-                     atm_add_at_start_) /
-            (double)state_.iterations());
-#endif
-    state_.SetLabel(out.str());
-  }
+#include "test/cpp/microbenchmarks/helpers.h"
 
- private:
-  benchmark::State& state_;
-#ifdef GPR_LOW_LEVEL_COUNTERS
-  const size_t mu_locks_at_start_ = gpr_atm_no_barrier_load(&gpr_mu_locks);
-  const size_t atm_cas_at_start_ =
-      gpr_atm_no_barrier_load(&gpr_counter_atm_cas);
-  const size_t atm_add_at_start_ =
-      gpr_atm_no_barrier_load(&gpr_counter_atm_add);
-#endif
-};
+auto& force_library_initialization = Library::get();
 
 static void BM_NoOpExecCtx(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   while (state.KeepRunning()) {
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     grpc_exec_ctx_finish(&exec_ctx);
   }
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_NoOpExecCtx);
 
 static void BM_WellFlushed(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   while (state.KeepRunning()) {
     grpc_exec_ctx_flush(&exec_ctx);
   }
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_WellFlushed);
 
 static void DoNothing(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {}
 
 static void BM_ClosureInitAgainstExecCtx(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_closure c;
   while (state.KeepRunning()) {
     benchmark::DoNotOptimize(
         grpc_closure_init(&c, DoNothing, NULL, grpc_schedule_on_exec_ctx));
   }
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ClosureInitAgainstExecCtx);
 
 static void BM_ClosureInitAgainstCombiner(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_combiner* combiner = grpc_combiner_create(NULL);
   grpc_closure c;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -131,11 +93,12 @@ static void BM_ClosureInitAgainstCombiner(benchmark::State& state) {
   }
   GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished");
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ClosureInitAgainstCombiner);
 
 static void BM_ClosureRunOnExecCtx(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_closure c;
   grpc_closure_init(&c, DoNothing, NULL, grpc_schedule_on_exec_ctx);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -144,11 +107,12 @@ static void BM_ClosureRunOnExecCtx(benchmark::State& state) {
     grpc_exec_ctx_flush(&exec_ctx);
   }
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ClosureRunOnExecCtx);
 
 static void BM_ClosureCreateAndRun(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   while (state.KeepRunning()) {
     grpc_closure_run(&exec_ctx, grpc_closure_create(DoNothing, NULL,
@@ -156,11 +120,12 @@ static void BM_ClosureCreateAndRun(benchmark::State& state) {
                      GRPC_ERROR_NONE);
   }
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ClosureCreateAndRun);
 
 static void BM_ClosureInitAndRun(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_closure c;
   while (state.KeepRunning()) {
@@ -169,11 +134,12 @@ static void BM_ClosureInitAndRun(benchmark::State& state) {
                      GRPC_ERROR_NONE);
   }
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ClosureInitAndRun);
 
 static void BM_ClosureSchedOnExecCtx(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_closure c;
   grpc_closure_init(&c, DoNothing, NULL, grpc_schedule_on_exec_ctx);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -182,11 +148,12 @@ static void BM_ClosureSchedOnExecCtx(benchmark::State& state) {
     grpc_exec_ctx_flush(&exec_ctx);
   }
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ClosureSchedOnExecCtx);
 
 static void BM_ClosureSched2OnExecCtx(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_closure c1;
   grpc_closure c2;
   grpc_closure_init(&c1, DoNothing, NULL, grpc_schedule_on_exec_ctx);
@@ -198,11 +165,12 @@ static void BM_ClosureSched2OnExecCtx(benchmark::State& state) {
     grpc_exec_ctx_flush(&exec_ctx);
   }
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ClosureSched2OnExecCtx);
 
 static void BM_ClosureSched3OnExecCtx(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_closure c1;
   grpc_closure c2;
   grpc_closure c3;
@@ -217,11 +185,12 @@ static void BM_ClosureSched3OnExecCtx(benchmark::State& state) {
     grpc_exec_ctx_flush(&exec_ctx);
   }
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ClosureSched3OnExecCtx);
 
 static void BM_AcquireMutex(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   // for comparison with the combiner stuff below
   gpr_mu mu;
   gpr_mu_init(&mu);
@@ -232,11 +201,12 @@ static void BM_AcquireMutex(benchmark::State& state) {
     gpr_mu_unlock(&mu);
   }
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_AcquireMutex);
 
 static void BM_TryAcquireMutex(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   // for comparison with the combiner stuff below
   gpr_mu mu;
   gpr_mu_init(&mu);
@@ -250,11 +220,12 @@ static void BM_TryAcquireMutex(benchmark::State& state) {
     }
   }
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_TryAcquireMutex);
 
 static void BM_AcquireSpinlock(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   // for comparison with the combiner stuff below
   gpr_spinlock mu = GPR_SPINLOCK_INITIALIZER;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -264,11 +235,12 @@ static void BM_AcquireSpinlock(benchmark::State& state) {
     gpr_spinlock_unlock(&mu);
   }
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_AcquireSpinlock);
 
 static void BM_TryAcquireSpinlock(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   // for comparison with the combiner stuff below
   gpr_spinlock mu = GPR_SPINLOCK_INITIALIZER;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -281,11 +253,12 @@ static void BM_TryAcquireSpinlock(benchmark::State& state) {
     }
   }
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_TryAcquireSpinlock);
 
 static void BM_ClosureSchedOnCombiner(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_combiner* combiner = grpc_combiner_create(NULL);
   grpc_closure c;
   grpc_closure_init(&c, DoNothing, NULL,
@@ -297,11 +270,12 @@ static void BM_ClosureSchedOnCombiner(benchmark::State& state) {
   }
   GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished");
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ClosureSchedOnCombiner);
 
 static void BM_ClosureSched2OnCombiner(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_combiner* combiner = grpc_combiner_create(NULL);
   grpc_closure c1;
   grpc_closure c2;
@@ -317,11 +291,12 @@ static void BM_ClosureSched2OnCombiner(benchmark::State& state) {
   }
   GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished");
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ClosureSched2OnCombiner);
 
 static void BM_ClosureSched3OnCombiner(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_combiner* combiner = grpc_combiner_create(NULL);
   grpc_closure c1;
   grpc_closure c2;
@@ -341,11 +316,12 @@ static void BM_ClosureSched3OnCombiner(benchmark::State& state) {
   }
   GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished");
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ClosureSched3OnCombiner);
 
 static void BM_ClosureSched2OnTwoCombiners(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_combiner* combiner1 = grpc_combiner_create(NULL);
   grpc_combiner* combiner2 = grpc_combiner_create(NULL);
   grpc_closure c1;
@@ -363,11 +339,12 @@ static void BM_ClosureSched2OnTwoCombiners(benchmark::State& state) {
   GRPC_COMBINER_UNREF(&exec_ctx, combiner1, "finished");
   GRPC_COMBINER_UNREF(&exec_ctx, combiner2, "finished");
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ClosureSched2OnTwoCombiners);
 
 static void BM_ClosureSched4OnTwoCombiners(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_combiner* combiner1 = grpc_combiner_create(NULL);
   grpc_combiner* combiner2 = grpc_combiner_create(NULL);
   grpc_closure c1;
@@ -393,6 +370,7 @@ static void BM_ClosureSched4OnTwoCombiners(benchmark::State& state) {
   GRPC_COMBINER_UNREF(&exec_ctx, combiner1, "finished");
   GRPC_COMBINER_UNREF(&exec_ctx, combiner2, "finished");
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ClosureSched4OnTwoCombiners);
 
@@ -428,16 +406,17 @@ class Rescheduler {
 };
 
 static void BM_ClosureReschedOnExecCtx(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   Rescheduler r(state, grpc_schedule_on_exec_ctx);
   r.ScheduleFirst(&exec_ctx);
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ClosureReschedOnExecCtx);
 
 static void BM_ClosureReschedOnCombiner(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_combiner* combiner = grpc_combiner_create(NULL);
   Rescheduler r(state, grpc_combiner_scheduler(combiner, false));
@@ -445,11 +424,12 @@ static void BM_ClosureReschedOnCombiner(benchmark::State& state) {
   grpc_exec_ctx_flush(&exec_ctx);
   GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished");
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ClosureReschedOnCombiner);
 
 static void BM_ClosureReschedOnCombinerFinally(benchmark::State& state) {
-  TrackCounters track_counters(state);
+  TrackCounters track_counters;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_combiner* combiner = grpc_combiner_create(NULL);
   Rescheduler r(state, grpc_combiner_finally_scheduler(combiner, false));
@@ -458,6 +438,7 @@ static void BM_ClosureReschedOnCombinerFinally(benchmark::State& state) {
   grpc_exec_ctx_flush(&exec_ctx);
   GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished");
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ClosureReschedOnCombinerFinally);
 
diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc
index c017474bf4a97929954f8305c762238778d26ee7..8b26bf977caaa32eafb50e8179ce0e7ec5dcb3a3 100644
--- a/test/cpp/microbenchmarks/bm_cq.cc
+++ b/test/cpp/microbenchmarks/bm_cq.cc
@@ -34,11 +34,11 @@
 /* This benchmark exists to ensure that the benchmark integration is
  * working */
 
+#include <benchmark/benchmark.h>
 #include <grpc++/completion_queue.h>
 #include <grpc++/impl/grpc_library.h>
 #include <grpc/grpc.h>
-
-#include "third_party/benchmark/include/benchmark/benchmark.h"
+#include "test/cpp/microbenchmarks/helpers.h"
 
 extern "C" {
 #include "src/core/lib/surface/completion_queue.h"
@@ -47,27 +47,37 @@ extern "C" {
 namespace grpc {
 namespace testing {
 
-static class InitializeStuff {
- public:
-  InitializeStuff() { init_lib_.init(); }
-  ~InitializeStuff() { init_lib_.shutdown(); }
-
- private:
-  internal::GrpcLibrary init_lib_;
-  internal::GrpcLibraryInitializer init_;
-} initialize_stuff;
+auto& force_library_initialization = Library::get();
 
 static void BM_CreateDestroyCpp(benchmark::State& state) {
+  TrackCounters track_counters;
   while (state.KeepRunning()) {
     CompletionQueue cq;
   }
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_CreateDestroyCpp);
 
+/* Create cq using a different constructor */
+static void BM_CreateDestroyCpp2(benchmark::State& state) {
+  TrackCounters track_counters;
+  while (state.KeepRunning()) {
+    grpc_completion_queue* core_cq =
+        grpc_completion_queue_create_for_next(NULL);
+    CompletionQueue cq(core_cq);
+  }
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_CreateDestroyCpp2);
+
 static void BM_CreateDestroyCore(benchmark::State& state) {
+  TrackCounters track_counters;
   while (state.KeepRunning()) {
-    grpc_completion_queue_destroy(grpc_completion_queue_create(NULL));
+    // TODO: sreek Templatize this benchmark and pass completion type and
+    // polling type as parameters
+    grpc_completion_queue_destroy(grpc_completion_queue_create_for_next(NULL));
   }
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_CreateDestroyCore);
 
@@ -80,6 +90,7 @@ class DummyTag final : public CompletionQueueTag {
 };
 
 static void BM_Pass1Cpp(benchmark::State& state) {
+  TrackCounters track_counters;
   CompletionQueue cq;
   grpc_completion_queue* c_cq = cq.cq();
   while (state.KeepRunning()) {
@@ -94,11 +105,14 @@ static void BM_Pass1Cpp(benchmark::State& state) {
     bool ok;
     cq.Next(&tag, &ok);
   }
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_Pass1Cpp);
 
 static void BM_Pass1Core(benchmark::State& state) {
-  grpc_completion_queue* cq = grpc_completion_queue_create(NULL);
+  TrackCounters track_counters;
+  // TODO: sreek Templatize this benchmark and pass polling_type as a param
+  grpc_completion_queue* cq = grpc_completion_queue_create_for_next(NULL);
   gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
   while (state.KeepRunning()) {
     grpc_cq_completion completion;
@@ -110,11 +124,14 @@ static void BM_Pass1Core(benchmark::State& state) {
     grpc_completion_queue_next(cq, deadline, NULL);
   }
   grpc_completion_queue_destroy(cq);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_Pass1Core);
 
 static void BM_Pluck1Core(benchmark::State& state) {
-  grpc_completion_queue* cq = grpc_completion_queue_create(NULL);
+  TrackCounters track_counters;
+  // TODO: sreek Templatize this benchmark and pass polling_type as a param
+  grpc_completion_queue* cq = grpc_completion_queue_create_for_pluck(NULL);
   gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
   while (state.KeepRunning()) {
     grpc_cq_completion completion;
@@ -126,16 +143,20 @@ static void BM_Pluck1Core(benchmark::State& state) {
     grpc_completion_queue_pluck(cq, NULL, deadline, NULL);
   }
   grpc_completion_queue_destroy(cq);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_Pluck1Core);
 
 static void BM_EmptyCore(benchmark::State& state) {
-  grpc_completion_queue* cq = grpc_completion_queue_create(NULL);
+  TrackCounters track_counters;
+  // TODO: sreek Templatize this benchmark and pass polling_type as a param
+  grpc_completion_queue* cq = grpc_completion_queue_create_for_next(NULL);
   gpr_timespec deadline = gpr_inf_past(GPR_CLOCK_MONOTONIC);
   while (state.KeepRunning()) {
     grpc_completion_queue_next(cq, deadline, NULL);
   }
   grpc_completion_queue_destroy(cq);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_EmptyCore);
 
diff --git a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9d7f65d2923001d923293041e1007d0ddedf91f2
--- /dev/null
+++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
@@ -0,0 +1,160 @@
+/*
+ *
+ * Copyright 2017, 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 <benchmark/benchmark.h>
+#include <string.h>
+#include <atomic>
+
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include "test/cpp/microbenchmarks/helpers.h"
+
+extern "C" {
+#include "src/core/lib/iomgr/ev_posix.h"
+#include "src/core/lib/iomgr/port.h"
+#include "src/core/lib/surface/completion_queue.h"
+}
+
+struct grpc_pollset {
+  gpr_mu mu;
+};
+
+namespace grpc {
+namespace testing {
+
+static void* g_tag = (void*)(intptr_t)10;  // Some random number
+static grpc_completion_queue* g_cq;
+static grpc_event_engine_vtable g_vtable;
+
+static void pollset_shutdown(grpc_exec_ctx* exec_ctx, grpc_pollset* ps,
+                             grpc_closure* closure) {
+  grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE);
+}
+
+static void pollset_init(grpc_pollset* ps, gpr_mu** mu) {
+  gpr_mu_init(&ps->mu);
+  *mu = &ps->mu;
+}
+
+static void pollset_destroy(grpc_pollset* ps) { gpr_mu_destroy(&ps->mu); }
+
+static grpc_error* pollset_kick(grpc_pollset* p, grpc_pollset_worker* worker) {
+  return GRPC_ERROR_NONE;
+}
+
+/* Callback when the tag is dequeued from the completion queue. Does nothing */
+static void cq_done_cb(grpc_exec_ctx* exec_ctx, void* done_arg,
+                       grpc_cq_completion* cq_completion) {
+  gpr_free(cq_completion);
+}
+
+/* Queues a completion tag. ZERO polling overhead */
+static grpc_error* pollset_work(grpc_exec_ctx* exec_ctx, grpc_pollset* ps,
+                                grpc_pollset_worker** worker, gpr_timespec now,
+                                gpr_timespec deadline) {
+  gpr_mu_unlock(&ps->mu);
+  grpc_cq_begin_op(g_cq, g_tag);
+  grpc_cq_end_op(exec_ctx, g_cq, g_tag, GRPC_ERROR_NONE, cq_done_cb, NULL,
+                 (grpc_cq_completion*)gpr_malloc(sizeof(grpc_cq_completion)));
+  grpc_exec_ctx_flush(exec_ctx);
+  gpr_mu_lock(&ps->mu);
+  return GRPC_ERROR_NONE;
+}
+
+static void init_engine_vtable() {
+  memset(&g_vtable, 0, sizeof(g_vtable));
+
+  g_vtable.pollset_size = sizeof(grpc_pollset);
+  g_vtable.pollset_init = pollset_init;
+  g_vtable.pollset_shutdown = pollset_shutdown;
+  g_vtable.pollset_destroy = pollset_destroy;
+  g_vtable.pollset_work = pollset_work;
+  g_vtable.pollset_kick = pollset_kick;
+}
+
+static void setup() {
+  grpc_init();
+  init_engine_vtable();
+  grpc_set_event_engine_test_only(&g_vtable);
+
+  g_cq = grpc_completion_queue_create_for_next(NULL);
+}
+
+static void teardown() {
+  grpc_completion_queue_shutdown(g_cq);
+  grpc_completion_queue_destroy(g_cq);
+}
+
+/* A few notes about Multi-threaded benchmarks:
+
+ Setup:
+  The benchmark framework ensures that none of the threads proceed beyond the
+  state.KeepRunning() call unless all the threads have called state.keepRunning
+  atleast once.  So it is safe to do the initialization in one of the threads
+  before state.KeepRunning() is called.
+
+ Teardown:
+  The benchmark framework also ensures that no thread is running the benchmark
+  code (i.e the code between two successive calls of state.KeepRunning()) if
+  state.KeepRunning() returns false. So it is safe to do the teardown in one
+  of the threads after state.keepRunning() returns false.
+*/
+static void BM_Cq_Throughput(benchmark::State& state) {
+  TrackCounters track_counters;
+  gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
+
+  if (state.thread_index == 0) {
+    setup();
+  }
+
+  while (state.KeepRunning()) {
+    GPR_ASSERT(grpc_completion_queue_next(g_cq, deadline, NULL).type ==
+               GRPC_OP_COMPLETE);
+  }
+
+  state.SetItemsProcessed(state.iterations());
+
+  if (state.thread_index == 0) {
+    teardown();
+  }
+
+  track_counters.Finish(state);
+}
+
+BENCHMARK(BM_Cq_Throughput)->ThreadRange(1, 16)->UseRealTime();
+
+}  // namespace testing
+}  // namespace grpc
+
+BENCHMARK_MAIN();
diff --git a/test/cpp/microbenchmarks/bm_error.cc b/test/cpp/microbenchmarks/bm_error.cc
index 8a4b86f281a1643d338e3b7c94e9d5f6dbf15a89..ea9777bbe6cf6295fd2421b92c0579e2dbf2bbd0 100644
--- a/test/cpp/microbenchmarks/bm_error.cc
+++ b/test/cpp/microbenchmarks/bm_error.cc
@@ -33,6 +33,7 @@
 
 /* Test various operations on grpc_error */
 
+#include <benchmark/benchmark.h>
 #include <memory>
 
 extern "C" {
@@ -40,7 +41,9 @@ extern "C" {
 #include "src/core/lib/transport/error_utils.h"
 }
 
-#include "third_party/benchmark/include/benchmark/benchmark.h"
+#include "test/cpp/microbenchmarks/helpers.h"
+
+auto& force_library_initialization = Library::get();
 
 class ErrorDeleter {
  public:
@@ -48,32 +51,86 @@ class ErrorDeleter {
 };
 typedef std::unique_ptr<grpc_error, ErrorDeleter> ErrorPtr;
 
-static void BM_ErrorCreate(benchmark::State& state) {
+static void BM_ErrorCreateFromStatic(benchmark::State& state) {
+  TrackCounters track_counters;
+  while (state.KeepRunning()) {
+    GRPC_ERROR_UNREF(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"));
+  }
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_ErrorCreateFromStatic);
+
+static void BM_ErrorCreateFromCopied(benchmark::State& state) {
+  TrackCounters track_counters;
   while (state.KeepRunning()) {
-    GRPC_ERROR_UNREF(GRPC_ERROR_CREATE("Error"));
+    GRPC_ERROR_UNREF(GRPC_ERROR_CREATE_FROM_COPIED_STRING("Error not inline"));
   }
+  track_counters.Finish(state);
 }
-BENCHMARK(BM_ErrorCreate);
+BENCHMARK(BM_ErrorCreateFromCopied);
 
 static void BM_ErrorCreateAndSetStatus(benchmark::State& state) {
+  TrackCounters track_counters;
   while (state.KeepRunning()) {
-    GRPC_ERROR_UNREF(grpc_error_set_int(GRPC_ERROR_CREATE("Error"),
-                                        GRPC_ERROR_INT_GRPC_STATUS,
-                                        GRPC_STATUS_ABORTED));
+    GRPC_ERROR_UNREF(
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"),
+                           GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_ABORTED));
   }
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ErrorCreateAndSetStatus);
 
+static void BM_ErrorCreateAndSetIntAndStr(benchmark::State& state) {
+  TrackCounters track_counters;
+  while (state.KeepRunning()) {
+    GRPC_ERROR_UNREF(grpc_error_set_str(
+        grpc_error_set_int(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("GOAWAY received"),
+            GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)0),
+        GRPC_ERROR_STR_RAW_BYTES, grpc_slice_from_static_string("raw bytes")));
+  }
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_ErrorCreateAndSetIntAndStr);
+
+static void BM_ErrorCreateAndSetIntLoop(benchmark::State& state) {
+  TrackCounters track_counters;
+  grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error");
+  int n = 0;
+  while (state.KeepRunning()) {
+    error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, n++);
+  }
+  GRPC_ERROR_UNREF(error);
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_ErrorCreateAndSetIntLoop);
+
+static void BM_ErrorCreateAndSetStrLoop(benchmark::State& state) {
+  TrackCounters track_counters;
+  grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error");
+  const char* str = "hello";
+  while (state.KeepRunning()) {
+    error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE,
+                               grpc_slice_from_static_string(str));
+  }
+  GRPC_ERROR_UNREF(error);
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_ErrorCreateAndSetStrLoop);
+
 static void BM_ErrorRefUnref(benchmark::State& state) {
-  grpc_error* error = GRPC_ERROR_CREATE("Error");
+  TrackCounters track_counters;
+  grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error");
   while (state.KeepRunning()) {
     GRPC_ERROR_UNREF(GRPC_ERROR_REF(error));
   }
   GRPC_ERROR_UNREF(error);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ErrorRefUnref);
 
 static void BM_ErrorUnrefNone(benchmark::State& state) {
+  TrackCounters track_counters;
   while (state.KeepRunning()) {
     GRPC_ERROR_UNREF(GRPC_ERROR_NONE);
   }
@@ -81,30 +138,36 @@ static void BM_ErrorUnrefNone(benchmark::State& state) {
 BENCHMARK(BM_ErrorUnrefNone);
 
 static void BM_ErrorGetIntFromNoError(benchmark::State& state) {
+  TrackCounters track_counters;
   while (state.KeepRunning()) {
     intptr_t value;
     grpc_error_get_int(GRPC_ERROR_NONE, GRPC_ERROR_INT_GRPC_STATUS, &value);
   }
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ErrorGetIntFromNoError);
 
 static void BM_ErrorGetMissingInt(benchmark::State& state) {
-  ErrorPtr error(
-      grpc_error_set_int(GRPC_ERROR_CREATE("Error"), GRPC_ERROR_INT_INDEX, 1));
+  TrackCounters track_counters;
+  ErrorPtr error(grpc_error_set_int(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_INDEX, 1));
   while (state.KeepRunning()) {
     intptr_t value;
     grpc_error_get_int(error.get(), GRPC_ERROR_INT_OFFSET, &value);
   }
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ErrorGetMissingInt);
 
 static void BM_ErrorGetPresentInt(benchmark::State& state) {
-  ErrorPtr error(
-      grpc_error_set_int(GRPC_ERROR_CREATE("Error"), GRPC_ERROR_INT_OFFSET, 1));
+  TrackCounters track_counters;
+  ErrorPtr error(grpc_error_set_int(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_OFFSET, 1));
   while (state.KeepRunning()) {
     intptr_t value;
     grpc_error_get_int(error.get(), GRPC_ERROR_INT_OFFSET, &value);
   }
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_ErrorGetPresentInt);
 
@@ -134,7 +197,7 @@ class SimpleError {
 
  private:
   const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC);
-  ErrorPtr error_{GRPC_ERROR_CREATE("Error")};
+  ErrorPtr error_{GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error")};
 };
 
 class ErrorWithGrpcStatus {
@@ -144,9 +207,9 @@ class ErrorWithGrpcStatus {
 
  private:
   const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC);
-  ErrorPtr error_{grpc_error_set_int(GRPC_ERROR_CREATE("Error"),
-                                     GRPC_ERROR_INT_GRPC_STATUS,
-                                     GRPC_STATUS_UNIMPLEMENTED)};
+  ErrorPtr error_{grpc_error_set_int(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_GRPC_STATUS,
+      GRPC_STATUS_UNIMPLEMENTED)};
 };
 
 class ErrorWithHttpError {
@@ -156,9 +219,9 @@ class ErrorWithHttpError {
 
  private:
   const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC);
-  ErrorPtr error_{grpc_error_set_int(GRPC_ERROR_CREATE("Error"),
-                                     GRPC_ERROR_INT_HTTP2_ERROR,
-                                     GRPC_HTTP2_COMPRESSION_ERROR)};
+  ErrorPtr error_{grpc_error_set_int(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_HTTP2_ERROR,
+      GRPC_HTTP2_COMPRESSION_ERROR)};
 };
 
 class ErrorWithNestedGrpcStatus {
@@ -168,66 +231,79 @@ class ErrorWithNestedGrpcStatus {
 
  private:
   const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC);
-  ErrorPtr nested_error_{grpc_error_set_int(GRPC_ERROR_CREATE("Error"),
-                                            GRPC_ERROR_INT_GRPC_STATUS,
-                                            GRPC_STATUS_UNIMPLEMENTED)};
+  ErrorPtr nested_error_{grpc_error_set_int(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_GRPC_STATUS,
+      GRPC_STATUS_UNIMPLEMENTED)};
   grpc_error* nested_errors_[1] = {nested_error_.get()};
-  ErrorPtr error_{GRPC_ERROR_CREATE_REFERENCING("Error", nested_errors_, 1)};
+  ErrorPtr error_{GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+      "Error", nested_errors_, 1)};
 };
 
 template <class Fixture>
 static void BM_ErrorStringOnNewError(benchmark::State& state) {
+  TrackCounters track_counters;
   while (state.KeepRunning()) {
     Fixture fixture;
     grpc_error_string(fixture.error());
   }
+  track_counters.Finish(state);
 }
 
 template <class Fixture>
 static void BM_ErrorStringRepeatedly(benchmark::State& state) {
+  TrackCounters track_counters;
   Fixture fixture;
   while (state.KeepRunning()) {
     grpc_error_string(fixture.error());
   }
+  track_counters.Finish(state);
 }
 
 template <class Fixture>
 static void BM_ErrorGetStatus(benchmark::State& state) {
+  TrackCounters track_counters;
   Fixture fixture;
   while (state.KeepRunning()) {
     grpc_status_code status;
-    const char* msg;
-    grpc_error_get_status(fixture.error(), fixture.deadline(), &status, &msg,
+    grpc_slice slice;
+    grpc_error_get_status(fixture.error(), fixture.deadline(), &status, &slice,
                           NULL);
   }
+  track_counters.Finish(state);
 }
 
 template <class Fixture>
 static void BM_ErrorGetStatusCode(benchmark::State& state) {
+  TrackCounters track_counters;
   Fixture fixture;
   while (state.KeepRunning()) {
     grpc_status_code status;
     grpc_error_get_status(fixture.error(), fixture.deadline(), &status, NULL,
                           NULL);
   }
+  track_counters.Finish(state);
 }
 
 template <class Fixture>
 static void BM_ErrorHttpError(benchmark::State& state) {
+  TrackCounters track_counters;
   Fixture fixture;
   while (state.KeepRunning()) {
     grpc_http2_error_code error;
     grpc_error_get_status(fixture.error(), fixture.deadline(), NULL, NULL,
                           &error);
   }
+  track_counters.Finish(state);
 }
 
 template <class Fixture>
 static void BM_HasClearGrpcStatus(benchmark::State& state) {
+  TrackCounters track_counters;
   Fixture fixture;
   while (state.KeepRunning()) {
     grpc_error_has_clear_grpc_status(fixture.error());
   }
+  track_counters.Finish(state);
 }
 
 #define BENCHMARK_SUITE(fixture)                         \
diff --git a/test/cpp/microbenchmarks/bm_fullstack.cc b/test/cpp/microbenchmarks/bm_fullstack.cc
deleted file mode 100644
index 48e131f1be086340091dddcfba2d757447ed4a5f..0000000000000000000000000000000000000000
--- a/test/cpp/microbenchmarks/bm_fullstack.cc
+++ /dev/null
@@ -1,1079 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-/* Benchmark gRPC end2end in various configurations */
-
-#include <sstream>
-
-#include <grpc++/channel.h>
-#include <grpc++/create_channel.h>
-#include <grpc++/impl/grpc_library.h>
-#include <grpc++/security/credentials.h>
-#include <grpc++/security/server_credentials.h>
-#include <grpc++/server.h>
-#include <grpc++/server_builder.h>
-#include <grpc/support/log.h>
-
-extern "C" {
-#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
-#include "src/core/ext/transport/chttp2/transport/internal.h"
-#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/iomgr/endpoint.h"
-#include "src/core/lib/iomgr/endpoint_pair.h"
-#include "src/core/lib/iomgr/exec_ctx.h"
-#include "src/core/lib/iomgr/tcp_posix.h"
-#include "src/core/lib/surface/channel.h"
-#include "src/core/lib/surface/completion_queue.h"
-#include "src/core/lib/surface/server.h"
-#include "test/core/util/memory_counters.h"
-#include "test/core/util/passthru_endpoint.h"
-#include "test/core/util/port.h"
-#include "test/core/util/trickle_endpoint.h"
-}
-#include "src/core/lib/profiling/timers.h"
-#include "src/cpp/client/create_channel_internal.h"
-#include "src/proto/grpc/testing/echo.grpc.pb.h"
-#include "third_party/benchmark/include/benchmark/benchmark.h"
-
-namespace grpc {
-namespace testing {
-
-static class InitializeStuff {
- public:
-  InitializeStuff() {
-    grpc_memory_counters_init();
-    init_lib_.init();
-    rq_ = grpc_resource_quota_create("bm");
-  }
-
-  ~InitializeStuff() { init_lib_.shutdown(); }
-
-  grpc_resource_quota* rq() { return rq_; }
-
- private:
-  internal::GrpcLibrary init_lib_;
-  grpc_resource_quota* rq_;
-} initialize_stuff;
-
-/*******************************************************************************
- * FIXTURES
- */
-
-static void ApplyCommonServerBuilderConfig(ServerBuilder* b) {
-  b->SetMaxReceiveMessageSize(INT_MAX);
-  b->SetMaxSendMessageSize(INT_MAX);
-}
-
-static void ApplyCommonChannelArguments(ChannelArguments* c) {
-  c->SetInt(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, INT_MAX);
-  c->SetInt(GRPC_ARG_MAX_SEND_MESSAGE_LENGTH, INT_MAX);
-}
-
-#ifdef GPR_LOW_LEVEL_COUNTERS
-extern "C" gpr_atm gpr_mu_locks;
-extern "C" gpr_atm gpr_counter_atm_cas;
-extern "C" gpr_atm gpr_counter_atm_add;
-#endif
-
-class BaseFixture {
- public:
-  void Finish(benchmark::State& s) {
-    std::ostringstream out;
-    this->AddToLabel(out, s);
-#ifdef GPR_LOW_LEVEL_COUNTERS
-    out << " locks/iter:" << ((double)(gpr_atm_no_barrier_load(&gpr_mu_locks) -
-                                       mu_locks_at_start_) /
-                              (double)s.iterations())
-        << " atm_cas/iter:"
-        << ((double)(gpr_atm_no_barrier_load(&gpr_counter_atm_cas) -
-                     atm_cas_at_start_) /
-            (double)s.iterations())
-        << " atm_add/iter:"
-        << ((double)(gpr_atm_no_barrier_load(&gpr_counter_atm_add) -
-                     atm_add_at_start_) /
-            (double)s.iterations());
-#endif
-    grpc_memory_counters counters_at_end = grpc_memory_counters_snapshot();
-    out << " allocs/iter:"
-        << ((double)(counters_at_end.total_allocs_absolute -
-                     counters_at_start_.total_allocs_absolute) /
-            (double)s.iterations());
-    auto label = out.str();
-    if (label.length() && label[0] == ' ') {
-      label = label.substr(1);
-    }
-    s.SetLabel(label);
-  }
-
-  virtual void AddToLabel(std::ostream& out, benchmark::State& s) = 0;
-
- private:
-#ifdef GPR_LOW_LEVEL_COUNTERS
-  const size_t mu_locks_at_start_ = gpr_atm_no_barrier_load(&gpr_mu_locks);
-  const size_t atm_cas_at_start_ =
-      gpr_atm_no_barrier_load(&gpr_counter_atm_cas);
-  const size_t atm_add_at_start_ =
-      gpr_atm_no_barrier_load(&gpr_counter_atm_add);
-#endif
-  grpc_memory_counters counters_at_start_ = grpc_memory_counters_snapshot();
-};
-
-class FullstackFixture : public BaseFixture {
- public:
-  FullstackFixture(Service* service, const grpc::string& address) {
-    ServerBuilder b;
-    b.AddListeningPort(address, InsecureServerCredentials());
-    cq_ = b.AddCompletionQueue(true);
-    b.RegisterService(service);
-    ApplyCommonServerBuilderConfig(&b);
-    server_ = b.BuildAndStart();
-    ChannelArguments args;
-    ApplyCommonChannelArguments(&args);
-    channel_ = CreateCustomChannel(address, InsecureChannelCredentials(), args);
-  }
-
-  virtual ~FullstackFixture() {
-    server_->Shutdown();
-    cq_->Shutdown();
-    void* tag;
-    bool ok;
-    while (cq_->Next(&tag, &ok)) {
-    }
-  }
-
-  ServerCompletionQueue* cq() { return cq_.get(); }
-  std::shared_ptr<Channel> channel() { return channel_; }
-
- private:
-  std::unique_ptr<Server> server_;
-  std::unique_ptr<ServerCompletionQueue> cq_;
-  std::shared_ptr<Channel> channel_;
-};
-
-class TCP : public FullstackFixture {
- public:
-  TCP(Service* service) : FullstackFixture(service, MakeAddress()) {}
-
-  void AddToLabel(std::ostream& out, benchmark::State& state) {}
-
- private:
-  static grpc::string MakeAddress() {
-    int port = grpc_pick_unused_port_or_die();
-    std::stringstream addr;
-    addr << "localhost:" << port;
-    return addr.str();
-  }
-};
-
-class UDS : public FullstackFixture {
- public:
-  UDS(Service* service) : FullstackFixture(service, MakeAddress()) {}
-
-  void AddToLabel(std::ostream& out, benchmark::State& state) override {}
-
- private:
-  static grpc::string MakeAddress() {
-    int port = grpc_pick_unused_port_or_die();  // just for a unique id - not a
-                                                // real port
-    std::stringstream addr;
-    addr << "unix:/tmp/bm_fullstack." << port;
-    return addr.str();
-  }
-};
-
-class EndpointPairFixture : public BaseFixture {
- public:
-  EndpointPairFixture(Service* service, grpc_endpoint_pair endpoints)
-      : endpoint_pair_(endpoints) {
-    ServerBuilder b;
-    cq_ = b.AddCompletionQueue(true);
-    b.RegisterService(service);
-    ApplyCommonServerBuilderConfig(&b);
-    server_ = b.BuildAndStart();
-
-    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-
-    /* add server endpoint to server_ */
-    {
-      const grpc_channel_args* server_args =
-          grpc_server_get_channel_args(server_->c_server());
-      server_transport_ = grpc_create_chttp2_transport(
-          &exec_ctx, server_args, endpoints.server, 0 /* is_client */);
-
-      grpc_pollset** pollsets;
-      size_t num_pollsets = 0;
-      grpc_server_get_pollsets(server_->c_server(), &pollsets, &num_pollsets);
-
-      for (size_t i = 0; i < num_pollsets; i++) {
-        grpc_endpoint_add_to_pollset(&exec_ctx, endpoints.server, pollsets[i]);
-      }
-
-      grpc_server_setup_transport(&exec_ctx, server_->c_server(),
-                                  server_transport_, NULL, server_args);
-      grpc_chttp2_transport_start_reading(&exec_ctx, server_transport_, NULL);
-    }
-
-    /* create channel */
-    {
-      ChannelArguments args;
-      args.SetString(GRPC_ARG_DEFAULT_AUTHORITY, "test.authority");
-      ApplyCommonChannelArguments(&args);
-
-      grpc_channel_args c_args = args.c_channel_args();
-      client_transport_ =
-          grpc_create_chttp2_transport(&exec_ctx, &c_args, endpoints.client, 1);
-      GPR_ASSERT(client_transport_);
-      grpc_channel* channel =
-          grpc_channel_create(&exec_ctx, "target", &c_args,
-                              GRPC_CLIENT_DIRECT_CHANNEL, client_transport_);
-      grpc_chttp2_transport_start_reading(&exec_ctx, client_transport_, NULL);
-
-      channel_ = CreateChannelInternal("", channel);
-    }
-
-    grpc_exec_ctx_finish(&exec_ctx);
-  }
-
-  virtual ~EndpointPairFixture() {
-    server_->Shutdown();
-    cq_->Shutdown();
-    void* tag;
-    bool ok;
-    while (cq_->Next(&tag, &ok)) {
-    }
-  }
-
-  ServerCompletionQueue* cq() { return cq_.get(); }
-  std::shared_ptr<Channel> channel() { return channel_; }
-
- protected:
-  grpc_endpoint_pair endpoint_pair_;
-  grpc_transport* client_transport_;
-  grpc_transport* server_transport_;
-
- private:
-  std::unique_ptr<Server> server_;
-  std::unique_ptr<ServerCompletionQueue> cq_;
-  std::shared_ptr<Channel> channel_;
-};
-
-class SockPair : public EndpointPairFixture {
- public:
-  SockPair(Service* service)
-      : EndpointPairFixture(service, grpc_iomgr_create_endpoint_pair(
-                                         "test", initialize_stuff.rq(), 8192)) {
-  }
-
-  void AddToLabel(std::ostream& out, benchmark::State& state) {}
-};
-
-class InProcessCHTTP2 : public EndpointPairFixture {
- public:
-  InProcessCHTTP2(Service* service)
-      : EndpointPairFixture(service, MakeEndpoints()) {}
-
-  void AddToLabel(std::ostream& out, benchmark::State& state) {
-    out << " writes/iter:"
-        << ((double)stats_.num_writes / (double)state.iterations());
-  }
-
- private:
-  grpc_passthru_endpoint_stats stats_;
-
-  grpc_endpoint_pair MakeEndpoints() {
-    grpc_endpoint_pair p;
-    grpc_passthru_endpoint_create(&p.client, &p.server, initialize_stuff.rq(),
-                                  &stats_);
-    return p;
-  }
-};
-
-class TrickledCHTTP2 : public EndpointPairFixture {
- public:
-  TrickledCHTTP2(Service* service, size_t megabits_per_second)
-      : EndpointPairFixture(service, MakeEndpoints(megabits_per_second)) {}
-
-  void AddToLabel(std::ostream& out, benchmark::State& state) {
-    out << " writes/iter:"
-        << ((double)stats_.num_writes / (double)state.iterations())
-        << " cli_transport_stalls/iter:"
-        << ((double)
-                client_stats_.streams_stalled_due_to_transport_flow_control /
-            (double)state.iterations())
-        << " cli_stream_stalls/iter:"
-        << ((double)client_stats_.streams_stalled_due_to_stream_flow_control /
-            (double)state.iterations())
-        << " svr_transport_stalls/iter:"
-        << ((double)
-                server_stats_.streams_stalled_due_to_transport_flow_control /
-            (double)state.iterations())
-        << " svr_stream_stalls/iter:"
-        << ((double)server_stats_.streams_stalled_due_to_stream_flow_control /
-            (double)state.iterations());
-  }
-
-  void Step() {
-    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-    size_t client_backlog =
-        grpc_trickle_endpoint_trickle(&exec_ctx, endpoint_pair_.client);
-    size_t server_backlog =
-        grpc_trickle_endpoint_trickle(&exec_ctx, endpoint_pair_.server);
-    grpc_exec_ctx_finish(&exec_ctx);
-
-    UpdateStats((grpc_chttp2_transport*)client_transport_, &client_stats_,
-                client_backlog);
-    UpdateStats((grpc_chttp2_transport*)server_transport_, &server_stats_,
-                server_backlog);
-  }
-
- private:
-  grpc_passthru_endpoint_stats stats_;
-  struct Stats {
-    int streams_stalled_due_to_stream_flow_control = 0;
-    int streams_stalled_due_to_transport_flow_control = 0;
-  };
-  Stats client_stats_;
-  Stats server_stats_;
-
-  grpc_endpoint_pair MakeEndpoints(size_t kilobits) {
-    grpc_endpoint_pair p;
-    grpc_passthru_endpoint_create(&p.client, &p.server, initialize_stuff.rq(),
-                                  &stats_);
-    double bytes_per_second = 125.0 * kilobits;
-    p.client = grpc_trickle_endpoint_create(p.client, bytes_per_second);
-    p.server = grpc_trickle_endpoint_create(p.server, bytes_per_second);
-    return p;
-  }
-
-  void UpdateStats(grpc_chttp2_transport* t, Stats* s, size_t backlog) {
-    if (backlog == 0) {
-      if (t->lists[GRPC_CHTTP2_LIST_STALLED_BY_STREAM].head != NULL) {
-        s->streams_stalled_due_to_stream_flow_control++;
-      }
-      if (t->lists[GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT].head != NULL) {
-        s->streams_stalled_due_to_transport_flow_control++;
-      }
-    }
-  }
-};
-
-/*******************************************************************************
- * CONTEXT MUTATORS
- */
-
-static const int kPregenerateKeyCount = 100000;
-
-template <class F>
-auto MakeVector(size_t length, F f) -> std::vector<decltype(f())> {
-  std::vector<decltype(f())> out;
-  out.reserve(length);
-  for (size_t i = 0; i < length; i++) {
-    out.push_back(f());
-  }
-  return out;
-}
-
-class NoOpMutator {
- public:
-  template <class ContextType>
-  NoOpMutator(ContextType* context) {}
-};
-
-template <int length>
-class RandomBinaryMetadata {
- public:
-  static const grpc::string& Key() { return kKey; }
-
-  static const grpc::string& Value() {
-    return kValues[rand() % kValues.size()];
-  }
-
- private:
-  static const grpc::string kKey;
-  static const std::vector<grpc::string> kValues;
-
-  static grpc::string GenerateOneString() {
-    grpc::string s;
-    s.reserve(length + 1);
-    for (int i = 0; i < length; i++) {
-      s += (char)rand();
-    }
-    return s;
-  }
-};
-
-template <int length>
-const grpc::string RandomBinaryMetadata<length>::kKey = "foo-bin";
-
-template <int length>
-const std::vector<grpc::string> RandomBinaryMetadata<length>::kValues =
-    MakeVector(kPregenerateKeyCount, GenerateOneString);
-
-template <int length>
-class RandomAsciiMetadata {
- public:
-  static const grpc::string& Key() { return kKey; }
-
-  static const grpc::string& Value() {
-    return kValues[rand() % kValues.size()];
-  }
-
- private:
-  static const grpc::string kKey;
-  static const std::vector<grpc::string> kValues;
-
-  static grpc::string GenerateOneString() {
-    grpc::string s;
-    s.reserve(length + 1);
-    for (int i = 0; i < length; i++) {
-      s += (char)(rand() % 26 + 'a');
-    }
-    return s;
-  }
-};
-
-template <int length>
-const grpc::string RandomAsciiMetadata<length>::kKey = "foo";
-
-template <int length>
-const std::vector<grpc::string> RandomAsciiMetadata<length>::kValues =
-    MakeVector(kPregenerateKeyCount, GenerateOneString);
-
-template <class Generator, int kNumKeys>
-class Client_AddMetadata : public NoOpMutator {
- public:
-  Client_AddMetadata(ClientContext* context) : NoOpMutator(context) {
-    for (int i = 0; i < kNumKeys; i++) {
-      context->AddMetadata(Generator::Key(), Generator::Value());
-    }
-  }
-};
-
-template <class Generator, int kNumKeys>
-class Server_AddInitialMetadata : public NoOpMutator {
- public:
-  Server_AddInitialMetadata(ServerContext* context) : NoOpMutator(context) {
-    for (int i = 0; i < kNumKeys; i++) {
-      context->AddInitialMetadata(Generator::Key(), Generator::Value());
-    }
-  }
-};
-
-/*******************************************************************************
- * BENCHMARKING KERNELS
- */
-
-static void* tag(intptr_t x) { return reinterpret_cast<void*>(x); }
-
-template <class Fixture, class ClientContextMutator, class ServerContextMutator>
-static void BM_UnaryPingPong(benchmark::State& state) {
-  EchoTestService::AsyncService service;
-  std::unique_ptr<Fixture> fixture(new Fixture(&service));
-  EchoRequest send_request;
-  EchoResponse send_response;
-  EchoResponse recv_response;
-  if (state.range(0) > 0) {
-    send_request.set_message(std::string(state.range(0), 'a'));
-  }
-  if (state.range(1) > 0) {
-    send_response.set_message(std::string(state.range(1), 'a'));
-  }
-  Status recv_status;
-  struct ServerEnv {
-    ServerContext ctx;
-    EchoRequest recv_request;
-    grpc::ServerAsyncResponseWriter<EchoResponse> response_writer;
-    ServerEnv() : response_writer(&ctx) {}
-  };
-  uint8_t server_env_buffer[2 * sizeof(ServerEnv)];
-  ServerEnv* server_env[2] = {
-      reinterpret_cast<ServerEnv*>(server_env_buffer),
-      reinterpret_cast<ServerEnv*>(server_env_buffer + sizeof(ServerEnv))};
-  new (server_env[0]) ServerEnv;
-  new (server_env[1]) ServerEnv;
-  service.RequestEcho(&server_env[0]->ctx, &server_env[0]->recv_request,
-                      &server_env[0]->response_writer, fixture->cq(),
-                      fixture->cq(), tag(0));
-  service.RequestEcho(&server_env[1]->ctx, &server_env[1]->recv_request,
-                      &server_env[1]->response_writer, fixture->cq(),
-                      fixture->cq(), tag(1));
-  std::unique_ptr<EchoTestService::Stub> stub(
-      EchoTestService::NewStub(fixture->channel()));
-  while (state.KeepRunning()) {
-    GPR_TIMER_SCOPE("BenchmarkCycle", 0);
-    recv_response.Clear();
-    ClientContext cli_ctx;
-    ClientContextMutator cli_ctx_mut(&cli_ctx);
-    std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
-        stub->AsyncEcho(&cli_ctx, send_request, fixture->cq()));
-    void* t;
-    bool ok;
-    GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-    GPR_ASSERT(ok);
-    GPR_ASSERT(t == tag(0) || t == tag(1));
-    intptr_t slot = reinterpret_cast<intptr_t>(t);
-    ServerEnv* senv = server_env[slot];
-    ServerContextMutator svr_ctx_mut(&senv->ctx);
-    senv->response_writer.Finish(send_response, Status::OK, tag(3));
-    response_reader->Finish(&recv_response, &recv_status, tag(4));
-    for (int i = (1 << 3) | (1 << 4); i != 0;) {
-      GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-      GPR_ASSERT(ok);
-      int tagnum = (int)reinterpret_cast<intptr_t>(t);
-      GPR_ASSERT(i & (1 << tagnum));
-      i -= 1 << tagnum;
-    }
-    GPR_ASSERT(recv_status.ok());
-
-    senv->~ServerEnv();
-    senv = new (senv) ServerEnv();
-    service.RequestEcho(&senv->ctx, &senv->recv_request, &senv->response_writer,
-                        fixture->cq(), fixture->cq(), tag(slot));
-  }
-  fixture->Finish(state);
-  fixture.reset();
-  server_env[0]->~ServerEnv();
-  server_env[1]->~ServerEnv();
-  state.SetBytesProcessed(state.range(0) * state.iterations() +
-                          state.range(1) * state.iterations());
-}
-
-// Repeatedly makes Streaming Bidi calls (exchanging a configurable number of
-// messages in each call) in a loop on a single channel
-//
-//  First parmeter (i.e state.range(0)):  Message size (in bytes) to use
-//  Second parameter (i.e state.range(1)): Number of ping pong messages.
-//      Note: One ping-pong means two messages (one from client to server and
-//      the other from server to client):
-template <class Fixture, class ClientContextMutator, class ServerContextMutator>
-static void BM_StreamingPingPong(benchmark::State& state) {
-  const int msg_size = state.range(0);
-  const int max_ping_pongs = state.range(1);
-
-  EchoTestService::AsyncService service;
-  std::unique_ptr<Fixture> fixture(new Fixture(&service));
-  {
-    EchoResponse send_response;
-    EchoResponse recv_response;
-    EchoRequest send_request;
-    EchoRequest recv_request;
-
-    if (msg_size > 0) {
-      send_request.set_message(std::string(msg_size, 'a'));
-      send_response.set_message(std::string(msg_size, 'b'));
-    }
-
-    std::unique_ptr<EchoTestService::Stub> stub(
-        EchoTestService::NewStub(fixture->channel()));
-
-    while (state.KeepRunning()) {
-      ServerContext svr_ctx;
-      ServerContextMutator svr_ctx_mut(&svr_ctx);
-      ServerAsyncReaderWriter<EchoResponse, EchoRequest> response_rw(&svr_ctx);
-      service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(),
-                                fixture->cq(), tag(0));
-
-      ClientContext cli_ctx;
-      ClientContextMutator cli_ctx_mut(&cli_ctx);
-      auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1));
-
-      // Establish async stream between client side and server side
-      void* t;
-      bool ok;
-      int need_tags = (1 << 0) | (1 << 1);
-      while (need_tags) {
-        GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-        GPR_ASSERT(ok);
-        int i = (int)(intptr_t)t;
-        GPR_ASSERT(need_tags & (1 << i));
-        need_tags &= ~(1 << i);
-      }
-
-      // Send 'max_ping_pongs' number of ping pong messages
-      int ping_pong_cnt = 0;
-      while (ping_pong_cnt < max_ping_pongs) {
-        request_rw->Write(send_request, tag(0));   // Start client send
-        response_rw.Read(&recv_request, tag(1));   // Start server recv
-        request_rw->Read(&recv_response, tag(2));  // Start client recv
-
-        need_tags = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3);
-        while (need_tags) {
-          GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-          GPR_ASSERT(ok);
-          int i = (int)(intptr_t)t;
-
-          // If server recv is complete, start the server send operation
-          if (i == 1) {
-            response_rw.Write(send_response, tag(3));
-          }
-
-          GPR_ASSERT(need_tags & (1 << i));
-          need_tags &= ~(1 << i);
-        }
-
-        ping_pong_cnt++;
-      }
-
-      request_rw->WritesDone(tag(0));
-      response_rw.Finish(Status::OK, tag(1));
-
-      Status recv_status;
-      request_rw->Finish(&recv_status, tag(2));
-
-      need_tags = (1 << 0) | (1 << 1) | (1 << 2);
-      while (need_tags) {
-        GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-        int i = (int)(intptr_t)t;
-        GPR_ASSERT(need_tags & (1 << i));
-        need_tags &= ~(1 << i);
-      }
-
-      GPR_ASSERT(recv_status.ok());
-    }
-  }
-
-  fixture->Finish(state);
-  fixture.reset();
-  state.SetBytesProcessed(msg_size * state.iterations() * max_ping_pongs * 2);
-}
-
-// Repeatedly sends ping pong messages in a single streaming Bidi call in a loop
-//     First parmeter (i.e state.range(0)):  Message size (in bytes) to use
-template <class Fixture, class ClientContextMutator, class ServerContextMutator>
-static void BM_StreamingPingPongMsgs(benchmark::State& state) {
-  const int msg_size = state.range(0);
-
-  EchoTestService::AsyncService service;
-  std::unique_ptr<Fixture> fixture(new Fixture(&service));
-  {
-    EchoResponse send_response;
-    EchoResponse recv_response;
-    EchoRequest send_request;
-    EchoRequest recv_request;
-
-    if (msg_size > 0) {
-      send_request.set_message(std::string(msg_size, 'a'));
-      send_response.set_message(std::string(msg_size, 'b'));
-    }
-
-    std::unique_ptr<EchoTestService::Stub> stub(
-        EchoTestService::NewStub(fixture->channel()));
-
-    ServerContext svr_ctx;
-    ServerContextMutator svr_ctx_mut(&svr_ctx);
-    ServerAsyncReaderWriter<EchoResponse, EchoRequest> response_rw(&svr_ctx);
-    service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(),
-                              fixture->cq(), tag(0));
-
-    ClientContext cli_ctx;
-    ClientContextMutator cli_ctx_mut(&cli_ctx);
-    auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1));
-
-    // Establish async stream between client side and server side
-    void* t;
-    bool ok;
-    int need_tags = (1 << 0) | (1 << 1);
-    while (need_tags) {
-      GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-      GPR_ASSERT(ok);
-      int i = (int)(intptr_t)t;
-      GPR_ASSERT(need_tags & (1 << i));
-      need_tags &= ~(1 << i);
-    }
-
-    while (state.KeepRunning()) {
-      GPR_TIMER_SCOPE("BenchmarkCycle", 0);
-      request_rw->Write(send_request, tag(0));   // Start client send
-      response_rw.Read(&recv_request, tag(1));   // Start server recv
-      request_rw->Read(&recv_response, tag(2));  // Start client recv
-
-      need_tags = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3);
-      while (need_tags) {
-        GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-        GPR_ASSERT(ok);
-        int i = (int)(intptr_t)t;
-
-        // If server recv is complete, start the server send operation
-        if (i == 1) {
-          response_rw.Write(send_response, tag(3));
-        }
-
-        GPR_ASSERT(need_tags & (1 << i));
-        need_tags &= ~(1 << i);
-      }
-    }
-
-    request_rw->WritesDone(tag(0));
-    response_rw.Finish(Status::OK, tag(1));
-    Status recv_status;
-    request_rw->Finish(&recv_status, tag(2));
-
-    need_tags = (1 << 0) | (1 << 1) | (1 << 2);
-    while (need_tags) {
-      GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-      int i = (int)(intptr_t)t;
-      GPR_ASSERT(need_tags & (1 << i));
-      need_tags &= ~(1 << i);
-    }
-
-    GPR_ASSERT(recv_status.ok());
-  }
-
-  fixture->Finish(state);
-  fixture.reset();
-  state.SetBytesProcessed(msg_size * state.iterations() * 2);
-}
-
-template <class Fixture>
-static void BM_PumpStreamClientToServer(benchmark::State& state) {
-  EchoTestService::AsyncService service;
-  std::unique_ptr<Fixture> fixture(new Fixture(&service));
-  {
-    EchoRequest send_request;
-    EchoRequest recv_request;
-    if (state.range(0) > 0) {
-      send_request.set_message(std::string(state.range(0), 'a'));
-    }
-    Status recv_status;
-    ServerContext svr_ctx;
-    ServerAsyncReaderWriter<EchoResponse, EchoRequest> response_rw(&svr_ctx);
-    service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(),
-                              fixture->cq(), tag(0));
-    std::unique_ptr<EchoTestService::Stub> stub(
-        EchoTestService::NewStub(fixture->channel()));
-    ClientContext cli_ctx;
-    auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1));
-    int need_tags = (1 << 0) | (1 << 1);
-    void* t;
-    bool ok;
-    while (need_tags) {
-      GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-      GPR_ASSERT(ok);
-      int i = (int)(intptr_t)t;
-      GPR_ASSERT(need_tags & (1 << i));
-      need_tags &= ~(1 << i);
-    }
-    response_rw.Read(&recv_request, tag(0));
-    while (state.KeepRunning()) {
-      GPR_TIMER_SCOPE("BenchmarkCycle", 0);
-      request_rw->Write(send_request, tag(1));
-      while (true) {
-        GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-        if (t == tag(0)) {
-          response_rw.Read(&recv_request, tag(0));
-        } else if (t == tag(1)) {
-          break;
-        } else {
-          GPR_ASSERT(false);
-        }
-      }
-    }
-    request_rw->WritesDone(tag(1));
-    need_tags = (1 << 0) | (1 << 1);
-    while (need_tags) {
-      GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-      int i = (int)(intptr_t)t;
-      GPR_ASSERT(need_tags & (1 << i));
-      need_tags &= ~(1 << i);
-    }
-  }
-  fixture->Finish(state);
-  fixture.reset();
-  state.SetBytesProcessed(state.range(0) * state.iterations());
-}
-
-template <class Fixture>
-static void BM_PumpStreamServerToClient(benchmark::State& state) {
-  EchoTestService::AsyncService service;
-  std::unique_ptr<Fixture> fixture(new Fixture(&service));
-  {
-    EchoResponse send_response;
-    EchoResponse recv_response;
-    if (state.range(0) > 0) {
-      send_response.set_message(std::string(state.range(0), 'a'));
-    }
-    Status recv_status;
-    ServerContext svr_ctx;
-    ServerAsyncReaderWriter<EchoResponse, EchoRequest> response_rw(&svr_ctx);
-    service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(),
-                              fixture->cq(), tag(0));
-    std::unique_ptr<EchoTestService::Stub> stub(
-        EchoTestService::NewStub(fixture->channel()));
-    ClientContext cli_ctx;
-    auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1));
-    int need_tags = (1 << 0) | (1 << 1);
-    void* t;
-    bool ok;
-    while (need_tags) {
-      GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-      GPR_ASSERT(ok);
-      int i = (int)(intptr_t)t;
-      GPR_ASSERT(need_tags & (1 << i));
-      need_tags &= ~(1 << i);
-    }
-    request_rw->Read(&recv_response, tag(0));
-    while (state.KeepRunning()) {
-      GPR_TIMER_SCOPE("BenchmarkCycle", 0);
-      response_rw.Write(send_response, tag(1));
-      while (true) {
-        GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-        if (t == tag(0)) {
-          request_rw->Read(&recv_response, tag(0));
-        } else if (t == tag(1)) {
-          break;
-        } else {
-          GPR_ASSERT(false);
-        }
-      }
-    }
-    response_rw.Finish(Status::OK, tag(1));
-    need_tags = (1 << 0) | (1 << 1);
-    while (need_tags) {
-      GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-      int i = (int)(intptr_t)t;
-      GPR_ASSERT(need_tags & (1 << i));
-      need_tags &= ~(1 << i);
-    }
-  }
-  fixture->Finish(state);
-  fixture.reset();
-  state.SetBytesProcessed(state.range(0) * state.iterations());
-}
-
-static void TrickleCQNext(TrickledCHTTP2* fixture, void** t, bool* ok) {
-  while (true) {
-    switch (fixture->cq()->AsyncNext(
-        t, ok, gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
-                            gpr_time_from_micros(100, GPR_TIMESPAN)))) {
-      case CompletionQueue::TIMEOUT:
-        fixture->Step();
-        break;
-      case CompletionQueue::SHUTDOWN:
-        GPR_ASSERT(false);
-        break;
-      case CompletionQueue::GOT_EVENT:
-        return;
-    }
-  }
-}
-
-static void BM_PumpStreamServerToClient_Trickle(benchmark::State& state) {
-  EchoTestService::AsyncService service;
-  std::unique_ptr<TrickledCHTTP2> fixture(
-      new TrickledCHTTP2(&service, state.range(1)));
-  {
-    EchoResponse send_response;
-    EchoResponse recv_response;
-    if (state.range(0) > 0) {
-      send_response.set_message(std::string(state.range(0), 'a'));
-    }
-    Status recv_status;
-    ServerContext svr_ctx;
-    ServerAsyncReaderWriter<EchoResponse, EchoRequest> response_rw(&svr_ctx);
-    service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(),
-                              fixture->cq(), tag(0));
-    std::unique_ptr<EchoTestService::Stub> stub(
-        EchoTestService::NewStub(fixture->channel()));
-    ClientContext cli_ctx;
-    auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1));
-    int need_tags = (1 << 0) | (1 << 1);
-    void* t;
-    bool ok;
-    while (need_tags) {
-      TrickleCQNext(fixture.get(), &t, &ok);
-      GPR_ASSERT(ok);
-      int i = (int)(intptr_t)t;
-      GPR_ASSERT(need_tags & (1 << i));
-      need_tags &= ~(1 << i);
-    }
-    request_rw->Read(&recv_response, tag(0));
-    while (state.KeepRunning()) {
-      GPR_TIMER_SCOPE("BenchmarkCycle", 0);
-      response_rw.Write(send_response, tag(1));
-      while (true) {
-        TrickleCQNext(fixture.get(), &t, &ok);
-        if (t == tag(0)) {
-          request_rw->Read(&recv_response, tag(0));
-        } else if (t == tag(1)) {
-          break;
-        } else {
-          GPR_ASSERT(false);
-        }
-      }
-    }
-    response_rw.Finish(Status::OK, tag(1));
-    need_tags = (1 << 0) | (1 << 1);
-    while (need_tags) {
-      TrickleCQNext(fixture.get(), &t, &ok);
-      int i = (int)(intptr_t)t;
-      GPR_ASSERT(need_tags & (1 << i));
-      need_tags &= ~(1 << i);
-    }
-  }
-  fixture->Finish(state);
-  fixture.reset();
-  state.SetBytesProcessed(state.range(0) * state.iterations());
-}
-
-/*******************************************************************************
- * CONFIGURATIONS
- */
-
-static void SweepSizesArgs(benchmark::internal::Benchmark* b) {
-  b->Args({0, 0});
-  for (int i = 1; i <= 128 * 1024 * 1024; i *= 8) {
-    b->Args({i, 0});
-    b->Args({0, i});
-    b->Args({i, i});
-  }
-}
-
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, TCP, NoOpMutator, NoOpMutator)
-    ->Apply(SweepSizesArgs);
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, UDS, NoOpMutator, NoOpMutator)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, SockPair, NoOpMutator, NoOpMutator)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, NoOpMutator)
-    ->Apply(SweepSizesArgs);
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
-                   Client_AddMetadata<RandomBinaryMetadata<10>, 1>, NoOpMutator)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
-                   Client_AddMetadata<RandomBinaryMetadata<31>, 1>, NoOpMutator)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
-                   Client_AddMetadata<RandomBinaryMetadata<100>, 1>,
-                   NoOpMutator)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
-                   Client_AddMetadata<RandomBinaryMetadata<10>, 2>, NoOpMutator)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
-                   Client_AddMetadata<RandomBinaryMetadata<31>, 2>, NoOpMutator)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
-                   Client_AddMetadata<RandomBinaryMetadata<100>, 2>,
-                   NoOpMutator)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator,
-                   Server_AddInitialMetadata<RandomBinaryMetadata<10>, 1>)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator,
-                   Server_AddInitialMetadata<RandomBinaryMetadata<31>, 1>)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator,
-                   Server_AddInitialMetadata<RandomBinaryMetadata<100>, 1>)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
-                   Client_AddMetadata<RandomAsciiMetadata<10>, 1>, NoOpMutator)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
-                   Client_AddMetadata<RandomAsciiMetadata<31>, 1>, NoOpMutator)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
-                   Client_AddMetadata<RandomAsciiMetadata<100>, 1>, NoOpMutator)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator,
-                   Server_AddInitialMetadata<RandomAsciiMetadata<10>, 1>)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator,
-                   Server_AddInitialMetadata<RandomAsciiMetadata<31>, 1>)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator,
-                   Server_AddInitialMetadata<RandomAsciiMetadata<100>, 1>)
-    ->Args({0, 0});
-BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator,
-                   Server_AddInitialMetadata<RandomAsciiMetadata<10>, 100>)
-    ->Args({0, 0});
-
-BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, TCP)
-    ->Range(0, 128 * 1024 * 1024);
-BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, UDS)
-    ->Range(0, 128 * 1024 * 1024);
-BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, SockPair)
-    ->Range(0, 128 * 1024 * 1024);
-BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, InProcessCHTTP2)
-    ->Range(0, 128 * 1024 * 1024);
-BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, TCP)
-    ->Range(0, 128 * 1024 * 1024);
-BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, UDS)
-    ->Range(0, 128 * 1024 * 1024);
-BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, SockPair)
-    ->Range(0, 128 * 1024 * 1024);
-BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, InProcessCHTTP2)
-    ->Range(0, 128 * 1024 * 1024);
-
-static void TrickleArgs(benchmark::internal::Benchmark* b) {
-  for (int i = 1; i <= 128 * 1024 * 1024; i *= 8) {
-    for (int j = 1; j <= 128 * 1024 * 1024; j *= 8) {
-      double expected_time =
-          static_cast<double>(14 + i) / (125.0 * static_cast<double>(j));
-      if (expected_time > 0.01) continue;
-      b->Args({i, j});
-    }
-  }
-}
-
-BENCHMARK(BM_PumpStreamServerToClient_Trickle)->Apply(TrickleArgs);
-
-// Generate Args for StreamingPingPong benchmarks. Currently generates args for
-// only "small streams" (i.e streams with 0, 1 or 2 messages)
-static void StreamingPingPongArgs(benchmark::internal::Benchmark* b) {
-  int msg_size = 0;
-
-  b->Args({0, 0});  // spl case: 0 ping-pong msgs (msg_size doesn't matter here)
-
-  for (msg_size = 0; msg_size <= 128 * 1024 * 1024;
-       msg_size == 0 ? msg_size++ : msg_size *= 8) {
-    b->Args({msg_size, 1});
-    b->Args({msg_size, 2});
-  }
-}
-
-BENCHMARK_TEMPLATE(BM_StreamingPingPong, InProcessCHTTP2, NoOpMutator,
-                   NoOpMutator)
-    ->Apply(StreamingPingPongArgs);
-BENCHMARK_TEMPLATE(BM_StreamingPingPong, TCP, NoOpMutator, NoOpMutator)
-    ->Apply(StreamingPingPongArgs);
-
-BENCHMARK_TEMPLATE(BM_StreamingPingPongMsgs, InProcessCHTTP2, NoOpMutator,
-                   NoOpMutator)
-    ->Range(0, 128 * 1024 * 1024);
-BENCHMARK_TEMPLATE(BM_StreamingPingPongMsgs, TCP, NoOpMutator, NoOpMutator)
-    ->Range(0, 128 * 1024 * 1024);
-
-}  // namespace testing
-}  // namespace grpc
-
-BENCHMARK_MAIN();
diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc
new file mode 100644
index 0000000000000000000000000000000000000000..fd2210c4747c2e5e5cdf021d71584d280da53cb8
--- /dev/null
+++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc
@@ -0,0 +1,481 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/* Benchmark gRPC end2end in various configurations */
+
+#include <benchmark/benchmark.h>
+#include <sstream>
+#include "src/core/lib/profiling/timers.h"
+#include "src/cpp/client/create_channel_internal.h"
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/cpp/microbenchmarks/fullstack_context_mutators.h"
+#include "test/cpp/microbenchmarks/fullstack_fixtures.h"
+
+namespace grpc {
+namespace testing {
+
+// force library initialization
+auto& force_library_initialization = Library::get();
+
+/*******************************************************************************
+ * BENCHMARKING KERNELS
+ */
+
+static void* tag(intptr_t x) { return reinterpret_cast<void*>(x); }
+
+// Repeatedly makes Streaming Bidi calls (exchanging a configurable number of
+// messages in each call) in a loop on a single channel
+//
+//  First parmeter (i.e state.range(0)):  Message size (in bytes) to use
+//  Second parameter (i.e state.range(1)): Number of ping pong messages.
+//      Note: One ping-pong means two messages (one from client to server and
+//      the other from server to client):
+template <class Fixture, class ClientContextMutator, class ServerContextMutator>
+static void BM_StreamingPingPong(benchmark::State& state) {
+  const int msg_size = state.range(0);
+  const int max_ping_pongs = state.range(1);
+
+  EchoTestService::AsyncService service;
+  std::unique_ptr<Fixture> fixture(new Fixture(&service));
+  {
+    EchoResponse send_response;
+    EchoResponse recv_response;
+    EchoRequest send_request;
+    EchoRequest recv_request;
+
+    if (msg_size > 0) {
+      send_request.set_message(std::string(msg_size, 'a'));
+      send_response.set_message(std::string(msg_size, 'b'));
+    }
+
+    std::unique_ptr<EchoTestService::Stub> stub(
+        EchoTestService::NewStub(fixture->channel()));
+
+    while (state.KeepRunning()) {
+      ServerContext svr_ctx;
+      ServerContextMutator svr_ctx_mut(&svr_ctx);
+      ServerAsyncReaderWriter<EchoResponse, EchoRequest> response_rw(&svr_ctx);
+      service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(),
+                                fixture->cq(), tag(0));
+
+      ClientContext cli_ctx;
+      ClientContextMutator cli_ctx_mut(&cli_ctx);
+      auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1));
+
+      // Establish async stream between client side and server side
+      void* t;
+      bool ok;
+      int need_tags = (1 << 0) | (1 << 1);
+      while (need_tags) {
+        GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+        GPR_ASSERT(ok);
+        int i = (int)(intptr_t)t;
+        GPR_ASSERT(need_tags & (1 << i));
+        need_tags &= ~(1 << i);
+      }
+
+      // Send 'max_ping_pongs' number of ping pong messages
+      int ping_pong_cnt = 0;
+      while (ping_pong_cnt < max_ping_pongs) {
+        request_rw->Write(send_request, tag(0));   // Start client send
+        response_rw.Read(&recv_request, tag(1));   // Start server recv
+        request_rw->Read(&recv_response, tag(2));  // Start client recv
+
+        need_tags = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3);
+        while (need_tags) {
+          GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+          GPR_ASSERT(ok);
+          int i = (int)(intptr_t)t;
+
+          // If server recv is complete, start the server send operation
+          if (i == 1) {
+            response_rw.Write(send_response, tag(3));
+          }
+
+          GPR_ASSERT(need_tags & (1 << i));
+          need_tags &= ~(1 << i);
+        }
+
+        ping_pong_cnt++;
+      }
+
+      request_rw->WritesDone(tag(0));
+      response_rw.Finish(Status::OK, tag(1));
+
+      Status recv_status;
+      request_rw->Finish(&recv_status, tag(2));
+
+      need_tags = (1 << 0) | (1 << 1) | (1 << 2);
+      while (need_tags) {
+        GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+        int i = (int)(intptr_t)t;
+        GPR_ASSERT(need_tags & (1 << i));
+        need_tags &= ~(1 << i);
+      }
+
+      GPR_ASSERT(recv_status.ok());
+    }
+  }
+
+  fixture->Finish(state);
+  fixture.reset();
+  state.SetBytesProcessed(msg_size * state.iterations() * max_ping_pongs * 2);
+}
+
+// Repeatedly sends ping pong messages in a single streaming Bidi call in a loop
+//     First parmeter (i.e state.range(0)):  Message size (in bytes) to use
+template <class Fixture, class ClientContextMutator, class ServerContextMutator>
+static void BM_StreamingPingPongMsgs(benchmark::State& state) {
+  const int msg_size = state.range(0);
+
+  EchoTestService::AsyncService service;
+  std::unique_ptr<Fixture> fixture(new Fixture(&service));
+  {
+    EchoResponse send_response;
+    EchoResponse recv_response;
+    EchoRequest send_request;
+    EchoRequest recv_request;
+
+    if (msg_size > 0) {
+      send_request.set_message(std::string(msg_size, 'a'));
+      send_response.set_message(std::string(msg_size, 'b'));
+    }
+
+    std::unique_ptr<EchoTestService::Stub> stub(
+        EchoTestService::NewStub(fixture->channel()));
+
+    ServerContext svr_ctx;
+    ServerContextMutator svr_ctx_mut(&svr_ctx);
+    ServerAsyncReaderWriter<EchoResponse, EchoRequest> response_rw(&svr_ctx);
+    service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(),
+                              fixture->cq(), tag(0));
+
+    ClientContext cli_ctx;
+    ClientContextMutator cli_ctx_mut(&cli_ctx);
+    auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1));
+
+    // Establish async stream between client side and server side
+    void* t;
+    bool ok;
+    int need_tags = (1 << 0) | (1 << 1);
+    while (need_tags) {
+      GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+      GPR_ASSERT(ok);
+      int i = (int)(intptr_t)t;
+      GPR_ASSERT(need_tags & (1 << i));
+      need_tags &= ~(1 << i);
+    }
+
+    while (state.KeepRunning()) {
+      GPR_TIMER_SCOPE("BenchmarkCycle", 0);
+      request_rw->Write(send_request, tag(0));   // Start client send
+      response_rw.Read(&recv_request, tag(1));   // Start server recv
+      request_rw->Read(&recv_response, tag(2));  // Start client recv
+
+      need_tags = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3);
+      while (need_tags) {
+        GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+        GPR_ASSERT(ok);
+        int i = (int)(intptr_t)t;
+
+        // If server recv is complete, start the server send operation
+        if (i == 1) {
+          response_rw.Write(send_response, tag(3));
+        }
+
+        GPR_ASSERT(need_tags & (1 << i));
+        need_tags &= ~(1 << i);
+      }
+    }
+
+    request_rw->WritesDone(tag(0));
+    response_rw.Finish(Status::OK, tag(1));
+    Status recv_status;
+    request_rw->Finish(&recv_status, tag(2));
+
+    need_tags = (1 << 0) | (1 << 1) | (1 << 2);
+    while (need_tags) {
+      GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+      int i = (int)(intptr_t)t;
+      GPR_ASSERT(need_tags & (1 << i));
+      need_tags &= ~(1 << i);
+    }
+
+    GPR_ASSERT(recv_status.ok());
+  }
+
+  fixture->Finish(state);
+  fixture.reset();
+  state.SetBytesProcessed(msg_size * state.iterations() * 2);
+}
+
+// Repeatedly makes Streaming Bidi calls (exchanging a configurable number of
+// messages in each call) in a loop on a single channel. Different from
+// BM_StreamingPingPong we are using stream coalescing api, e.g. WriteLast,
+// WriteAndFinish, set_initial_metadata_corked. These apis aim at saving
+// sendmsg syscalls for streaming by coalescing 1. initial metadata with first
+// message; 2. final streaming message with trailing metadata.
+//
+//  First parmeter (i.e state.range(0)):  Message size (in bytes) to use
+//  Second parameter (i.e state.range(1)): Number of ping pong messages.
+//      Note: One ping-pong means two messages (one from client to server and
+//      the other from server to client):
+//  Third parameter (i.e state.range(2)): Switch between using WriteAndFinish
+//  API and WriteLast API for server.
+template <class Fixture, class ClientContextMutator, class ServerContextMutator>
+static void BM_StreamingPingPongWithCoalescingApi(benchmark::State& state) {
+  const int msg_size = state.range(0);
+  const int max_ping_pongs = state.range(1);
+  // This options is used to test out server API: WriteLast and WriteAndFinish
+  // respectively, since we can not use both of them on server side at the same
+  // time. Value 1 means we are testing out the WriteAndFinish API, and
+  // otherwise we are testing out the WriteLast API.
+  const int write_and_finish = state.range(2);
+
+  EchoTestService::AsyncService service;
+  std::unique_ptr<Fixture> fixture(new Fixture(&service));
+  {
+    EchoResponse send_response;
+    EchoResponse recv_response;
+    EchoRequest send_request;
+    EchoRequest recv_request;
+
+    if (msg_size > 0) {
+      send_request.set_message(std::string(msg_size, 'a'));
+      send_response.set_message(std::string(msg_size, 'b'));
+    }
+
+    std::unique_ptr<EchoTestService::Stub> stub(
+        EchoTestService::NewStub(fixture->channel()));
+
+    while (state.KeepRunning()) {
+      ServerContext svr_ctx;
+      ServerContextMutator svr_ctx_mut(&svr_ctx);
+      ServerAsyncReaderWriter<EchoResponse, EchoRequest> response_rw(&svr_ctx);
+      service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(),
+                                fixture->cq(), tag(0));
+
+      ClientContext cli_ctx;
+      ClientContextMutator cli_ctx_mut(&cli_ctx);
+      cli_ctx.set_initial_metadata_corked(true);
+      // tag:1 here will never comes up, since we are not performing any op due
+      // to initial metadata coalescing.
+      auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1));
+
+      void* t;
+      bool ok;
+      int need_tags;
+
+      // Send 'max_ping_pongs' number of ping pong messages
+      int ping_pong_cnt = 0;
+      while (ping_pong_cnt < max_ping_pongs) {
+        if (ping_pong_cnt == max_ping_pongs - 1) {
+          request_rw->WriteLast(send_request, WriteOptions(), tag(2));
+        } else {
+          request_rw->Write(send_request, tag(2));  // Start client send
+        }
+
+        need_tags = (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5);
+
+        if (ping_pong_cnt == 0) {
+          // wait for the server call structure (call_hook, etc.) to be
+          // initialized (async stream between client side and server side
+          // established). It is necessary when client init metadata is
+          // coalesced
+          GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+          while ((int)(intptr_t)t != 0) {
+            // In some cases tag:2 comes before tag:0 (write tag comes out
+            // first), this while loop is to make sure get tag:0.
+            int i = (int)(intptr_t)t;
+            GPR_ASSERT(need_tags & (1 << i));
+            need_tags &= ~(1 << i);
+            GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+          }
+        }
+
+        response_rw.Read(&recv_request, tag(3));   // Start server recv
+        request_rw->Read(&recv_response, tag(4));  // Start client recv
+
+        while (need_tags) {
+          GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+          GPR_ASSERT(ok);
+          int i = (int)(intptr_t)t;
+
+          // If server recv is complete, start the server send operation
+          if (i == 3) {
+            if (ping_pong_cnt == max_ping_pongs - 1) {
+              if (write_and_finish == 1) {
+                response_rw.WriteAndFinish(send_response, WriteOptions(),
+                                           Status::OK, tag(5));
+              } else {
+                response_rw.WriteLast(send_response, WriteOptions(), tag(5));
+                // WriteLast buffers the write, so neither server write op nor
+                // client read op will finish inside the while loop.
+                need_tags &= ~(1 << 4);
+                need_tags &= ~(1 << 5);
+              }
+            } else {
+              response_rw.Write(send_response, tag(5));
+            }
+          }
+
+          GPR_ASSERT(need_tags & (1 << i));
+          need_tags &= ~(1 << i);
+        }
+
+        ping_pong_cnt++;
+      }
+
+      if (max_ping_pongs == 0) {
+        need_tags = (1 << 6) | (1 << 7) | (1 << 8);
+      } else {
+        if (write_and_finish == 1) {
+          need_tags = (1 << 8);
+        } else {
+          // server's buffered write and the client's read of the buffered write
+          // tags should come up.
+          need_tags = (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8);
+        }
+      }
+
+      // No message write or initial metadata write happened yet.
+      if (max_ping_pongs == 0) {
+        request_rw->WritesDone(tag(6));
+        // wait for server call data structure(call_hook, etc.) to be
+        // initialized, since initial metadata is corked.
+        GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+        while ((int)(intptr_t)t != 0) {
+          int i = (int)(intptr_t)t;
+          GPR_ASSERT(need_tags & (1 << i));
+          need_tags &= ~(1 << i);
+          GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+        }
+        response_rw.Finish(Status::OK, tag(7));
+      } else {
+        if (write_and_finish != 1) {
+          response_rw.Finish(Status::OK, tag(7));
+        }
+      }
+
+      Status recv_status;
+      request_rw->Finish(&recv_status, tag(8));
+
+      while (need_tags) {
+        GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+        int i = (int)(intptr_t)t;
+        GPR_ASSERT(need_tags & (1 << i));
+        need_tags &= ~(1 << i);
+      }
+
+      GPR_ASSERT(recv_status.ok());
+    }
+  }
+
+  fixture->Finish(state);
+  fixture.reset();
+  state.SetBytesProcessed(msg_size * state.iterations() * max_ping_pongs * 2);
+}
+
+/*******************************************************************************
+ * CONFIGURATIONS
+ */
+
+// Generate Args for StreamingPingPong benchmarks. Currently generates args for
+// only "small streams" (i.e streams with 0, 1 or 2 messages)
+static void StreamingPingPongArgs(benchmark::internal::Benchmark* b) {
+  int msg_size = 0;
+
+  b->Args({0, 0});  // spl case: 0 ping-pong msgs (msg_size doesn't matter here)
+
+  for (msg_size = 0; msg_size <= 128 * 1024 * 1024;
+       msg_size == 0 ? msg_size++ : msg_size *= 8) {
+    b->Args({msg_size, 1});
+    b->Args({msg_size, 2});
+  }
+}
+
+BENCHMARK_TEMPLATE(BM_StreamingPingPong, InProcessCHTTP2, NoOpMutator,
+                   NoOpMutator)
+    ->Apply(StreamingPingPongArgs);
+BENCHMARK_TEMPLATE(BM_StreamingPingPong, TCP, NoOpMutator, NoOpMutator)
+    ->Apply(StreamingPingPongArgs);
+
+BENCHMARK_TEMPLATE(BM_StreamingPingPongMsgs, InProcessCHTTP2, NoOpMutator,
+                   NoOpMutator)
+    ->Range(0, 128 * 1024 * 1024);
+BENCHMARK_TEMPLATE(BM_StreamingPingPongMsgs, TCP, NoOpMutator, NoOpMutator)
+    ->Range(0, 128 * 1024 * 1024);
+
+BENCHMARK_TEMPLATE(BM_StreamingPingPong, MinInProcessCHTTP2, NoOpMutator,
+                   NoOpMutator)
+    ->Apply(StreamingPingPongArgs);
+BENCHMARK_TEMPLATE(BM_StreamingPingPong, MinTCP, NoOpMutator, NoOpMutator)
+    ->Apply(StreamingPingPongArgs);
+
+BENCHMARK_TEMPLATE(BM_StreamingPingPongMsgs, MinInProcessCHTTP2, NoOpMutator,
+                   NoOpMutator)
+    ->Range(0, 128 * 1024 * 1024);
+BENCHMARK_TEMPLATE(BM_StreamingPingPongMsgs, MinTCP, NoOpMutator, NoOpMutator)
+    ->Range(0, 128 * 1024 * 1024);
+
+// Generate Args for StreamingPingPongWithCoalescingApi benchmarks. Currently
+// generates args for only "small streams" (i.e streams with 0, 1 or 2 messages)
+static void StreamingPingPongWithCoalescingApiArgs(
+    benchmark::internal::Benchmark* b) {
+  int msg_size = 0;
+
+  b->Args(
+      {0, 0, 0});  // spl case: 0 ping-pong msgs (msg_size doesn't matter here)
+  b->Args(
+      {0, 0, 1});  // spl case: 0 ping-pong msgs (msg_size doesn't matter here)
+
+  for (msg_size = 0; msg_size <= 128 * 1024 * 1024;
+       msg_size == 0 ? msg_size++ : msg_size *= 8) {
+    b->Args({msg_size, 1, 0});
+    b->Args({msg_size, 2, 0});
+    b->Args({msg_size, 1, 1});
+    b->Args({msg_size, 2, 1});
+  }
+}
+
+BENCHMARK_TEMPLATE(BM_StreamingPingPongWithCoalescingApi, InProcessCHTTP2,
+                   NoOpMutator, NoOpMutator)
+    ->Apply(StreamingPingPongWithCoalescingApiArgs);
+BENCHMARK_TEMPLATE(BM_StreamingPingPongWithCoalescingApi, MinInProcessCHTTP2,
+                   NoOpMutator, NoOpMutator)
+    ->Apply(StreamingPingPongWithCoalescingApiArgs);
+
+}  // namespace testing
+}  // namespace grpc
+
+BENCHMARK_MAIN();
diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc
new file mode 100644
index 0000000000000000000000000000000000000000..47705d3031895c967a87d31c6d80e8ad41734b5b
--- /dev/null
+++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc
@@ -0,0 +1,204 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/* Benchmark gRPC end2end in various configurations */
+
+#include <benchmark/benchmark.h>
+#include <sstream>
+#include "src/core/lib/profiling/timers.h"
+#include "src/cpp/client/create_channel_internal.h"
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/cpp/microbenchmarks/fullstack_context_mutators.h"
+#include "test/cpp/microbenchmarks/fullstack_fixtures.h"
+
+namespace grpc {
+namespace testing {
+
+// force library initialization
+auto& force_library_initialization = Library::get();
+
+/*******************************************************************************
+ * BENCHMARKING KERNELS
+ */
+
+static void* tag(intptr_t x) { return reinterpret_cast<void*>(x); }
+
+template <class Fixture>
+static void BM_PumpStreamClientToServer(benchmark::State& state) {
+  EchoTestService::AsyncService service;
+  std::unique_ptr<Fixture> fixture(new Fixture(&service));
+  {
+    EchoRequest send_request;
+    EchoRequest recv_request;
+    if (state.range(0) > 0) {
+      send_request.set_message(std::string(state.range(0), 'a'));
+    }
+    Status recv_status;
+    ServerContext svr_ctx;
+    ServerAsyncReaderWriter<EchoResponse, EchoRequest> response_rw(&svr_ctx);
+    service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(),
+                              fixture->cq(), tag(0));
+    std::unique_ptr<EchoTestService::Stub> stub(
+        EchoTestService::NewStub(fixture->channel()));
+    ClientContext cli_ctx;
+    auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1));
+    int need_tags = (1 << 0) | (1 << 1);
+    void* t;
+    bool ok;
+    while (need_tags) {
+      GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+      GPR_ASSERT(ok);
+      int i = (int)(intptr_t)t;
+      GPR_ASSERT(need_tags & (1 << i));
+      need_tags &= ~(1 << i);
+    }
+    response_rw.Read(&recv_request, tag(0));
+    while (state.KeepRunning()) {
+      GPR_TIMER_SCOPE("BenchmarkCycle", 0);
+      request_rw->Write(send_request, tag(1));
+      while (true) {
+        GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+        if (t == tag(0)) {
+          response_rw.Read(&recv_request, tag(0));
+        } else if (t == tag(1)) {
+          break;
+        } else {
+          GPR_ASSERT(false);
+        }
+      }
+    }
+    request_rw->WritesDone(tag(1));
+    need_tags = (1 << 0) | (1 << 1);
+    while (need_tags) {
+      GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+      int i = (int)(intptr_t)t;
+      GPR_ASSERT(need_tags & (1 << i));
+      need_tags &= ~(1 << i);
+    }
+  }
+  fixture->Finish(state);
+  fixture.reset();
+  state.SetBytesProcessed(state.range(0) * state.iterations());
+}
+
+template <class Fixture>
+static void BM_PumpStreamServerToClient(benchmark::State& state) {
+  EchoTestService::AsyncService service;
+  std::unique_ptr<Fixture> fixture(new Fixture(&service));
+  {
+    EchoResponse send_response;
+    EchoResponse recv_response;
+    if (state.range(0) > 0) {
+      send_response.set_message(std::string(state.range(0), 'a'));
+    }
+    Status recv_status;
+    ServerContext svr_ctx;
+    ServerAsyncReaderWriter<EchoResponse, EchoRequest> response_rw(&svr_ctx);
+    service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(),
+                              fixture->cq(), tag(0));
+    std::unique_ptr<EchoTestService::Stub> stub(
+        EchoTestService::NewStub(fixture->channel()));
+    ClientContext cli_ctx;
+    auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1));
+    int need_tags = (1 << 0) | (1 << 1);
+    void* t;
+    bool ok;
+    while (need_tags) {
+      GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+      GPR_ASSERT(ok);
+      int i = (int)(intptr_t)t;
+      GPR_ASSERT(need_tags & (1 << i));
+      need_tags &= ~(1 << i);
+    }
+    request_rw->Read(&recv_response, tag(0));
+    while (state.KeepRunning()) {
+      GPR_TIMER_SCOPE("BenchmarkCycle", 0);
+      response_rw.Write(send_response, tag(1));
+      while (true) {
+        GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+        if (t == tag(0)) {
+          request_rw->Read(&recv_response, tag(0));
+        } else if (t == tag(1)) {
+          break;
+        } else {
+          GPR_ASSERT(false);
+        }
+      }
+    }
+    response_rw.Finish(Status::OK, tag(1));
+    need_tags = (1 << 0) | (1 << 1);
+    while (need_tags) {
+      GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+      int i = (int)(intptr_t)t;
+      GPR_ASSERT(need_tags & (1 << i));
+      need_tags &= ~(1 << i);
+    }
+  }
+  fixture->Finish(state);
+  fixture.reset();
+  state.SetBytesProcessed(state.range(0) * state.iterations());
+}
+
+/*******************************************************************************
+ * CONFIGURATIONS
+ */
+
+BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, TCP)
+    ->Range(0, 128 * 1024 * 1024);
+BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, UDS)
+    ->Range(0, 128 * 1024 * 1024);
+BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, SockPair)
+    ->Range(0, 128 * 1024 * 1024);
+BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, InProcessCHTTP2)
+    ->Range(0, 128 * 1024 * 1024);
+BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, TCP)
+    ->Range(0, 128 * 1024 * 1024);
+BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, UDS)
+    ->Range(0, 128 * 1024 * 1024);
+BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, SockPair)
+    ->Range(0, 128 * 1024 * 1024);
+BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, InProcessCHTTP2)
+    ->Range(0, 128 * 1024 * 1024);
+BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, MinTCP)->Arg(0);
+BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, MinUDS)->Arg(0);
+BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, MinSockPair)->Arg(0);
+BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, MinInProcessCHTTP2)->Arg(0);
+BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, MinTCP)->Arg(0);
+BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, MinUDS)->Arg(0);
+BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, MinSockPair)->Arg(0);
+BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, MinInProcessCHTTP2)->Arg(0);
+
+}  // namespace testing
+}  // namespace grpc
+
+BENCHMARK_MAIN();
diff --git a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a5cfeb4f955de18ef97991a93b356d6ae4d2d4fe
--- /dev/null
+++ b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc
@@ -0,0 +1,220 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/* Benchmark gRPC end2end in various configurations */
+
+#include <benchmark/benchmark.h>
+#include "src/core/lib/profiling/timers.h"
+#include "src/cpp/client/create_channel_internal.h"
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/cpp/microbenchmarks/fullstack_context_mutators.h"
+#include "test/cpp/microbenchmarks/fullstack_fixtures.h"
+extern "C" {
+#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
+#include "src/core/ext/transport/chttp2/transport/internal.h"
+#include "test/core/util/trickle_endpoint.h"
+}
+
+namespace grpc {
+namespace testing {
+
+static void* tag(intptr_t x) { return reinterpret_cast<void*>(x); }
+
+class TrickledCHTTP2 : public EndpointPairFixture {
+ public:
+  TrickledCHTTP2(Service* service, size_t megabits_per_second)
+      : EndpointPairFixture(service, MakeEndpoints(megabits_per_second),
+                            FixtureConfiguration()) {}
+
+  void AddToLabel(std::ostream& out, benchmark::State& state) {
+    out << " writes/iter:"
+        << ((double)stats_.num_writes / (double)state.iterations())
+        << " cli_transport_stalls/iter:"
+        << ((double)
+                client_stats_.streams_stalled_due_to_transport_flow_control /
+            (double)state.iterations())
+        << " cli_stream_stalls/iter:"
+        << ((double)client_stats_.streams_stalled_due_to_stream_flow_control /
+            (double)state.iterations())
+        << " svr_transport_stalls/iter:"
+        << ((double)
+                server_stats_.streams_stalled_due_to_transport_flow_control /
+            (double)state.iterations())
+        << " svr_stream_stalls/iter:"
+        << ((double)server_stats_.streams_stalled_due_to_stream_flow_control /
+            (double)state.iterations());
+  }
+
+  void Step() {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    size_t client_backlog =
+        grpc_trickle_endpoint_trickle(&exec_ctx, endpoint_pair_.client);
+    size_t server_backlog =
+        grpc_trickle_endpoint_trickle(&exec_ctx, endpoint_pair_.server);
+    grpc_exec_ctx_finish(&exec_ctx);
+
+    UpdateStats((grpc_chttp2_transport*)client_transport_, &client_stats_,
+                client_backlog);
+    UpdateStats((grpc_chttp2_transport*)server_transport_, &server_stats_,
+                server_backlog);
+  }
+
+ private:
+  grpc_passthru_endpoint_stats stats_;
+  struct Stats {
+    int streams_stalled_due_to_stream_flow_control = 0;
+    int streams_stalled_due_to_transport_flow_control = 0;
+  };
+  Stats client_stats_;
+  Stats server_stats_;
+
+  grpc_endpoint_pair MakeEndpoints(size_t kilobits) {
+    grpc_endpoint_pair p;
+    grpc_passthru_endpoint_create(&p.client, &p.server, Library::get().rq(),
+                                  &stats_);
+    double bytes_per_second = 125.0 * kilobits;
+    p.client = grpc_trickle_endpoint_create(p.client, bytes_per_second);
+    p.server = grpc_trickle_endpoint_create(p.server, bytes_per_second);
+    return p;
+  }
+
+  void UpdateStats(grpc_chttp2_transport* t, Stats* s, size_t backlog) {
+    if (backlog == 0) {
+      if (t->lists[GRPC_CHTTP2_LIST_STALLED_BY_STREAM].head != NULL) {
+        s->streams_stalled_due_to_stream_flow_control++;
+      }
+      if (t->lists[GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT].head != NULL) {
+        s->streams_stalled_due_to_transport_flow_control++;
+      }
+    }
+  }
+};
+
+// force library initialization
+auto& force_library_initialization = Library::get();
+
+static void TrickleCQNext(TrickledCHTTP2* fixture, void** t, bool* ok) {
+  while (true) {
+    switch (fixture->cq()->AsyncNext(
+        t, ok, gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+                            gpr_time_from_micros(100, GPR_TIMESPAN)))) {
+      case CompletionQueue::TIMEOUT:
+        fixture->Step();
+        break;
+      case CompletionQueue::SHUTDOWN:
+        GPR_ASSERT(false);
+        break;
+      case CompletionQueue::GOT_EVENT:
+        return;
+    }
+  }
+}
+
+static void BM_PumpStreamServerToClient_Trickle(benchmark::State& state) {
+  EchoTestService::AsyncService service;
+  std::unique_ptr<TrickledCHTTP2> fixture(
+      new TrickledCHTTP2(&service, state.range(1)));
+  {
+    EchoResponse send_response;
+    EchoResponse recv_response;
+    if (state.range(0) > 0) {
+      send_response.set_message(std::string(state.range(0), 'a'));
+    }
+    Status recv_status;
+    ServerContext svr_ctx;
+    ServerAsyncReaderWriter<EchoResponse, EchoRequest> response_rw(&svr_ctx);
+    service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(),
+                              fixture->cq(), tag(0));
+    std::unique_ptr<EchoTestService::Stub> stub(
+        EchoTestService::NewStub(fixture->channel()));
+    ClientContext cli_ctx;
+    auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1));
+    int need_tags = (1 << 0) | (1 << 1);
+    void* t;
+    bool ok;
+    while (need_tags) {
+      TrickleCQNext(fixture.get(), &t, &ok);
+      GPR_ASSERT(ok);
+      int i = (int)(intptr_t)t;
+      GPR_ASSERT(need_tags & (1 << i));
+      need_tags &= ~(1 << i);
+    }
+    request_rw->Read(&recv_response, tag(0));
+    while (state.KeepRunning()) {
+      GPR_TIMER_SCOPE("BenchmarkCycle", 0);
+      response_rw.Write(send_response, tag(1));
+      while (true) {
+        TrickleCQNext(fixture.get(), &t, &ok);
+        if (t == tag(0)) {
+          request_rw->Read(&recv_response, tag(0));
+        } else if (t == tag(1)) {
+          break;
+        } else {
+          GPR_ASSERT(false);
+        }
+      }
+    }
+    response_rw.Finish(Status::OK, tag(1));
+    need_tags = (1 << 0) | (1 << 1);
+    while (need_tags) {
+      TrickleCQNext(fixture.get(), &t, &ok);
+      int i = (int)(intptr_t)t;
+      GPR_ASSERT(need_tags & (1 << i));
+      need_tags &= ~(1 << i);
+    }
+  }
+  fixture->Finish(state);
+  fixture.reset();
+  state.SetBytesProcessed(state.range(0) * state.iterations());
+}
+
+/*******************************************************************************
+ * CONFIGURATIONS
+ */
+
+static void TrickleArgs(benchmark::internal::Benchmark* b) {
+  for (int i = 1; i <= 128 * 1024 * 1024; i *= 8) {
+    for (int j = 1; j <= 128 * 1024 * 1024; j *= 8) {
+      double expected_time =
+          static_cast<double>(14 + i) / (125.0 * static_cast<double>(j));
+      if (expected_time > 0.01) continue;
+      b->Args({i, j});
+    }
+  }
+}
+
+BENCHMARK(BM_PumpStreamServerToClient_Trickle)->Apply(TrickleArgs);
+}
+}
+
+BENCHMARK_MAIN();
diff --git a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7524751fbcef2d69592971878d5992ea3b331b29
--- /dev/null
+++ b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc
@@ -0,0 +1,213 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/* Benchmark gRPC end2end in various configurations */
+
+#include <benchmark/benchmark.h>
+#include <sstream>
+#include "src/core/lib/profiling/timers.h"
+#include "src/cpp/client/create_channel_internal.h"
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/cpp/microbenchmarks/fullstack_context_mutators.h"
+#include "test/cpp/microbenchmarks/fullstack_fixtures.h"
+
+namespace grpc {
+namespace testing {
+
+// force library initialization
+auto& force_library_initialization = Library::get();
+
+/*******************************************************************************
+ * BENCHMARKING KERNELS
+ */
+
+static void* tag(intptr_t x) { return reinterpret_cast<void*>(x); }
+
+template <class Fixture, class ClientContextMutator, class ServerContextMutator>
+static void BM_UnaryPingPong(benchmark::State& state) {
+  EchoTestService::AsyncService service;
+  std::unique_ptr<Fixture> fixture(new Fixture(&service));
+  EchoRequest send_request;
+  EchoResponse send_response;
+  EchoResponse recv_response;
+  if (state.range(0) > 0) {
+    send_request.set_message(std::string(state.range(0), 'a'));
+  }
+  if (state.range(1) > 0) {
+    send_response.set_message(std::string(state.range(1), 'a'));
+  }
+  Status recv_status;
+  struct ServerEnv {
+    ServerContext ctx;
+    EchoRequest recv_request;
+    grpc::ServerAsyncResponseWriter<EchoResponse> response_writer;
+    ServerEnv() : response_writer(&ctx) {}
+  };
+  uint8_t server_env_buffer[2 * sizeof(ServerEnv)];
+  ServerEnv* server_env[2] = {
+      reinterpret_cast<ServerEnv*>(server_env_buffer),
+      reinterpret_cast<ServerEnv*>(server_env_buffer + sizeof(ServerEnv))};
+  new (server_env[0]) ServerEnv;
+  new (server_env[1]) ServerEnv;
+  service.RequestEcho(&server_env[0]->ctx, &server_env[0]->recv_request,
+                      &server_env[0]->response_writer, fixture->cq(),
+                      fixture->cq(), tag(0));
+  service.RequestEcho(&server_env[1]->ctx, &server_env[1]->recv_request,
+                      &server_env[1]->response_writer, fixture->cq(),
+                      fixture->cq(), tag(1));
+  std::unique_ptr<EchoTestService::Stub> stub(
+      EchoTestService::NewStub(fixture->channel()));
+  while (state.KeepRunning()) {
+    GPR_TIMER_SCOPE("BenchmarkCycle", 0);
+    recv_response.Clear();
+    ClientContext cli_ctx;
+    ClientContextMutator cli_ctx_mut(&cli_ctx);
+    std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
+        stub->AsyncEcho(&cli_ctx, send_request, fixture->cq()));
+    void* t;
+    bool ok;
+    GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+    GPR_ASSERT(ok);
+    GPR_ASSERT(t == tag(0) || t == tag(1));
+    intptr_t slot = reinterpret_cast<intptr_t>(t);
+    ServerEnv* senv = server_env[slot];
+    ServerContextMutator svr_ctx_mut(&senv->ctx);
+    senv->response_writer.Finish(send_response, Status::OK, tag(3));
+    response_reader->Finish(&recv_response, &recv_status, tag(4));
+    for (int i = (1 << 3) | (1 << 4); i != 0;) {
+      GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+      GPR_ASSERT(ok);
+      int tagnum = (int)reinterpret_cast<intptr_t>(t);
+      GPR_ASSERT(i & (1 << tagnum));
+      i -= 1 << tagnum;
+    }
+    GPR_ASSERT(recv_status.ok());
+
+    senv->~ServerEnv();
+    senv = new (senv) ServerEnv();
+    service.RequestEcho(&senv->ctx, &senv->recv_request, &senv->response_writer,
+                        fixture->cq(), fixture->cq(), tag(slot));
+  }
+  fixture->Finish(state);
+  fixture.reset();
+  server_env[0]->~ServerEnv();
+  server_env[1]->~ServerEnv();
+  state.SetBytesProcessed(state.range(0) * state.iterations() +
+                          state.range(1) * state.iterations());
+}
+
+/*******************************************************************************
+ * CONFIGURATIONS
+ */
+
+static void SweepSizesArgs(benchmark::internal::Benchmark* b) {
+  b->Args({0, 0});
+  for (int i = 1; i <= 128 * 1024 * 1024; i *= 8) {
+    b->Args({i, 0});
+    b->Args({0, i});
+    b->Args({i, i});
+  }
+}
+
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, TCP, NoOpMutator, NoOpMutator)
+    ->Apply(SweepSizesArgs);
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, MinTCP, NoOpMutator, NoOpMutator)
+    ->Apply(SweepSizesArgs);
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, UDS, NoOpMutator, NoOpMutator)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, MinUDS, NoOpMutator, NoOpMutator)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, SockPair, NoOpMutator, NoOpMutator)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, MinSockPair, NoOpMutator, NoOpMutator)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, NoOpMutator)
+    ->Apply(SweepSizesArgs);
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, MinInProcessCHTTP2, NoOpMutator,
+                   NoOpMutator)
+    ->Apply(SweepSizesArgs);
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
+                   Client_AddMetadata<RandomBinaryMetadata<10>, 1>, NoOpMutator)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
+                   Client_AddMetadata<RandomBinaryMetadata<31>, 1>, NoOpMutator)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
+                   Client_AddMetadata<RandomBinaryMetadata<100>, 1>,
+                   NoOpMutator)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
+                   Client_AddMetadata<RandomBinaryMetadata<10>, 2>, NoOpMutator)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
+                   Client_AddMetadata<RandomBinaryMetadata<31>, 2>, NoOpMutator)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
+                   Client_AddMetadata<RandomBinaryMetadata<100>, 2>,
+                   NoOpMutator)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator,
+                   Server_AddInitialMetadata<RandomBinaryMetadata<10>, 1>)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator,
+                   Server_AddInitialMetadata<RandomBinaryMetadata<31>, 1>)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator,
+                   Server_AddInitialMetadata<RandomBinaryMetadata<100>, 1>)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
+                   Client_AddMetadata<RandomAsciiMetadata<10>, 1>, NoOpMutator)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
+                   Client_AddMetadata<RandomAsciiMetadata<31>, 1>, NoOpMutator)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2,
+                   Client_AddMetadata<RandomAsciiMetadata<100>, 1>, NoOpMutator)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator,
+                   Server_AddInitialMetadata<RandomAsciiMetadata<10>, 1>)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator,
+                   Server_AddInitialMetadata<RandomAsciiMetadata<31>, 1>)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator,
+                   Server_AddInitialMetadata<RandomAsciiMetadata<100>, 1>)
+    ->Args({0, 0});
+BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator,
+                   Server_AddInitialMetadata<RandomAsciiMetadata<10>, 100>)
+    ->Args({0, 0});
+
+}  // namespace testing
+}  // namespace grpc
+
+BENCHMARK_MAIN();
diff --git a/test/cpp/microbenchmarks/bm_metadata.cc b/test/cpp/microbenchmarks/bm_metadata.cc
index 7f81fbabcc1760f21aef6d1ed3dd3d8af9f3076f..7029f369ad80cf9c40562975c645b53930f90439 100644
--- a/test/cpp/microbenchmarks/bm_metadata.cc
+++ b/test/cpp/microbenchmarks/bm_metadata.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2017, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,6 +33,7 @@
 
 /* Test out various metadata handling primitives */
 
+#include <benchmark/benchmark.h>
 #include <grpc/grpc.h>
 
 extern "C" {
@@ -40,61 +41,70 @@ extern "C" {
 #include "src/core/lib/transport/static_metadata.h"
 }
 
-#include "third_party/benchmark/include/benchmark/benchmark.h"
+#include "test/cpp/microbenchmarks/helpers.h"
 
-static class InitializeStuff {
- public:
-  InitializeStuff() { grpc_init(); }
-  ~InitializeStuff() { grpc_shutdown(); }
-} initialize_stuff;
+auto& force_library_initialization = Library::get();
 
 static void BM_SliceFromStatic(benchmark::State& state) {
+  TrackCounters track_counters;
   while (state.KeepRunning()) {
     benchmark::DoNotOptimize(grpc_slice_from_static_string("abc"));
   }
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_SliceFromStatic);
 
 static void BM_SliceFromCopied(benchmark::State& state) {
+  TrackCounters track_counters;
   while (state.KeepRunning()) {
     grpc_slice_unref(grpc_slice_from_copied_string("abc"));
   }
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_SliceFromCopied);
 
 static void BM_SliceIntern(benchmark::State& state) {
+  TrackCounters track_counters;
   gpr_slice slice = grpc_slice_from_static_string("abc");
   while (state.KeepRunning()) {
     grpc_slice_unref(grpc_slice_intern(slice));
   }
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_SliceIntern);
 
 static void BM_SliceReIntern(benchmark::State& state) {
+  TrackCounters track_counters;
   gpr_slice slice = grpc_slice_intern(grpc_slice_from_static_string("abc"));
   while (state.KeepRunning()) {
     grpc_slice_unref(grpc_slice_intern(slice));
   }
   grpc_slice_unref(slice);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_SliceReIntern);
 
 static void BM_SliceInternStaticMetadata(benchmark::State& state) {
+  TrackCounters track_counters;
   while (state.KeepRunning()) {
     grpc_slice_intern(GRPC_MDSTR_GZIP);
   }
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_SliceInternStaticMetadata);
 
 static void BM_SliceInternEqualToStaticMetadata(benchmark::State& state) {
+  TrackCounters track_counters;
   gpr_slice slice = grpc_slice_from_static_string("gzip");
   while (state.KeepRunning()) {
     grpc_slice_intern(slice);
   }
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_SliceInternEqualToStaticMetadata);
 
 static void BM_MetadataFromNonInternedSlices(benchmark::State& state) {
+  TrackCounters track_counters;
   gpr_slice k = grpc_slice_from_static_string("key");
   gpr_slice v = grpc_slice_from_static_string("value");
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -102,10 +112,12 @@ static void BM_MetadataFromNonInternedSlices(benchmark::State& state) {
     GRPC_MDELEM_UNREF(&exec_ctx, grpc_mdelem_create(&exec_ctx, k, v, NULL));
   }
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_MetadataFromNonInternedSlices);
 
 static void BM_MetadataFromInternedSlices(benchmark::State& state) {
+  TrackCounters track_counters;
   gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key"));
   gpr_slice v = grpc_slice_intern(grpc_slice_from_static_string("value"));
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -115,11 +127,13 @@ static void BM_MetadataFromInternedSlices(benchmark::State& state) {
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_slice_unref(k);
   grpc_slice_unref(v);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_MetadataFromInternedSlices);
 
 static void BM_MetadataFromInternedSlicesAlreadyInIndex(
     benchmark::State& state) {
+  TrackCounters track_counters;
   gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key"));
   gpr_slice v = grpc_slice_intern(grpc_slice_from_static_string("value"));
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -131,10 +145,12 @@ static void BM_MetadataFromInternedSlicesAlreadyInIndex(
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_slice_unref(k);
   grpc_slice_unref(v);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_MetadataFromInternedSlicesAlreadyInIndex);
 
 static void BM_MetadataFromInternedKey(benchmark::State& state) {
+  TrackCounters track_counters;
   gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key"));
   gpr_slice v = grpc_slice_from_static_string("value");
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -143,11 +159,13 @@ static void BM_MetadataFromInternedKey(benchmark::State& state) {
   }
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_slice_unref(k);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_MetadataFromInternedKey);
 
 static void BM_MetadataFromNonInternedSlicesWithBackingStore(
     benchmark::State& state) {
+  TrackCounters track_counters;
   gpr_slice k = grpc_slice_from_static_string("key");
   gpr_slice v = grpc_slice_from_static_string("value");
   char backing_store[sizeof(grpc_mdelem_data)];
@@ -159,11 +177,13 @@ static void BM_MetadataFromNonInternedSlicesWithBackingStore(
                            reinterpret_cast<grpc_mdelem_data*>(backing_store)));
   }
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_MetadataFromNonInternedSlicesWithBackingStore);
 
 static void BM_MetadataFromInternedSlicesWithBackingStore(
     benchmark::State& state) {
+  TrackCounters track_counters;
   gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key"));
   gpr_slice v = grpc_slice_intern(grpc_slice_from_static_string("value"));
   char backing_store[sizeof(grpc_mdelem_data)];
@@ -177,11 +197,13 @@ static void BM_MetadataFromInternedSlicesWithBackingStore(
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_slice_unref(k);
   grpc_slice_unref(v);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_MetadataFromInternedSlicesWithBackingStore);
 
 static void BM_MetadataFromInternedKeyWithBackingStore(
     benchmark::State& state) {
+  TrackCounters track_counters;
   gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key"));
   gpr_slice v = grpc_slice_from_static_string("value");
   char backing_store[sizeof(grpc_mdelem_data)];
@@ -194,10 +216,12 @@ static void BM_MetadataFromInternedKeyWithBackingStore(
   }
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_slice_unref(k);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_MetadataFromInternedKeyWithBackingStore);
 
 static void BM_MetadataFromStaticMetadataStrings(benchmark::State& state) {
+  TrackCounters track_counters;
   gpr_slice k = GRPC_MDSTR_STATUS;
   gpr_slice v = GRPC_MDSTR_200;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -206,11 +230,13 @@ static void BM_MetadataFromStaticMetadataStrings(benchmark::State& state) {
   }
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_slice_unref(k);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_MetadataFromStaticMetadataStrings);
 
 static void BM_MetadataFromStaticMetadataStringsNotIndexed(
     benchmark::State& state) {
+  TrackCounters track_counters;
   gpr_slice k = GRPC_MDSTR_STATUS;
   gpr_slice v = GRPC_MDSTR_GZIP;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -219,10 +245,12 @@ static void BM_MetadataFromStaticMetadataStringsNotIndexed(
   }
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_slice_unref(k);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_MetadataFromStaticMetadataStringsNotIndexed);
 
 static void BM_MetadataRefUnrefExternal(benchmark::State& state) {
+  TrackCounters track_counters;
   char backing_store[sizeof(grpc_mdelem_data)];
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_mdelem el =
@@ -234,10 +262,12 @@ static void BM_MetadataRefUnrefExternal(benchmark::State& state) {
   }
   GRPC_MDELEM_UNREF(&exec_ctx, el);
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_MetadataRefUnrefExternal);
 
 static void BM_MetadataRefUnrefInterned(benchmark::State& state) {
+  TrackCounters track_counters;
   char backing_store[sizeof(grpc_mdelem_data)];
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key"));
@@ -251,10 +281,12 @@ static void BM_MetadataRefUnrefInterned(benchmark::State& state) {
   }
   GRPC_MDELEM_UNREF(&exec_ctx, el);
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_MetadataRefUnrefInterned);
 
 static void BM_MetadataRefUnrefAllocated(benchmark::State& state) {
+  TrackCounters track_counters;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_mdelem el =
       grpc_mdelem_create(&exec_ctx, grpc_slice_from_static_string("a"),
@@ -264,10 +296,12 @@ static void BM_MetadataRefUnrefAllocated(benchmark::State& state) {
   }
   GRPC_MDELEM_UNREF(&exec_ctx, el);
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_MetadataRefUnrefAllocated);
 
 static void BM_MetadataRefUnrefStatic(benchmark::State& state) {
+  TrackCounters track_counters;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_mdelem el =
       grpc_mdelem_create(&exec_ctx, GRPC_MDSTR_STATUS, GRPC_MDSTR_200, NULL);
@@ -276,6 +310,7 @@ static void BM_MetadataRefUnrefStatic(benchmark::State& state) {
   }
   GRPC_MDELEM_UNREF(&exec_ctx, el);
   grpc_exec_ctx_finish(&exec_ctx);
+  track_counters.Finish(state);
 }
 BENCHMARK(BM_MetadataRefUnrefStatic);
 
diff --git a/test/cpp/microbenchmarks/bm_pollset.cc b/test/cpp/microbenchmarks/bm_pollset.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0f3d3cef66a9e9c4fae30305e078d6a4dfe9b373
--- /dev/null
+++ b/test/cpp/microbenchmarks/bm_pollset.cc
@@ -0,0 +1,254 @@
+/*
+ *
+ * Copyright 2017, 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.
+ *
+ */
+
+/* Test out pollset latencies */
+
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/useful.h>
+
+extern "C" {
+#include "src/core/lib/iomgr/ev_posix.h"
+#include "src/core/lib/iomgr/pollset.h"
+#include "src/core/lib/iomgr/port.h"
+#include "src/core/lib/iomgr/wakeup_fd_posix.h"
+}
+
+#include "test/cpp/microbenchmarks/helpers.h"
+#include "third_party/benchmark/include/benchmark/benchmark.h"
+
+#include <string.h>
+
+#ifdef GRPC_LINUX_MULTIPOLL_WITH_EPOLL
+#include <sys/epoll.h>
+#include <sys/eventfd.h>
+#include <unistd.h>
+#endif
+
+auto& force_library_initialization = Library::get();
+
+static void shutdown_ps(grpc_exec_ctx* exec_ctx, void* ps, grpc_error* error) {
+  grpc_pollset_destroy(static_cast<grpc_pollset*>(ps));
+}
+
+static void BM_CreateDestroyPollset(benchmark::State& state) {
+  TrackCounters track_counters;
+  size_t ps_sz = grpc_pollset_size();
+  grpc_pollset* ps = static_cast<grpc_pollset*>(gpr_malloc(ps_sz));
+  gpr_mu* mu;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_closure shutdown_ps_closure;
+  grpc_closure_init(&shutdown_ps_closure, shutdown_ps, ps,
+                    grpc_schedule_on_exec_ctx);
+  while (state.KeepRunning()) {
+    memset(ps, 0, ps_sz);
+    grpc_pollset_init(ps, &mu);
+    gpr_mu_lock(mu);
+    grpc_pollset_shutdown(&exec_ctx, ps, &shutdown_ps_closure);
+    gpr_mu_unlock(mu);
+    grpc_exec_ctx_flush(&exec_ctx);
+  }
+  grpc_exec_ctx_finish(&exec_ctx);
+  gpr_free(ps);
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_CreateDestroyPollset);
+
+#ifdef GRPC_LINUX_MULTIPOLL_WITH_EPOLL
+static void BM_PollEmptyPollset_SpeedOfLight(benchmark::State& state) {
+  // equivalent to BM_PollEmptyPollset, but just use the OS primitives to guage
+  // what the speed of light would be if we abstracted perfectly
+  TrackCounters track_counters;
+  int epfd = epoll_create1(0);
+  GPR_ASSERT(epfd != -1);
+  size_t nev = state.range(0);
+  size_t nfd = state.range(1);
+  epoll_event* ev = new epoll_event[nev];
+  std::vector<int> fds;
+  for (size_t i = 0; i < nfd; i++) {
+    fds.push_back(eventfd(0, 0));
+    epoll_event ev;
+    ev.events = EPOLLIN;
+    epoll_ctl(epfd, EPOLL_CTL_ADD, fds.back(), &ev);
+  }
+  while (state.KeepRunning()) {
+    epoll_wait(epfd, ev, nev, 0);
+  }
+  for (auto fd : fds) {
+    close(fd);
+  }
+  close(epfd);
+  delete[] ev;
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_PollEmptyPollset_SpeedOfLight)
+    ->Args({1, 0})
+    ->Args({1, 1})
+    ->Args({1, 10})
+    ->Args({1, 100})
+    ->Args({1, 1000})
+    ->Args({1, 10000})
+    ->Args({1, 100000})
+    ->Args({10, 1})
+    ->Args({100, 1})
+    ->Args({1000, 1});
+#endif
+
+static void BM_PollEmptyPollset(benchmark::State& state) {
+  TrackCounters track_counters;
+  size_t ps_sz = grpc_pollset_size();
+  grpc_pollset* ps = static_cast<grpc_pollset*>(gpr_zalloc(ps_sz));
+  gpr_mu* mu;
+  grpc_pollset_init(ps, &mu);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  gpr_timespec now = gpr_time_0(GPR_CLOCK_MONOTONIC);
+  gpr_timespec deadline = gpr_inf_past(GPR_CLOCK_MONOTONIC);
+  gpr_mu_lock(mu);
+  while (state.KeepRunning()) {
+    grpc_pollset_worker* worker;
+    GRPC_ERROR_UNREF(grpc_pollset_work(&exec_ctx, ps, &worker, now, deadline));
+  }
+  grpc_closure shutdown_ps_closure;
+  grpc_closure_init(&shutdown_ps_closure, shutdown_ps, ps,
+                    grpc_schedule_on_exec_ctx);
+  grpc_pollset_shutdown(&exec_ctx, ps, &shutdown_ps_closure);
+  gpr_mu_unlock(mu);
+  grpc_exec_ctx_finish(&exec_ctx);
+  gpr_free(ps);
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_PollEmptyPollset);
+
+class Closure : public grpc_closure {
+ public:
+  virtual ~Closure() {}
+};
+
+template <class F>
+Closure* MakeClosure(F f, grpc_closure_scheduler* scheduler) {
+  struct C : public Closure {
+    C(F f, grpc_closure_scheduler* scheduler) : f_(f) {
+      grpc_closure_init(this, C::cbfn, this, scheduler);
+    }
+    static void cbfn(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
+      C* p = static_cast<C*>(arg);
+      p->f_();
+    }
+    F f_;
+  };
+  return new C(f, scheduler);
+}
+
+#ifdef GRPC_LINUX_MULTIPOLL_WITH_EPOLL
+static void BM_SingleThreadPollOneFd_SpeedOfLight(benchmark::State& state) {
+  // equivalent to BM_PollEmptyPollset, but just use the OS primitives to guage
+  // what the speed of light would be if we abstracted perfectly
+  TrackCounters track_counters;
+  int epfd = epoll_create1(0);
+  GPR_ASSERT(epfd != -1);
+  epoll_event ev[100];
+  int fd = eventfd(0, EFD_NONBLOCK);
+  ev[0].events = EPOLLIN;
+  epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev[0]);
+  while (state.KeepRunning()) {
+    int err;
+    do {
+      err = eventfd_write(fd, 1);
+    } while (err < 0 && errno == EINTR);
+    GPR_ASSERT(err == 0);
+    do {
+      err = epoll_wait(epfd, ev, GPR_ARRAY_SIZE(ev), 0);
+    } while (err < 0 && errno == EINTR);
+    GPR_ASSERT(err == 1);
+    eventfd_t value;
+    do {
+      err = eventfd_read(fd, &value);
+    } while (err < 0 && errno == EINTR);
+    GPR_ASSERT(err == 0);
+  }
+  close(fd);
+  close(epfd);
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_SingleThreadPollOneFd_SpeedOfLight);
+#endif
+
+static void BM_SingleThreadPollOneFd(benchmark::State& state) {
+  TrackCounters track_counters;
+  size_t ps_sz = grpc_pollset_size();
+  grpc_pollset* ps = static_cast<grpc_pollset*>(gpr_zalloc(ps_sz));
+  gpr_mu* mu;
+  grpc_pollset_init(ps, &mu);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  gpr_timespec now = gpr_time_0(GPR_CLOCK_MONOTONIC);
+  gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
+  grpc_wakeup_fd wakeup_fd;
+  GRPC_ERROR_UNREF(grpc_wakeup_fd_init(&wakeup_fd));
+  grpc_fd* wakeup = grpc_fd_create(wakeup_fd.read_fd, "wakeup_read");
+  grpc_pollset_add_fd(&exec_ctx, ps, wakeup);
+  bool done = false;
+  Closure* continue_closure = MakeClosure(
+      [&]() {
+        GRPC_ERROR_UNREF(grpc_wakeup_fd_consume_wakeup(&wakeup_fd));
+        if (!state.KeepRunning()) {
+          done = true;
+          return;
+        }
+        GRPC_ERROR_UNREF(grpc_wakeup_fd_wakeup(&wakeup_fd));
+        grpc_fd_notify_on_read(&exec_ctx, wakeup, continue_closure);
+      },
+      grpc_schedule_on_exec_ctx);
+  GRPC_ERROR_UNREF(grpc_wakeup_fd_wakeup(&wakeup_fd));
+  grpc_fd_notify_on_read(&exec_ctx, wakeup, continue_closure);
+  gpr_mu_lock(mu);
+  while (!done) {
+    grpc_pollset_worker* worker;
+    GRPC_ERROR_UNREF(grpc_pollset_work(&exec_ctx, ps, &worker, now, deadline));
+  }
+  grpc_fd_orphan(&exec_ctx, wakeup, NULL, NULL, "done");
+  wakeup_fd.read_fd = 0;
+  grpc_closure shutdown_ps_closure;
+  grpc_closure_init(&shutdown_ps_closure, shutdown_ps, ps,
+                    grpc_schedule_on_exec_ctx);
+  grpc_pollset_shutdown(&exec_ctx, ps, &shutdown_ps_closure);
+  gpr_mu_unlock(mu);
+  grpc_exec_ctx_finish(&exec_ctx);
+  grpc_wakeup_fd_destroy(&wakeup_fd);
+  gpr_free(ps);
+  track_counters.Finish(state);
+  delete continue_closure;
+}
+BENCHMARK(BM_SingleThreadPollOneFd);
+
+BENCHMARK_MAIN();
diff --git a/test/cpp/microbenchmarks/fullstack_context_mutators.h b/test/cpp/microbenchmarks/fullstack_context_mutators.h
new file mode 100644
index 0000000000000000000000000000000000000000..676f9aa1cc6b723f06da24f6063dde426f522ee0
--- /dev/null
+++ b/test/cpp/microbenchmarks/fullstack_context_mutators.h
@@ -0,0 +1,158 @@
+/*
+ *
+ * Copyright 2017, 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 TEST_CPP_MICROBENCHMARKS_FULLSTACK_CONTEXT_MUTATORS_H
+#define TEST_CPP_MICROBENCHMARKS_FULLSTACK_CONTEXT_MUTATORS_H
+
+#include <grpc++/channel.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/security/credentials.h>
+#include <grpc++/security/server_credentials.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc/support/log.h>
+
+#include "test/cpp/microbenchmarks/helpers.h"
+
+namespace grpc {
+namespace testing {
+
+/*******************************************************************************
+ * CONTEXT MUTATORS
+ */
+
+static const int kPregenerateKeyCount = 100000;
+
+template <class F>
+auto MakeVector(size_t length, F f) -> std::vector<decltype(f())> {
+  std::vector<decltype(f())> out;
+  out.reserve(length);
+  for (size_t i = 0; i < length; i++) {
+    out.push_back(f());
+  }
+  return out;
+}
+
+class NoOpMutator {
+ public:
+  template <class ContextType>
+  NoOpMutator(ContextType* context) {}
+};
+
+template <int length>
+class RandomBinaryMetadata {
+ public:
+  static const grpc::string& Key() { return kKey; }
+
+  static const grpc::string& Value() {
+    return kValues[rand() % kValues.size()];
+  }
+
+ private:
+  static const grpc::string kKey;
+  static const std::vector<grpc::string> kValues;
+
+  static grpc::string GenerateOneString() {
+    grpc::string s;
+    s.reserve(length + 1);
+    for (int i = 0; i < length; i++) {
+      s += (char)rand();
+    }
+    return s;
+  }
+};
+
+template <int length>
+class RandomAsciiMetadata {
+ public:
+  static const grpc::string& Key() { return kKey; }
+
+  static const grpc::string& Value() {
+    return kValues[rand() % kValues.size()];
+  }
+
+ private:
+  static const grpc::string kKey;
+  static const std::vector<grpc::string> kValues;
+
+  static grpc::string GenerateOneString() {
+    grpc::string s;
+    s.reserve(length + 1);
+    for (int i = 0; i < length; i++) {
+      s += (char)(rand() % 26 + 'a');
+    }
+    return s;
+  }
+};
+
+template <class Generator, int kNumKeys>
+class Client_AddMetadata : public NoOpMutator {
+ public:
+  Client_AddMetadata(ClientContext* context) : NoOpMutator(context) {
+    for (int i = 0; i < kNumKeys; i++) {
+      context->AddMetadata(Generator::Key(), Generator::Value());
+    }
+  }
+};
+
+template <class Generator, int kNumKeys>
+class Server_AddInitialMetadata : public NoOpMutator {
+ public:
+  Server_AddInitialMetadata(ServerContext* context) : NoOpMutator(context) {
+    for (int i = 0; i < kNumKeys; i++) {
+      context->AddInitialMetadata(Generator::Key(), Generator::Value());
+    }
+  }
+};
+
+// static initialization
+
+template <int length>
+const grpc::string RandomBinaryMetadata<length>::kKey = "foo-bin";
+
+template <int length>
+const std::vector<grpc::string> RandomBinaryMetadata<length>::kValues =
+    MakeVector(kPregenerateKeyCount, GenerateOneString);
+
+template <int length>
+const grpc::string RandomAsciiMetadata<length>::kKey = "foo";
+
+template <int length>
+const std::vector<grpc::string> RandomAsciiMetadata<length>::kValues =
+    MakeVector(kPregenerateKeyCount, GenerateOneString);
+
+}  // namespace testing
+}  // namespace grpc
+
+#endif
diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h
new file mode 100644
index 0000000000000000000000000000000000000000..98aca1c34652bcf43b143405b2f5e62e7fd52e0b
--- /dev/null
+++ b/test/cpp/microbenchmarks/fullstack_fixtures.h
@@ -0,0 +1,291 @@
+/*
+ *
+ * Copyright 2017, 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 TEST_CPP_MICROBENCHMARKS_FULLSTACK_FIXTURES_H
+#define TEST_CPP_MICROBENCHMARKS_FULLSTACK_FIXTURES_H
+
+#include <grpc++/channel.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/security/credentials.h>
+#include <grpc++/security/server_credentials.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc/support/log.h>
+
+extern "C" {
+#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/iomgr/endpoint.h"
+#include "src/core/lib/iomgr/endpoint_pair.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/iomgr/tcp_posix.h"
+#include "src/core/lib/surface/channel.h"
+#include "src/core/lib/surface/completion_queue.h"
+#include "src/core/lib/surface/server.h"
+#include "test/core/util/passthru_endpoint.h"
+#include "test/core/util/port.h"
+}
+
+#include "test/cpp/microbenchmarks/helpers.h"
+
+namespace grpc {
+namespace testing {
+
+class FixtureConfiguration {
+ public:
+  virtual void ApplyCommonChannelArguments(ChannelArguments* c) const {
+    c->SetInt(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, INT_MAX);
+    c->SetInt(GRPC_ARG_MAX_SEND_MESSAGE_LENGTH, INT_MAX);
+  }
+
+  virtual void ApplyCommonServerBuilderConfig(ServerBuilder* b) const {
+    b->SetMaxReceiveMessageSize(INT_MAX);
+    b->SetMaxSendMessageSize(INT_MAX);
+  }
+};
+
+class BaseFixture : public TrackCounters {};
+
+class FullstackFixture : public BaseFixture {
+ public:
+  FullstackFixture(Service* service, const FixtureConfiguration& config,
+                   const grpc::string& address) {
+    ServerBuilder b;
+    b.AddListeningPort(address, InsecureServerCredentials());
+    cq_ = b.AddCompletionQueue(true);
+    b.RegisterService(service);
+    config.ApplyCommonServerBuilderConfig(&b);
+    server_ = b.BuildAndStart();
+    ChannelArguments args;
+    config.ApplyCommonChannelArguments(&args);
+    channel_ = CreateCustomChannel(address, InsecureChannelCredentials(), args);
+  }
+
+  virtual ~FullstackFixture() {
+    server_->Shutdown();
+    cq_->Shutdown();
+    void* tag;
+    bool ok;
+    while (cq_->Next(&tag, &ok)) {
+    }
+  }
+
+  ServerCompletionQueue* cq() { return cq_.get(); }
+  std::shared_ptr<Channel> channel() { return channel_; }
+
+ private:
+  std::unique_ptr<Server> server_;
+  std::unique_ptr<ServerCompletionQueue> cq_;
+  std::shared_ptr<Channel> channel_;
+};
+
+class TCP : public FullstackFixture {
+ public:
+  TCP(Service* service, const FixtureConfiguration& fixture_configuration =
+                            FixtureConfiguration())
+      : FullstackFixture(service, fixture_configuration, MakeAddress(&port_)) {}
+
+  ~TCP() { grpc_recycle_unused_port(port_); }
+
+ private:
+  int port_;
+
+  static grpc::string MakeAddress(int* port) {
+    *port = grpc_pick_unused_port_or_die();
+    std::stringstream addr;
+    addr << "localhost:" << *port;
+    return addr.str();
+  }
+};
+
+class UDS : public FullstackFixture {
+ public:
+  UDS(Service* service, const FixtureConfiguration& fixture_configuration =
+                            FixtureConfiguration())
+      : FullstackFixture(service, fixture_configuration, MakeAddress(&port_)) {}
+
+  ~UDS() { grpc_recycle_unused_port(port_); }
+
+ private:
+  int port_;
+
+  static grpc::string MakeAddress(int* port) {
+    *port = grpc_pick_unused_port_or_die();  // just for a unique id - not a
+                                             // real port
+    std::stringstream addr;
+    addr << "unix:/tmp/bm_fullstack." << *port;
+    return addr.str();
+  }
+};
+
+class EndpointPairFixture : public BaseFixture {
+ public:
+  EndpointPairFixture(Service* service, grpc_endpoint_pair endpoints,
+                      const FixtureConfiguration& fixture_configuration)
+      : endpoint_pair_(endpoints) {
+    ServerBuilder b;
+    cq_ = b.AddCompletionQueue(true);
+    b.RegisterService(service);
+    fixture_configuration.ApplyCommonServerBuilderConfig(&b);
+    server_ = b.BuildAndStart();
+
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
+    /* add server endpoint to server_
+     * */
+    {
+      const grpc_channel_args* server_args =
+          grpc_server_get_channel_args(server_->c_server());
+      server_transport_ = grpc_create_chttp2_transport(
+          &exec_ctx, server_args, endpoints.server, 0 /* is_client */);
+
+      grpc_pollset** pollsets;
+      size_t num_pollsets = 0;
+      grpc_server_get_pollsets(server_->c_server(), &pollsets, &num_pollsets);
+
+      for (size_t i = 0; i < num_pollsets; i++) {
+        grpc_endpoint_add_to_pollset(&exec_ctx, endpoints.server, pollsets[i]);
+      }
+
+      grpc_server_setup_transport(&exec_ctx, server_->c_server(),
+                                  server_transport_, NULL, server_args);
+      grpc_chttp2_transport_start_reading(&exec_ctx, server_transport_, NULL);
+    }
+
+    /* create channel */
+    {
+      ChannelArguments args;
+      args.SetString(GRPC_ARG_DEFAULT_AUTHORITY, "test.authority");
+      fixture_configuration.ApplyCommonChannelArguments(&args);
+
+      grpc_channel_args c_args = args.c_channel_args();
+      client_transport_ =
+          grpc_create_chttp2_transport(&exec_ctx, &c_args, endpoints.client, 1);
+      GPR_ASSERT(client_transport_);
+      grpc_channel* channel =
+          grpc_channel_create(&exec_ctx, "target", &c_args,
+                              GRPC_CLIENT_DIRECT_CHANNEL, client_transport_);
+      grpc_chttp2_transport_start_reading(&exec_ctx, client_transport_, NULL);
+
+      channel_ = CreateChannelInternal("", channel);
+    }
+
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
+
+  virtual ~EndpointPairFixture() {
+    server_->Shutdown();
+    cq_->Shutdown();
+    void* tag;
+    bool ok;
+    while (cq_->Next(&tag, &ok)) {
+    }
+  }
+
+  ServerCompletionQueue* cq() { return cq_.get(); }
+  std::shared_ptr<Channel> channel() { return channel_; }
+
+ protected:
+  grpc_endpoint_pair endpoint_pair_;
+  grpc_transport* client_transport_;
+  grpc_transport* server_transport_;
+
+ private:
+  std::unique_ptr<Server> server_;
+  std::unique_ptr<ServerCompletionQueue> cq_;
+  std::shared_ptr<Channel> channel_;
+};
+
+class SockPair : public EndpointPairFixture {
+ public:
+  SockPair(Service* service, const FixtureConfiguration& fixture_configuration =
+                                 FixtureConfiguration())
+      : EndpointPairFixture(service,
+                            grpc_iomgr_create_endpoint_pair("test", NULL),
+                            fixture_configuration) {}
+};
+
+class InProcessCHTTP2 : public EndpointPairFixture {
+ public:
+  InProcessCHTTP2(Service* service,
+                  const FixtureConfiguration& fixture_configuration =
+                      FixtureConfiguration())
+      : EndpointPairFixture(service, MakeEndpoints(), fixture_configuration) {}
+
+  void AddToLabel(std::ostream& out, benchmark::State& state) {
+    EndpointPairFixture::AddToLabel(out, state);
+    out << " writes/iter:"
+        << ((double)stats_.num_writes / (double)state.iterations());
+  }
+
+ private:
+  grpc_passthru_endpoint_stats stats_;
+
+  grpc_endpoint_pair MakeEndpoints() {
+    grpc_endpoint_pair p;
+    grpc_passthru_endpoint_create(&p.client, &p.server, Library::get().rq(),
+                                  &stats_);
+    return p;
+  }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Minimal stack fixtures
+
+class MinStackConfiguration : public FixtureConfiguration {
+  void ApplyCommonChannelArguments(ChannelArguments* a) const override {
+    a->SetInt(GRPC_ARG_MINIMAL_STACK, 1);
+    FixtureConfiguration::ApplyCommonChannelArguments(a);
+  }
+
+  void ApplyCommonServerBuilderConfig(ServerBuilder* b) const override {
+    b->AddChannelArgument(GRPC_ARG_MINIMAL_STACK, 1);
+    FixtureConfiguration::ApplyCommonServerBuilderConfig(b);
+  }
+};
+
+template <class Base>
+class MinStackize : public Base {
+ public:
+  MinStackize(Service* service) : Base(service, MinStackConfiguration()) {}
+};
+
+typedef MinStackize<TCP> MinTCP;
+typedef MinStackize<UDS> MinUDS;
+typedef MinStackize<SockPair> MinSockPair;
+typedef MinStackize<InProcessCHTTP2> MinInProcessCHTTP2;
+
+}  // namespace testing
+}  // namespace grpc
+
+#endif
diff --git a/test/cpp/microbenchmarks/helpers.cc b/test/cpp/microbenchmarks/helpers.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6550742453a77674ec0fe74cb5c1049573846b5c
--- /dev/null
+++ b/test/cpp/microbenchmarks/helpers.cc
@@ -0,0 +1,69 @@
+/*
+ *
+ * Copyright 2017, 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/microbenchmarks/helpers.h"
+
+void TrackCounters::Finish(benchmark::State &state) {
+  std::ostringstream out;
+  AddToLabel(out, state);
+  auto label = out.str();
+  if (label.length() && label[0] == ' ') {
+    label = label.substr(1);
+  }
+  state.SetLabel(label);
+}
+
+void TrackCounters::AddToLabel(std::ostream &out, benchmark::State &state) {
+#ifdef GPR_LOW_LEVEL_COUNTERS
+  grpc_memory_counters counters_at_end = grpc_memory_counters_snapshot();
+  out << " locks/iter:" << ((double)(gpr_atm_no_barrier_load(&gpr_mu_locks) -
+                                     mu_locks_at_start_) /
+                            (double)state.iterations())
+      << " atm_cas/iter:"
+      << ((double)(gpr_atm_no_barrier_load(&gpr_counter_atm_cas) -
+                   atm_cas_at_start_) /
+          (double)state.iterations())
+      << " atm_add/iter:"
+      << ((double)(gpr_atm_no_barrier_load(&gpr_counter_atm_add) -
+                   atm_add_at_start_) /
+          (double)state.iterations())
+      << " nows/iter:"
+      << ((double)(gpr_atm_no_barrier_load(&gpr_now_call_count) -
+                   now_calls_at_start_) /
+          (double)state.iterations())
+      << " allocs/iter:"
+      << ((double)(counters_at_end.total_allocs_absolute -
+                   counters_at_start_.total_allocs_absolute) /
+          (double)state.iterations());
+#endif
+}
diff --git a/test/cpp/microbenchmarks/helpers.h b/test/cpp/microbenchmarks/helpers.h
new file mode 100644
index 0000000000000000000000000000000000000000..7360a1c9f267deffeceb2581a67845a18a673f87
--- /dev/null
+++ b/test/cpp/microbenchmarks/helpers.h
@@ -0,0 +1,96 @@
+/*
+ *
+ * Copyright 2017, 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 TEST_CPP_MICROBENCHMARKS_COUNTERS_H
+#define TEST_CPP_MICROBENCHMARKS_COUNTERS_H
+
+#include <sstream>
+
+extern "C" {
+#include <grpc/support/port_platform.h>
+#include "test/core/util/memory_counters.h"
+}
+
+#include <benchmark/benchmark.h>
+#include <grpc++/impl/grpc_library.h>
+
+class Library {
+ public:
+  static Library& get() {
+    static Library lib;
+    return lib;
+  }
+
+  grpc_resource_quota* rq() { return rq_; }
+
+ private:
+  Library() {
+#ifdef GPR_LOW_LEVEL_COUNTERS
+    grpc_memory_counters_init();
+#endif
+    init_lib_.init();
+    rq_ = grpc_resource_quota_create("bm");
+  }
+
+  ~Library() { init_lib_.shutdown(); }
+
+  grpc::internal::GrpcLibrary init_lib_;
+  grpc_resource_quota* rq_;
+};
+
+#ifdef GPR_LOW_LEVEL_COUNTERS
+extern "C" gpr_atm gpr_mu_locks;
+extern "C" gpr_atm gpr_counter_atm_cas;
+extern "C" gpr_atm gpr_counter_atm_add;
+extern "C" gpr_atm gpr_now_call_count;
+#endif
+
+class TrackCounters {
+ public:
+  virtual void Finish(benchmark::State& state);
+  virtual void AddToLabel(std::ostream& out, benchmark::State& state);
+
+ private:
+#ifdef GPR_LOW_LEVEL_COUNTERS
+  const size_t mu_locks_at_start_ = gpr_atm_no_barrier_load(&gpr_mu_locks);
+  const size_t atm_cas_at_start_ =
+      gpr_atm_no_barrier_load(&gpr_counter_atm_cas);
+  const size_t atm_add_at_start_ =
+      gpr_atm_no_barrier_load(&gpr_counter_atm_add);
+  const size_t now_calls_at_start_ =
+      gpr_atm_no_barrier_load(&gpr_now_call_count);
+  grpc_memory_counters counters_at_start_ = grpc_memory_counters_snapshot();
+#endif
+};
+
+#endif
diff --git a/test/cpp/microbenchmarks/noop-benchmark.cc b/test/cpp/microbenchmarks/noop-benchmark.cc
index 99fa6d5f6e539c19bf7e6c7f70642666c55f92eb..7372ad04f25302701b03823400373ada6eea9902 100644
--- a/test/cpp/microbenchmarks/noop-benchmark.cc
+++ b/test/cpp/microbenchmarks/noop-benchmark.cc
@@ -34,7 +34,7 @@
 /* This benchmark exists to ensure that the benchmark integration is
  * working */
 
-#include "third_party/benchmark/include/benchmark/benchmark.h"
+#include <benchmark/benchmark.h>
 
 static void BM_NoOp(benchmark::State& state) {
   while (state.KeepRunning()) {
diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD
new file mode 100644
index 0000000000000000000000000000000000000000..6492b63ec3023a826a9bc6102086bd2147e8515b
--- /dev/null
+++ b/test/cpp/qps/BUILD
@@ -0,0 +1,194 @@
+# Copyright 2017, 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.
+
+licenses(["notice"])  # 3-clause BSD
+
+cc_library(
+    name = "parse_json",
+    srcs = ["parse_json.cc"],
+    hdrs = ["parse_json.h"],
+    deps = ["//:grpc++"],
+)
+
+cc_library(
+    name = "qps_worker_impl",
+    srcs = [
+        "client_async.cc",
+        "client_sync.cc",
+        "qps_worker.cc",
+        "server_async.cc",
+        "server_sync.cc",
+    ],
+    hdrs = [
+        "client.h",
+        "qps_worker.h",
+        "server.h",
+    ],
+    deps = [
+        ":histogram",
+        ":interarrival",
+        ":usage_timer",
+        "//:grpc",
+        "//:grpc++",
+        "//external:gtest",
+        "//src/proto/grpc/testing:control_proto",
+        "//src/proto/grpc/testing:payloads_proto",
+        "//src/proto/grpc/testing:services_proto",
+        "//test/core/end2end:ssl_test_data",
+        "//test/core/util:gpr_test_util",
+        "//test/core/util:grpc_test_util",
+        "//test/cpp/util:test_util",
+    ],
+)
+
+cc_library(
+    name = "driver_impl",
+    srcs = [
+        "driver.cc",
+        "report.cc",
+    ],
+    hdrs = [
+        "driver.h",
+        "report.h",
+    ],
+    deps = [
+        ":histogram",
+        ":parse_json",
+        ":qps_worker_impl",
+        "//:grpc++",
+        "//src/proto/grpc/testing:control_proto",
+        "//src/proto/grpc/testing:messages_proto",
+        "//src/proto/grpc/testing:services_proto",
+        "//test/core/util:gpr_test_util",
+        "//test/core/util:grpc_test_util",
+    ],
+)
+
+cc_library(
+    name = "benchmark_config",
+    srcs = [
+        "benchmark_config.cc",
+    ],
+    hdrs = [
+        "benchmark_config.h",
+    ],
+    deps = [
+        ":driver_impl",
+        ":histogram",
+        "//:grpc++",
+        "//external:gflags",
+        "//src/proto/grpc/testing:control_proto",
+    ],
+)
+
+cc_library(
+    name = "histogram",
+    hdrs = [
+        "histogram.h",
+        "stats.h",
+    ],
+    deps = ["//:gpr"],
+)
+
+cc_library(
+    name = "interarrival",
+    hdrs = ["interarrival.h"],
+    deps = ["//:grpc++"],
+)
+
+cc_binary(
+    name = "json_run_localhost",
+    srcs = ["json_run_localhost.cc"],
+    deps = [
+        "//:gpr",
+        "//test/core/util:gpr_test_util",
+        "//test/core/util:grpc_test_util",
+        "//test/cpp/util:test_util",
+    ],
+)
+
+cc_test(
+    name = "qps_interarrival_test",
+    srcs = ["qps_interarrival_test.cc"],
+    deps = [
+        ":histogram",
+        ":interarrival",
+    ],
+)
+
+cc_binary(
+    name = "qps_json_driver",
+    srcs = ["qps_json_driver.cc"],
+    deps = [
+        ":benchmark_config",
+        ":driver_impl",
+        "//:grpc++",
+        "//external:gflags",
+    ],
+)
+
+cc_test(
+    name = "qps_openloop_test",
+    srcs = ["qps_openloop_test.cc"],
+    deps = [
+        ":benchmark_config",
+        ":driver_impl",
+        ":qps_worker_impl",
+    ],
+)
+
+cc_test(
+    name = "secure_sync_unary_ping_pong_test",
+    srcs = ["secure_sync_unary_ping_pong_test.cc"],
+    deps = [
+        ":benchmark_config",
+        ":driver_impl",
+        "//:grpc++",
+    ],
+)
+
+cc_library(
+    name = "usage_timer",
+    srcs = ["usage_timer.cc"],
+    hdrs = ["usage_timer.h"],
+    deps = ["//:gpr"],
+)
+
+cc_binary(
+    name = "qps_worker",
+    srcs = ["worker.cc"],
+    deps = [
+        ":qps_worker_impl",
+        "//:grpc++",
+        "//test/core/util:gpr_test_util",
+        "//test/core/util:grpc_test_util",
+        "//test/cpp/util:test_config",
+        "//test/cpp/util:test_util",
+    ],
+)
diff --git a/test/cpp/util/benchmark_config.cc b/test/cpp/qps/benchmark_config.cc
similarity index 82%
rename from test/cpp/util/benchmark_config.cc
rename to test/cpp/qps/benchmark_config.cc
index 6fc864069ef05bf84c96ecd7bb275cb3e09c20dc..d33f3e9ae10f909e47bf1fa82df2c5bf9a383ba8 100644
--- a/test/cpp/util/benchmark_config.cc
+++ b/test/cpp/qps/benchmark_config.cc
@@ -31,8 +31,11 @@
  *
  */
 
-#include "test/cpp/util/benchmark_config.h"
+#include "test/cpp/qps/benchmark_config.h"
 #include <gflags/gflags.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/security/credentials.h>
+#include <grpc/support/log.h>
 
 DEFINE_bool(enable_log_reporter, true,
             "Enable reporting of benchmark results through GprLog");
@@ -51,6 +54,11 @@ DEFINE_string(server_address, "localhost:50052",
 
 DEFINE_string(tag, "", "Optional tag for the test");
 
+DEFINE_string(rpc_reporter_server_address, "",
+              "Server address for rpc reporter to send results to");
+
+DEFINE_bool(enable_rpc_reporter, false, "Enable use of RPC reporter");
+
 // In some distros, gflags is in the namespace google, and in some others,
 // in gflags. This hack is enabling us to find both.
 namespace google {}
@@ -75,6 +83,13 @@ static std::shared_ptr<Reporter> InitBenchmarkReporters() {
     composite_reporter->add(std::unique_ptr<Reporter>(
         new JsonReporter("JsonReporter", FLAGS_scenario_result_file)));
   }
+  if (FLAGS_enable_rpc_reporter) {
+    GPR_ASSERT(!FLAGS_rpc_reporter_server_address.empty());
+    composite_reporter->add(std::unique_ptr<Reporter>(new RpcReporter(
+        "RpcReporter",
+        grpc::CreateChannel(FLAGS_rpc_reporter_server_address,
+                            grpc::InsecureChannelCredentials()))));
+  }
 
   return std::shared_ptr<Reporter>(composite_reporter);
 }
diff --git a/test/cpp/util/benchmark_config.h b/test/cpp/qps/benchmark_config.h
similarity index 100%
rename from test/cpp/util/benchmark_config.h
rename to test/cpp/qps/benchmark_config.h
diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h
index baa9304cc2d47e5df91f2fcef62a90c3622279d7..25a19a5a740ddef9dbe0717a428918bb10589b20 100644
--- a/test/cpp/qps/client.h
+++ b/test/cpp/qps/client.h
@@ -46,7 +46,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 
-#include "src/proto/grpc/testing/payloads.grpc.pb.h"
+#include "src/proto/grpc/testing/payloads.pb.h"
 #include "src/proto/grpc/testing/services.grpc.pb.h"
 
 #include "test/cpp/qps/histogram.h"
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index 4032039ea1064d5919295985c2933b4df28de2c4..29a79e7343dab3950a6e755322954a8f8e644bfb 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -63,13 +63,13 @@ class ClientRpcContext {
   virtual ~ClientRpcContext() {}
   // next state, return false if done. Collect stats when appropriate
   virtual bool RunNextState(bool, HistogramEntry* entry) = 0;
-  virtual ClientRpcContext* StartNewClone() = 0;
+  virtual void StartNewClone(CompletionQueue* cq) = 0;
   static void* tag(ClientRpcContext* c) { return reinterpret_cast<void*>(c); }
   static ClientRpcContext* detag(void* t) {
     return reinterpret_cast<ClientRpcContext*>(t);
   }
 
-  virtual void Start(CompletionQueue* cq) = 0;
+  virtual void Start(CompletionQueue* cq, const ClientConfig& config) = 0;
 };
 
 template <class RequestType, class ResponseType>
@@ -94,25 +94,22 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
         next_issue_(next_issue),
         start_req_(start_req) {}
   ~ClientRpcContextUnaryImpl() override {}
-  void Start(CompletionQueue* cq) override {
-    cq_ = cq;
-    if (!next_issue_) {  // ready to issue
-      RunNextState(true, nullptr);
-    } else {  // wait for the issue time
-      alarm_.reset(new Alarm(cq_, next_issue_(), ClientRpcContext::tag(this)));
-    }
+  void Start(CompletionQueue* cq, const ClientConfig& config) override {
+    StartInternal(cq);
   }
   bool RunNextState(bool ok, HistogramEntry* entry) override {
     switch (next_state_) {
       case State::READY:
         start_ = UsageTimer::Now();
         response_reader_ = start_req_(stub_, &context_, req_, cq_);
+        next_state_ = State::RESP_DONE;
         response_reader_->Finish(&response_, &status_,
                                  ClientRpcContext::tag(this));
-        next_state_ = State::RESP_DONE;
         return true;
       case State::RESP_DONE:
-        entry->set_value((UsageTimer::Now() - start_) * 1e9);
+        if (status_.ok()) {
+          entry->set_value((UsageTimer::Now() - start_) * 1e9);
+        }
         callback_(status_, &response_, entry);
         next_state_ = State::INVALID;
         return false;
@@ -121,9 +118,10 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
         return false;
     }
   }
-  ClientRpcContext* StartNewClone() override {
-    return new ClientRpcContextUnaryImpl(stub_, req_, next_issue_, start_req_,
-                                         callback_);
+  void StartNewClone(CompletionQueue* cq) override {
+    auto* clone = new ClientRpcContextUnaryImpl(stub_, req_, next_issue_,
+                                                start_req_, callback_);
+    clone->StartInternal(cq);
   }
 
  private:
@@ -145,6 +143,15 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
   double start_;
   std::unique_ptr<grpc::ClientAsyncResponseReader<ResponseType>>
       response_reader_;
+
+  void StartInternal(CompletionQueue* cq) {
+    cq_ = cq;
+    if (!next_issue_) {  // ready to issue
+      RunNextState(true, nullptr);
+    } else {  // wait for the issue time
+      alarm_.reset(new Alarm(cq_, next_issue_(), ClientRpcContext::tag(this)));
+    }
+  }
 };
 
 typedef std::forward_list<ClientRpcContext*> context_list;
@@ -183,7 +190,7 @@ class AsyncClient : public ClientImpl<StubType, RequestType> {
         auto* cq = cli_cqs_[t].get();
         auto ctx =
             setup_ctx(channels_[ch].get_stub(), next_issuers_[t], request_);
-        ctx->Start(cq);
+        ctx->Start(cq, config);
       }
       t = (t + 1) % cli_cqs_.size();
     }
@@ -246,8 +253,7 @@ class AsyncClient : public ClientImpl<StubType, RequestType> {
         } else if (!ctx->RunNextState(ok, entry)) {
           // The RPC and callback are done, so clone the ctx
           // and kickstart the new one
-          auto clone = ctx->StartNewClone();
-          clone->Start(cli_cqs_[thread_idx].get());
+          ctx->StartNewClone(cli_cqs_[thread_idx].get());
           // delete the old version
           delete ctx;
         }
@@ -328,10 +334,8 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext {
         next_issue_(next_issue),
         start_req_(start_req) {}
   ~ClientRpcContextStreamingImpl() override {}
-  void Start(CompletionQueue* cq) override {
-    cq_ = cq;
-    stream_ = start_req_(stub_, &context_, cq, ClientRpcContext::tag(this));
-    next_state_ = State::STREAM_IDLE;
+  void Start(CompletionQueue* cq, const ClientConfig& config) override {
+    StartInternal(cq, config.messages_per_stream());
   }
   bool RunNextState(bool ok, HistogramEntry* entry) override {
     while (true) {
@@ -344,9 +348,9 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext {
           }
           break;  // loop around, don't return
         case State::WAIT:
+          next_state_ = State::READY_TO_WRITE;
           alarm_.reset(
               new Alarm(cq_, next_issue_(), ClientRpcContext::tag(this)));
-          next_state_ = State::READY_TO_WRITE;
           return true;
         case State::READY_TO_WRITE:
           if (!ok) {
@@ -367,17 +371,32 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext {
         case State::READ_DONE:
           entry->set_value((UsageTimer::Now() - start_) * 1e9);
           callback_(status_, &response_);
+          if ((messages_per_stream_ != 0) &&
+              (++messages_issued_ >= messages_per_stream_)) {
+            next_state_ = State::WRITES_DONE_DONE;
+            stream_->WritesDone(ClientRpcContext::tag(this));
+            return true;
+          }
           next_state_ = State::STREAM_IDLE;
           break;  // loop around
+        case State::WRITES_DONE_DONE:
+          next_state_ = State::FINISH_DONE;
+          stream_->Finish(&status_, ClientRpcContext::tag(this));
+          return true;
+        case State::FINISH_DONE:
+          next_state_ = State::INVALID;
+          return false;
+          break;
         default:
           GPR_ASSERT(false);
           return false;
       }
     }
   }
-  ClientRpcContext* StartNewClone() override {
-    return new ClientRpcContextStreamingImpl(stub_, req_, next_issue_,
-                                             start_req_, callback_);
+  void StartNewClone(CompletionQueue* cq) override {
+    auto* clone = new ClientRpcContextStreamingImpl(stub_, req_, next_issue_,
+                                                    start_req_, callback_);
+    clone->StartInternal(cq, messages_per_stream_);
   }
 
  private:
@@ -393,7 +412,9 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext {
     WAIT,
     READY_TO_WRITE,
     WRITE_DONE,
-    READ_DONE
+    READ_DONE,
+    WRITES_DONE_DONE,
+    FINISH_DONE
   };
   State next_state_;
   std::function<void(grpc::Status, ResponseType*)> callback_;
@@ -406,6 +427,18 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext {
   double start_;
   std::unique_ptr<grpc::ClientAsyncReaderWriter<RequestType, ResponseType>>
       stream_;
+
+  // Allow a limit on number of messages in a stream
+  int messages_per_stream_;
+  int messages_issued_;
+
+  void StartInternal(CompletionQueue* cq, int messages_per_stream) {
+    cq_ = cq;
+    next_state_ = State::STREAM_IDLE;
+    stream_ = start_req_(stub_, &context_, cq, ClientRpcContext::tag(this));
+    messages_per_stream_ = messages_per_stream;
+    messages_issued_ = 0;
+  }
 };
 
 class AsyncStreamingClient final
@@ -457,13 +490,8 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext {
         next_issue_(next_issue),
         start_req_(start_req) {}
   ~ClientRpcContextGenericStreamingImpl() override {}
-  void Start(CompletionQueue* cq) override {
-    cq_ = cq;
-    const grpc::string kMethodName(
-        "/grpc.testing.BenchmarkService/StreamingCall");
-    stream_ = start_req_(stub_, &context_, kMethodName, cq,
-                         ClientRpcContext::tag(this));
-    next_state_ = State::STREAM_IDLE;
+  void Start(CompletionQueue* cq, const ClientConfig& config) override {
+    StartInternal(cq, config.messages_per_stream());
   }
   bool RunNextState(bool ok, HistogramEntry* entry) override {
     while (true) {
@@ -476,9 +504,9 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext {
           }
           break;  // loop around, don't return
         case State::WAIT:
+          next_state_ = State::READY_TO_WRITE;
           alarm_.reset(
               new Alarm(cq_, next_issue_(), ClientRpcContext::tag(this)));
-          next_state_ = State::READY_TO_WRITE;
           return true;
         case State::READY_TO_WRITE:
           if (!ok) {
@@ -499,17 +527,32 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext {
         case State::READ_DONE:
           entry->set_value((UsageTimer::Now() - start_) * 1e9);
           callback_(status_, &response_);
+          if ((messages_per_stream_ != 0) &&
+              (++messages_issued_ >= messages_per_stream_)) {
+            next_state_ = State::WRITES_DONE_DONE;
+            stream_->WritesDone(ClientRpcContext::tag(this));
+            return true;
+          }
           next_state_ = State::STREAM_IDLE;
           break;  // loop around
+        case State::WRITES_DONE_DONE:
+          next_state_ = State::FINISH_DONE;
+          stream_->Finish(&status_, ClientRpcContext::tag(this));
+          return true;
+        case State::FINISH_DONE:
+          next_state_ = State::INVALID;
+          return false;
+          break;
         default:
           GPR_ASSERT(false);
           return false;
       }
     }
   }
-  ClientRpcContext* StartNewClone() override {
-    return new ClientRpcContextGenericStreamingImpl(stub_, req_, next_issue_,
-                                                    start_req_, callback_);
+  void StartNewClone(CompletionQueue* cq) override {
+    auto* clone = new ClientRpcContextGenericStreamingImpl(
+        stub_, req_, next_issue_, start_req_, callback_);
+    clone->StartInternal(cq, messages_per_stream_);
   }
 
  private:
@@ -525,7 +568,9 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext {
     WAIT,
     READY_TO_WRITE,
     WRITE_DONE,
-    READ_DONE
+    READ_DONE,
+    WRITES_DONE_DONE,
+    FINISH_DONE
   };
   State next_state_;
   std::function<void(grpc::Status, ByteBuffer*)> callback_;
@@ -537,6 +582,21 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext {
   grpc::Status status_;
   double start_;
   std::unique_ptr<grpc::GenericClientAsyncReaderWriter> stream_;
+
+  // Allow a limit on number of messages in a stream
+  int messages_per_stream_;
+  int messages_issued_;
+
+  void StartInternal(CompletionQueue* cq, int messages_per_stream) {
+    cq_ = cq;
+    const grpc::string kMethodName(
+        "/grpc.testing.BenchmarkService/StreamingCall");
+    next_state_ = State::STREAM_IDLE;
+    stream_ = start_req_(stub_, &context_, kMethodName, cq,
+                         ClientRpcContext::tag(this));
+    messages_per_stream_ = messages_per_stream;
+    messages_issued_ = 0;
+  }
 };
 
 static std::unique_ptr<grpc::GenericStub> GenericStubCreator(
diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc
index 498416c64a1a8b073f0820d1a3f48fce7fb8e4ab..f8ce2cccbea6a88f3f5af94c32980cb7b11a29bb 100644
--- a/test/cpp/qps/client_sync.cc
+++ b/test/cpp/qps/client_sync.cc
@@ -129,7 +129,9 @@ class SynchronousUnaryClient final : public SynchronousClient {
     grpc::ClientContext context;
     grpc::Status s =
         stub->UnaryCall(&context, request_, &responses_[thread_idx]);
-    entry->set_value((UsageTimer::Now() - start) * 1e9);
+    if (s.ok()) {
+      entry->set_value((UsageTimer::Now() - start) * 1e9);
+    }
     entry->set_status(s.error_code());
     return true;
   }
@@ -140,24 +142,33 @@ class SynchronousStreamingClient final : public SynchronousClient {
   SynchronousStreamingClient(const ClientConfig& config)
       : SynchronousClient(config),
         context_(num_threads_),
-        stream_(num_threads_) {
+        stream_(num_threads_),
+        messages_per_stream_(config.messages_per_stream()),
+        messages_issued_(num_threads_) {
     for (size_t thread_idx = 0; thread_idx < num_threads_; thread_idx++) {
       auto* stub = channels_[thread_idx % channels_.size()].get_stub();
       stream_[thread_idx] = stub->StreamingCall(&context_[thread_idx]);
+      messages_issued_[thread_idx] = 0;
     }
     StartThreads(num_threads_);
   }
   ~SynchronousStreamingClient() {
+    std::vector<std::thread> cleanup_threads;
     for (size_t i = 0; i < num_threads_; i++) {
-      auto stream = &stream_[i];
-      if (*stream) {
-        (*stream)->WritesDone();
-        Status s = (*stream)->Finish();
-        if (!s.ok()) {
-          gpr_log(GPR_ERROR, "Stream %zu received an error %s", i,
-                  s.error_message().c_str());
+      cleanup_threads.emplace_back([this, i]() {
+        auto stream = &stream_[i];
+        if (*stream) {
+          (*stream)->WritesDone();
+          Status s = (*stream)->Finish();
+          if (!s.ok()) {
+            gpr_log(GPR_ERROR, "Stream %" PRIuPTR " received an error %s", i,
+                    s.error_message().c_str());
+          }
         }
-      }
+      });
+    }
+    for (size_t i = 0; i < num_threads_; i++) {
+      cleanup_threads[i].join();
     }
   }
 
@@ -170,12 +181,30 @@ class SynchronousStreamingClient final : public SynchronousClient {
     if (stream_[thread_idx]->Write(request_) &&
         stream_[thread_idx]->Read(&responses_[thread_idx])) {
       entry->set_value((UsageTimer::Now() - start) * 1e9);
-      return true;
+      // don't set the status since there isn't one yet
+      if ((messages_per_stream_ != 0) &&
+          (++messages_issued_[thread_idx] < messages_per_stream_)) {
+        return true;
+      } else if (messages_per_stream_ == 0) {
+        return true;
+      } else {
+        // Fall through to the below resetting code after finish
+      }
+    }
+    stream_[thread_idx]->WritesDone();
+    Status s = stream_[thread_idx]->Finish();
+    // don't set the value since this is either a failure (shouldn't be timed)
+    // or a stream-end (already has been timed)
+    entry->set_status(s.error_code());
+    if (!s.ok()) {
+      gpr_log(GPR_ERROR, "Stream %" PRIuPTR " received an error %s", thread_idx,
+              s.error_message().c_str());
     }
     auto* stub = channels_[thread_idx % channels_.size()].get_stub();
     context_[thread_idx].~ClientContext();
     new (&context_[thread_idx]) ClientContext();
     stream_[thread_idx] = stub->StreamingCall(&context_[thread_idx]);
+    messages_issued_[thread_idx] = 0;
     return true;
   }
 
@@ -186,6 +215,8 @@ class SynchronousStreamingClient final : public SynchronousClient {
   std::vector<
       std::unique_ptr<grpc::ClientReaderWriter<SimpleRequest, SimpleResponse>>>
       stream_;
+  const int messages_per_stream_;
+  std::vector<int> messages_issued_;
 };
 
 std::unique_ptr<Client> CreateSynchronousUnaryClient(
diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h
index e72d30a4effbc03cc3e67835eee4722fcc43b13e..dd32a16c879abbacffd115721b8da4c3ae303af0 100644
--- a/test/cpp/qps/driver.h
+++ b/test/cpp/qps/driver.h
@@ -36,7 +36,7 @@
 
 #include <memory>
 
-#include "src/proto/grpc/testing/control.grpc.pb.h"
+#include "src/proto/grpc/testing/control.pb.h"
 #include "test/cpp/qps/histogram.h"
 
 namespace grpc {
diff --git a/test/cpp/qps/histogram.h b/test/cpp/qps/histogram.h
index acb415f0a1085ed22edf0b83e2d1d90ed57f32e7..470a394301345cfe6145520ede70cd10c8e16114 100644
--- a/test/cpp/qps/histogram.h
+++ b/test/cpp/qps/histogram.h
@@ -35,7 +35,7 @@
 #define TEST_QPS_HISTOGRAM_H
 
 #include <grpc/support/histogram.h>
-#include "src/proto/grpc/testing/stats.grpc.pb.h"
+#include "src/proto/grpc/testing/stats.pb.h"
 
 namespace grpc {
 namespace testing {
diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc
index ddaaa7ca75e1a83ce06940802a1093b50637cc69..a9061374748a479dac074c4995504bab58693daf 100644
--- a/test/cpp/qps/qps_json_driver.cc
+++ b/test/cpp/qps/qps_json_driver.cc
@@ -31,6 +31,7 @@
  *
  */
 
+#include <iostream>
 #include <memory>
 #include <set>
 
@@ -39,10 +40,10 @@
 #include <gflags/gflags.h>
 #include <grpc/support/log.h>
 
+#include "test/cpp/qps/benchmark_config.h"
 #include "test/cpp/qps/driver.h"
 #include "test/cpp/qps/parse_json.h"
 #include "test/cpp/qps/report.h"
-#include "test/cpp/util/benchmark_config.h"
 
 DEFINE_string(scenarios_file, "",
               "JSON file containing an array of Scenario objects");
diff --git a/test/cpp/qps/qps_openloop_test.cc b/test/cpp/qps/qps_openloop_test.cc
index 70e2709ac02cbb595ea89cc98bd2700c869325f6..28b396739fb45531fa1c9e23562685c9ca9240dd 100644
--- a/test/cpp/qps/qps_openloop_test.cc
+++ b/test/cpp/qps/qps_openloop_test.cc
@@ -36,9 +36,9 @@
 #include <grpc/support/log.h>
 
 #include "test/core/util/test_config.h"
+#include "test/cpp/qps/benchmark_config.h"
 #include "test/cpp/qps/driver.h"
 #include "test/cpp/qps/report.h"
-#include "test/cpp/util/benchmark_config.h"
 
 namespace grpc {
 namespace testing {
diff --git a/test/cpp/qps/qps_test.cc b/test/cpp/qps/qps_test.cc
index f94ea0cb499c174c0245c9b941361471df3445ad..7c4e2cfd3e1f7e3f30518c2013c1d85877c40a2f 100644
--- a/test/cpp/qps/qps_test.cc
+++ b/test/cpp/qps/qps_test.cc
@@ -35,9 +35,9 @@
 
 #include <grpc/support/log.h>
 
+#include "test/cpp/qps/benchmark_config.h"
 #include "test/cpp/qps/driver.h"
 #include "test/cpp/qps/report.h"
-#include "test/cpp/util/benchmark_config.h"
 
 namespace grpc {
 namespace testing {
diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc
index 7f8481642190803f11fc51331893692f5a24be34..a9130bf5d425b3dd8970eff3874a3647b6d25439 100644
--- a/test/cpp/qps/report.cc
+++ b/test/cpp/qps/report.cc
@@ -40,6 +40,9 @@
 #include "test/cpp/qps/parse_json.h"
 #include "test/cpp/qps/stats.h"
 
+#include <grpc++/client_context.h>
+#include "src/proto/grpc/testing/services.grpc.pb.h"
+
 namespace grpc {
 namespace testing {
 
@@ -142,5 +145,37 @@ void JsonReporter::ReportCpuUsage(const ScenarioResult& result) {
   // NOP - all reporting is handled by ReportQPS.
 }
 
+void RpcReporter::ReportQPS(const ScenarioResult& result) {
+  grpc::ClientContext context;
+  grpc::Status status;
+  Void dummy;
+
+  gpr_log(GPR_INFO, "RPC reporter sending scenario result to server");
+  status = stub_->ReportScenario(&context, result, &dummy);
+
+  if (status.ok()) {
+    gpr_log(GPR_INFO, "RpcReporter report RPC success!");
+  } else {
+    gpr_log(GPR_ERROR, "RpcReporter report RPC: code: %d. message: %s",
+            status.error_code(), status.error_message().c_str());
+  }
+}
+
+void RpcReporter::ReportQPSPerCore(const ScenarioResult& result) {
+  // NOP - all reporting is handled by ReportQPS.
+}
+
+void RpcReporter::ReportLatency(const ScenarioResult& result) {
+  // NOP - all reporting is handled by ReportQPS.
+}
+
+void RpcReporter::ReportTimes(const ScenarioResult& result) {
+  // NOP - all reporting is handled by ReportQPS.
+}
+
+void RpcReporter::ReportCpuUsage(const ScenarioResult& result) {
+  // NOP - all reporting is handled by ReportQPS.
+}
+
 }  // namespace testing
 }  // namespace grpc
diff --git a/test/cpp/qps/report.h b/test/cpp/qps/report.h
index faf87ff060f6f4832ec1d17bf45ff3e5e7d016b9..1749be98c6f9ce95b9d97e664340e85d004c40e0 100644
--- a/test/cpp/qps/report.h
+++ b/test/cpp/qps/report.h
@@ -42,6 +42,9 @@
 
 #include "test/cpp/qps/driver.h"
 
+#include <grpc++/channel.h>
+#include "src/proto/grpc/testing/services.grpc.pb.h"
+
 namespace grpc {
 namespace testing {
 
@@ -124,6 +127,21 @@ class JsonReporter : public Reporter {
   const string report_file_;
 };
 
+class RpcReporter : public Reporter {
+ public:
+  RpcReporter(const string& name, std::shared_ptr<grpc::Channel> channel)
+      : Reporter(name), stub_(ReportQpsScenarioService::NewStub(channel)) {}
+
+ private:
+  void ReportQPS(const ScenarioResult& result) override;
+  void ReportQPSPerCore(const ScenarioResult& result) override;
+  void ReportLatency(const ScenarioResult& result) override;
+  void ReportTimes(const ScenarioResult& result) override;
+  void ReportCpuUsage(const ScenarioResult& result) override;
+
+  std::unique_ptr<ReportQpsScenarioService::Stub> stub_;
+};
+
 }  // namespace testing
 }  // namespace grpc
 
diff --git a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
index d0c47d102ad0b541f27e2e72c224ec6f7aa43833..509d9f89c3849e3f021372a161d3aa48d1599b5d 100644
--- a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
+++ b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
@@ -35,9 +35,9 @@
 
 #include <grpc/support/log.h>
 
+#include "test/cpp/qps/benchmark_config.h"
 #include "test/cpp/qps/driver.h"
 #include "test/cpp/qps/report.h"
-#include "test/cpp/util/benchmark_config.h"
 
 namespace grpc {
 namespace testing {
diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h
index 821d5935beb96d971ad2539587492f9a183f50b5..8fbf37a0957869868fec4b68c75c0823f21e1b39 100644
--- a/test/cpp/qps/server.h
+++ b/test/cpp/qps/server.h
@@ -38,8 +38,8 @@
 #include <grpc/support/cpu.h>
 #include <vector>
 
-#include "src/proto/grpc/testing/control.grpc.pb.h"
-#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/control.pb.h"
+#include "src/proto/grpc/testing/messages.pb.h"
 #include "test/core/end2end/data/ssl_test_data.h"
 #include "test/core/util/port.h"
 #include "test/cpp/qps/usage_timer.h"
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index b3a06aeaf5319ae6a661889f388fb54e0e6b8695..b499b82091e55d48d618a61677fbb7bd4ab5eb04 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -103,24 +103,25 @@ class AsyncQpsServerTest final : public grpc::testing::Server {
 
     server_ = builder.BuildAndStart();
 
-    using namespace std::placeholders;
-
     auto process_rpc_bound =
-        std::bind(process_rpc, config.payload_config(), _1, _2);
+        std::bind(process_rpc, config.payload_config(), std::placeholders::_1,
+                  std::placeholders::_2);
 
     for (int i = 0; i < 15000; i++) {
       for (int j = 0; j < num_threads; j++) {
         if (request_unary_function) {
-          auto request_unary =
-              std::bind(request_unary_function, &async_service_, _1, _2, _3,
-                        srv_cqs_[j].get(), srv_cqs_[j].get(), _4);
+          auto request_unary = std::bind(
+              request_unary_function, &async_service_, std::placeholders::_1,
+              std::placeholders::_2, std::placeholders::_3, srv_cqs_[j].get(),
+              srv_cqs_[j].get(), std::placeholders::_4);
           contexts_.emplace_back(
               new ServerRpcContextUnaryImpl(request_unary, process_rpc_bound));
         }
         if (request_streaming_function) {
-          auto request_streaming =
-              std::bind(request_streaming_function, &async_service_, _1, _2,
-                        srv_cqs_[j].get(), srv_cqs_[j].get(), _3);
+          auto request_streaming = std::bind(
+              request_streaming_function, &async_service_,
+              std::placeholders::_1, std::placeholders::_2, srv_cqs_[j].get(),
+              srv_cqs_[j].get(), std::placeholders::_3);
           contexts_.emplace_back(new ServerRpcContextStreamingImpl(
               request_streaming, process_rpc_bound));
         }
@@ -234,18 +235,17 @@ class AsyncQpsServerTest final : public grpc::testing::Server {
         return false;
       }
 
-      ResponseType response;
-
       // Call the RPC processing function
-      grpc::Status status = invoke_method_(&req_, &response);
+      grpc::Status status = invoke_method_(&req_, &response_);
 
       // Have the response writer work and invoke on_finish when done
       next_state_ = &ServerRpcContextUnaryImpl::finisher;
-      response_writer_.Finish(response, status, AsyncQpsServerTest::tag(this));
+      response_writer_.Finish(response_, status, AsyncQpsServerTest::tag(this));
       return true;
     }
     std::unique_ptr<ServerContextType> srv_ctx_;
     RequestType req_;
+    ResponseType response_;
     bool (ServerRpcContextUnaryImpl::*next_state_)(bool);
     std::function<void(ServerContextType *, RequestType *,
                        grpc::ServerAsyncResponseWriter<ResponseType> *, void *)>
@@ -297,11 +297,10 @@ class AsyncQpsServerTest final : public grpc::testing::Server {
     bool read_done(bool ok) {
       if (ok) {
         // invoke the method
-        ResponseType response;
         // Call the RPC processing function
-        grpc::Status status = invoke_method_(&req_, &response);
+        grpc::Status status = invoke_method_(&req_, &response_);
         // initiate the write
-        stream_.Write(response, AsyncQpsServerTest::tag(this));
+        stream_.Write(response_, AsyncQpsServerTest::tag(this));
         next_state_ = &ServerRpcContextStreamingImpl::write_done;
       } else {  // client has sent writes done
         // finish the stream
@@ -325,6 +324,7 @@ class AsyncQpsServerTest final : public grpc::testing::Server {
 
     std::unique_ptr<ServerContextType> srv_ctx_;
     RequestType req_;
+    ResponseType response_;
     bool (ServerRpcContextStreamingImpl::*next_state_)(bool);
     std::function<void(
         ServerContextType *,
diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc
index 8076a4a6b9abb7374781cb84fa812c2ffb0bbb3d..f79284d2254b04f952aed145a088f135e7d9e142 100644
--- a/test/cpp/qps/server_sync.cc
+++ b/test/cpp/qps/server_sync.cc
@@ -74,7 +74,9 @@ class BenchmarkServiceImpl final : public BenchmarkService::Service {
           return Status(grpc::StatusCode::INTERNAL, "Error creating payload.");
         }
       }
-      stream->Write(response);
+      if (!stream->Write(response)) {
+        return Status(StatusCode::INTERNAL, "Server couldn't respond");
+      }
     }
     return Status::OK;
   }
diff --git a/test/cpp/server/server_builder_test.cc b/test/cpp/server/server_builder_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1d9eda17b40e46477f7ef83d78584c286584d4c8
--- /dev/null
+++ b/test/cpp/server/server_builder_test.cc
@@ -0,0 +1,96 @@
+/*
+ *
+ * Copyright 2017, 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++/impl/codegen/config.h>
+#include <gtest/gtest.h>
+
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/core/util/port.h"
+
+namespace grpc {
+namespace {
+
+testing::EchoTestService::Service g_service;
+
+grpc::string MakePort() {
+  std::ostringstream s;
+  int p = grpc_pick_unused_port_or_die();
+  s << "localhost:" << p;
+  return s.str();
+}
+
+grpc::string g_port = MakePort();
+
+TEST(ServerBuilderTest, NoOp) { ServerBuilder b; }
+
+TEST(ServerBuilderTest, CreateServerNoPorts) {
+  ServerBuilder().RegisterService(&g_service).BuildAndStart()->Shutdown();
+}
+
+TEST(ServerBuilderTest, CreateServerOnePort) {
+  ServerBuilder()
+      .RegisterService(&g_service)
+      .AddListeningPort(g_port, InsecureServerCredentials())
+      .BuildAndStart()
+      ->Shutdown();
+}
+
+TEST(ServerBuilderTest, CreateServerRepeatedPort) {
+  ServerBuilder()
+      .RegisterService(&g_service)
+      .AddListeningPort(g_port, InsecureServerCredentials())
+      .AddListeningPort(g_port, InsecureServerCredentials())
+      .BuildAndStart()
+      ->Shutdown();
+}
+
+TEST(ServerBuilderTest, CreateServerRepeatedPortWithDisallowedReusePort) {
+  EXPECT_EQ(ServerBuilder()
+                .RegisterService(&g_service)
+                .AddListeningPort(g_port, InsecureServerCredentials())
+                .AddListeningPort(g_port, InsecureServerCredentials())
+                .AddChannelArgument(GRPC_ARG_ALLOW_REUSEPORT, 0)
+                .BuildAndStart(),
+            nullptr);
+}
+
+}  // namespace
+}  // namespace grpc
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/test/cpp/thread_manager/thread_manager_test.cc b/test/cpp/thread_manager/thread_manager_test.cc
index 35c8d5d0880d0e6f2eb1970a7d78dce9a98d9e02..e1a03666f0b4ec407d2c40eb264860f32be51f90 100644
--- a/test/cpp/thread_manager/thread_manager_test.cc
+++ b/test/cpp/thread_manager/thread_manager_test.cc
@@ -118,7 +118,7 @@ void ThreadManagerTest::PerformTest() {
 
   // The number of times DoWork() was called is equal to the number of times
   // WORK_FOUND was returned
-  gpr_log(GPR_DEBUG, "DoWork() called %ld times",
+  gpr_log(GPR_DEBUG, "DoWork() called %" PRIdPTR " times",
           gpr_atm_no_barrier_load(&num_do_work_));
   GPR_ASSERT(gpr_atm_no_barrier_load(&num_do_work_) ==
              gpr_atm_no_barrier_load(&num_work_found_));
diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD
index dc90a4e172cc8411daa56a2d9bb91ade0adbf8d3..9dde22b4d1ba83cb2b463721e651ca9bb81b26e8 100644
--- a/test/cpp/util/BUILD
+++ b/test/cpp/util/BUILD
@@ -29,6 +29,15 @@
 
 licenses(["notice"])  # 3-clause BSD
 
+# The following builds a shared-object to confirm that grpc++_unsecure
+# builds properly. Build-only is sufficient here
+cc_binary(
+    name = "testso.so",
+    srcs = [],
+    linkshared = 1,
+    deps = ["//:grpc++_unsecure"],
+)
+
 cc_library(
     name = "test_config",
     srcs = [
@@ -62,7 +71,6 @@ cc_library(
 cc_library(
     name = "test_util",
     srcs = [
-        #        "test/cpp/end2end/test_service_impl.cc",
         "byte_buffer_proto_helper.cc",
         "create_test_channel.cc",
         "string_ref_helper.cc",
@@ -83,3 +91,42 @@ cc_library(
         "//test/core/util:gpr_test_util",
     ],
 )
+
+cc_test(
+    name = "error_details_test",
+    srcs = [
+        "error_details_test.cc",
+    ],
+    deps = [
+        "//:grpc++_error_details",
+        "//external:gtest",
+        "//src/proto/grpc/testing:echo_messages_proto",
+    ],
+)
+
+cc_binary(
+    name = "grpc_cli",
+    srcs = [
+        "cli_call.cc",
+        "cli_call.h",
+        "cli_credentials.cc",
+        "cli_credentials.h",
+        "config_grpc_cli.h",
+        "grpc_cli.cc",
+        "grpc_tool.cc",
+        "grpc_tool.h",
+        "proto_file_parser.cc",
+        "proto_file_parser.h",
+        "proto_reflection_descriptor_database.cc",
+        "proto_reflection_descriptor_database.h",
+        "service_describer.cc",
+        "service_describer.h",
+        "test_config.h",
+        "test_config_cc.cc",
+    ],
+    deps = [
+        "//:grpc++",
+        "//external:gflags",
+        "//src/proto/grpc/reflection/v1alpha:reflection_proto",
+    ],
+)
diff --git a/test/cpp/util/cli_call.cc b/test/cpp/util/cli_call.cc
index 041cc0e4c35998c59ce6232d86df0a1c08321b70..b26beb050da6016e8894246220bf6576a3ce7f5a 100644
--- a/test/cpp/util/cli_call.cc
+++ b/test/cpp/util/cli_call.cc
@@ -91,7 +91,7 @@ void CliCall::Write(const grpc::string& request) {
   void* got_tag;
   bool ok;
 
-  grpc_slice s = grpc_slice_from_copied_string(request.c_str());
+  gpr_slice s = gpr_slice_from_copied_buffer(request.data(), request.size());
   grpc::Slice req_slice(s, grpc::Slice::STEAL_REF);
   grpc::ByteBuffer send_buffer(&req_slice, 1);
   call_->Write(send_buffer, tag(2));
diff --git a/test/cpp/util/error_details_test.cc b/test/cpp/util/error_details_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d01fd3b08708f461af1d92fd4334dbc0af915833
--- /dev/null
+++ b/test/cpp/util/error_details_test.cc
@@ -0,0 +1,120 @@
+/*
+ *
+ * Copyright 2017, 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++/support/error_details.h>
+#include <gtest/gtest.h>
+
+#include "src/proto/grpc/status/status.pb.h"
+#include "src/proto/grpc/testing/echo_messages.pb.h"
+
+namespace grpc {
+namespace {
+
+TEST(ExtractTest, Success) {
+  google::rpc::Status expected;
+  expected.set_code(13);  // INTERNAL
+  expected.set_message("I am an error message");
+  testing::EchoRequest expected_details;
+  expected_details.set_message(grpc::string(100, '\0'));
+  expected.add_details()->PackFrom(expected_details);
+
+  google::rpc::Status to;
+  grpc::string error_details = expected.SerializeAsString();
+  Status from(static_cast<StatusCode>(expected.code()), expected.message(),
+              error_details);
+  EXPECT_TRUE(ExtractErrorDetails(from, &to).ok());
+  EXPECT_EQ(expected.code(), to.code());
+  EXPECT_EQ(expected.message(), to.message());
+  EXPECT_EQ(1, to.details_size());
+  testing::EchoRequest details;
+  to.details(0).UnpackTo(&details);
+  EXPECT_EQ(expected_details.message(), details.message());
+}
+
+TEST(ExtractTest, NullInput) {
+  EXPECT_EQ(StatusCode::FAILED_PRECONDITION,
+            ExtractErrorDetails(Status(), nullptr).error_code());
+}
+
+TEST(ExtractTest, Unparsable) {
+  grpc::string error_details("I am not a status object");
+  Status from(StatusCode::INTERNAL, "", error_details);
+  google::rpc::Status to;
+  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
+            ExtractErrorDetails(from, &to).error_code());
+}
+
+TEST(SetTest, Success) {
+  google::rpc::Status expected;
+  expected.set_code(13);  // INTERNAL
+  expected.set_message("I am an error message");
+  testing::EchoRequest expected_details;
+  expected_details.set_message(grpc::string(100, '\0'));
+  expected.add_details()->PackFrom(expected_details);
+
+  Status to;
+  Status s = SetErrorDetails(expected, &to);
+  EXPECT_TRUE(s.ok());
+  EXPECT_EQ(expected.code(), to.error_code());
+  EXPECT_EQ(expected.message(), to.error_message());
+  EXPECT_EQ(expected.SerializeAsString(), to.error_details());
+}
+
+TEST(SetTest, NullInput) {
+  EXPECT_EQ(StatusCode::FAILED_PRECONDITION,
+            SetErrorDetails(google::rpc::Status(), nullptr).error_code());
+}
+
+TEST(SetTest, OutOfScopeErrorCode) {
+  google::rpc::Status expected;
+  expected.set_code(20);  // Out of scope (DATA_LOSS is 15).
+  expected.set_message("I am an error message");
+  testing::EchoRequest expected_details;
+  expected_details.set_message(grpc::string(100, '\0'));
+  expected.add_details()->PackFrom(expected_details);
+
+  Status to;
+  Status s = SetErrorDetails(expected, &to);
+  EXPECT_TRUE(s.ok());
+  EXPECT_EQ(StatusCode::UNKNOWN, to.error_code());
+  EXPECT_EQ(expected.message(), to.error_message());
+  EXPECT_EQ(expected.SerializeAsString(), to.error_details());
+}
+
+}  // namespace
+}  // namespace grpc
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc
index 856cd32c3ce0f8fed980137132167615239ba59a..c7acb7c63135c5fd3c9d36bb01020d1148295983 100644
--- a/test/cpp/util/grpc_tool.cc
+++ b/test/cpp/util/grpc_tool.cc
@@ -321,6 +321,7 @@ bool GrpcTool::ListServices(int argc, const char** argv,
 
   std::vector<grpc::string> service_list;
   if (!desc_db.GetServices(&service_list)) {
+    fprintf(stderr, "Received an error when querying services endpoint.\n");
     return false;
   }
 
diff --git a/test/distrib/cpp/run_distrib_test.sh b/test/distrib/cpp/run_distrib_test.sh
index 15fbf28107494f318d60779918d34b30c123a67d..4728e32f065be466ccce1187f10f3f1def5a40ae 100755
--- a/test/distrib/cpp/run_distrib_test.sh
+++ b/test/distrib/cpp/run_distrib_test.sh
@@ -30,13 +30,8 @@
 
 set -ex
 
-git clone $EXTERNAL_GIT_ROOT
-# clone gRPC submodules, use data from locally cloned submodules where possible
-(cd ${EXTERNAL_GIT_ROOT} && git submodule foreach 'cd /var/local/git/grpc \
-&& git submodule update --init --reference ${EXTERNAL_GIT_ROOT}/${name} \
-${name}')
-
-cd grpc
+# change to grpc repo root
+cd $(dirname $0)/../../..
 
 cd third_party/protobuf && ./autogen.sh && \
 ./configure && make -j4 && make check && make install && ldconfig
diff --git a/test/distrib/csharp/run_distrib_test.bat b/test/distrib/csharp/run_distrib_test.bat
index 6cf381142f4b5a8add9d633ea4260c59d044e2e7..cb5dd55273989eb8e750930205b5ab3fbff963c4 100644
--- a/test/distrib/csharp/run_distrib_test.bat
+++ b/test/distrib/csharp/run_distrib_test.bat
@@ -31,7 +31,7 @@
 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_dotnetcli.zip', 'TestNugetFeed');"
+powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('../../../input_artifacts/csharp_nugets_windows_dotnetcli.zip', 'TestNugetFeed');"
 
 update_version.sh auto
 
diff --git a/test/distrib/csharp/run_distrib_test.sh b/test/distrib/csharp/run_distrib_test.sh
index 0a77c1af4407a16259da7cda77b663a38676aa2e..9de5ce0cd32b452d25dce11dcc68c07798502ac5 100755
--- a/test/distrib/csharp/run_distrib_test.sh
+++ b/test/distrib/csharp/run_distrib_test.sh
@@ -32,7 +32,7 @@ set -ex
 
 cd $(dirname $0)
 
-unzip -o "$EXTERNAL_GIT_ROOT/input_artifacts/csharp_nugets_dotnetcli.zip" -d TestNugetFeed
+unzip -o "$EXTERNAL_GIT_ROOT/input_artifacts/csharp_nugets_windows_dotnetcli.zip" -d TestNugetFeed
 
 ./update_version.sh auto
 
diff --git a/test/distrib/csharp/run_distrib_test_dotnetcli.sh b/test/distrib/csharp/run_distrib_test_dotnetcli.sh
index 493c5049fb8e00a4c63e0d3b0d5afe637b148cbb..cdfc91bf42775fb88d00f395a99a16fa7859a52a 100755
--- a/test/distrib/csharp/run_distrib_test_dotnetcli.sh
+++ b/test/distrib/csharp/run_distrib_test_dotnetcli.sh
@@ -32,7 +32,7 @@ set -ex
 
 cd $(dirname $0)
 
-unzip -o "$EXTERNAL_GIT_ROOT/input_artifacts/csharp_nugets_dotnetcli.zip" -d TestNugetFeed
+unzip -o "$EXTERNAL_GIT_ROOT/input_artifacts/csharp_nugets_windows_dotnetcli.zip" -d TestNugetFeed
 
 ./update_version.sh auto
 
diff --git a/test/http2_test/http2_base_server.py b/test/http2_test/http2_base_server.py
index 8de028ceb1b85a90c7e563eaf05fdff6088891f5..e158e9b703031adf5033207beef454fc49be8202 100644
--- a/test/http2_test/http2_base_server.py
+++ b/test/http2_test/http2_base_server.py
@@ -39,6 +39,7 @@ import twisted.internet.protocol
 
 _READ_CHUNK_SIZE = 16384
 _GRPC_HEADER_SIZE = 5
+_MIN_SETTINGS_MAX_FRAME_SIZE = 16384
 
 class H2ProtocolBaseServer(twisted.internet.protocol.Protocol):
   def __init__(self):
@@ -121,38 +122,46 @@ class H2ProtocolBaseServer(twisted.internet.protocol.Protocol):
     )
     self.transport.write(self._conn.data_to_send())
 
-  def on_window_update_default(self, event):
-    # send pending data, if any
-    self.default_send(event.stream_id)
+  def on_window_update_default(self, _, pad_length=None, read_chunk_size=_READ_CHUNK_SIZE):
+    # try to resume sending on all active streams (update might be for connection)
+    for stream_id in self._send_remaining:
+      self.default_send(stream_id, pad_length=pad_length, read_chunk_size=read_chunk_size)
 
   def send_reset_stream(self):
     self._conn.reset_stream(self._stream_id)
     self.transport.write(self._conn.data_to_send())
 
-  def setup_send(self, data_to_send, stream_id):
+  def setup_send(self, data_to_send, stream_id, pad_length=None, read_chunk_size=_READ_CHUNK_SIZE):
     logging.info('Setting up data to send for stream_id: %d' % stream_id)
     self._send_remaining[stream_id] = len(data_to_send)
     self._send_offset = 0
     self._data_to_send = data_to_send
-    self.default_send(stream_id)
+    self.default_send(stream_id, pad_length=pad_length, read_chunk_size=read_chunk_size)
 
-  def default_send(self, stream_id):
+  def default_send(self, stream_id, pad_length=None, read_chunk_size=_READ_CHUNK_SIZE):
     if not self._send_remaining.has_key(stream_id):
       # not setup to send data yet
       return
 
     while self._send_remaining[stream_id] > 0:
       lfcw = self._conn.local_flow_control_window(stream_id)
-      if lfcw == 0:
+      padding_bytes = pad_length + 1 if pad_length is not None else 0
+      if lfcw - padding_bytes <= 0:
+        logging.info('Stream %d. lfcw: %d. padding bytes: %d. not enough quota yet' % (stream_id, lfcw, padding_bytes))
         break
-      chunk_size = min(lfcw, _READ_CHUNK_SIZE)
+      chunk_size = min(lfcw - padding_bytes, read_chunk_size)
       bytes_to_send = min(chunk_size, self._send_remaining[stream_id])
-      logging.info('flow_control_window = %d. sending [%d:%d] stream_id %d' %
-                    (lfcw, self._send_offset, self._send_offset + bytes_to_send,
-                    stream_id))
+      logging.info('flow_control_window = %d. sending [%d:%d] stream_id %d. includes %d total padding bytes' %
+                    (lfcw, self._send_offset, self._send_offset + bytes_to_send + padding_bytes,
+                    stream_id, padding_bytes))
+      # The receiver might allow sending frames larger than the http2 minimum
+      # max frame size (16384), but this test should never send more than 16384
+      # for simplicity (which is always legal).
+      if bytes_to_send + padding_bytes > _MIN_SETTINGS_MAX_FRAME_SIZE:
+        raise ValueError("overload: sending %d" % (bytes_to_send + padding_bytes))
       data = self._data_to_send[self._send_offset : self._send_offset + bytes_to_send]
       try:
-        self._conn.send_data(stream_id, data, False)
+        self._conn.send_data(stream_id, data, end_stream=False, pad_length=pad_length)
       except h2.exceptions.ProtocolError:
         logging.info('Stream %d is closed' % stream_id)
         break
@@ -200,5 +209,5 @@ class H2ProtocolBaseServer(twisted.internet.protocol.Protocol):
     req_proto_str = recv_buffer[5:5+grpc_msg_size]
     sr = messages_pb2.SimpleRequest()
     sr.ParseFromString(req_proto_str)
-    logging.info('Parsed request for stream %d: response_size=%s' % (stream_id, sr.response_size))
+    logging.info('Parsed simple request for stream %d' % stream_id)
     return sr
diff --git a/test/http2_test/http2_server_health_check.py b/test/http2_test/http2_server_health_check.py
new file mode 100644
index 0000000000000000000000000000000000000000..dd9402b8557bc8fee0baeb9f728d3c332668ae1e
--- /dev/null
+++ b/test/http2_test/http2_server_health_check.py
@@ -0,0 +1,49 @@
+# Copyright 2017, 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 hyper
+import sys
+
+# Utility to healthcheck the http2 server. Used when starting the server to
+# verify that the server is live before tests begin.
+if __name__ == '__main__':
+  parser = argparse.ArgumentParser()
+  parser.add_argument('--server_host', type=str, default='localhost')
+  parser.add_argument('--server_port', type=int, default=8080)
+  args = parser.parse_args()
+  server_host = args.server_host
+  server_port = args.server_port
+  conn = hyper.HTTP20Connection('%s:%d' % (server_host, server_port))
+  conn.request('POST', '/grpc.testing.TestService/UnaryCall')
+  resp = conn.get_response()
+  if resp.headers.get('grpc-encoding') is None:
+    sys.exit(1)
+  else:
+    sys.exit(0)
diff --git a/test/http2_test/http2_test_server.py b/test/http2_test/http2_test_server.py
index abde3433ad22782ab1757c52650e6575f4e8d014..6a7849b94a72c407e6db29e717fb0bd0f3d782c0 100644
--- a/test/http2_test/http2_test_server.py
+++ b/test/http2_test/http2_test_server.py
@@ -31,6 +31,7 @@
 
 import argparse
 import logging
+import sys
 import twisted
 import twisted.internet
 import twisted.internet.endpoints
@@ -43,6 +44,7 @@ import test_ping
 import test_rst_after_data
 import test_rst_after_header
 import test_rst_during_data
+import test_data_frame_padding
 
 _TEST_CASE_MAPPING = {
   'rst_after_header': test_rst_after_header.TestcaseRstStreamAfterHeader,
@@ -51,11 +53,17 @@ _TEST_CASE_MAPPING = {
   'goaway': test_goaway.TestcaseGoaway,
   'ping': test_ping.TestcasePing,
   'max_streams': test_max_streams.TestcaseSettingsMaxStreams,
+
+  # Positive tests below:
+  'data_frame_padding': test_data_frame_padding.TestDataFramePadding,
+  'no_df_padding_sanity_test': test_data_frame_padding.TestDataFramePadding,
 }
 
+_exit_code = 0
+
 class H2Factory(twisted.internet.protocol.Factory):
   def __init__(self, testcase):
-    logging.info('Creating H2Factory for new connection.')
+    logging.info('Creating H2Factory for new connection (%s)', testcase)
     self._num_streams = 0
     self._testcase = testcase
 
@@ -70,6 +78,8 @@ class H2Factory(twisted.internet.protocol.Factory):
 
     if self._testcase == 'goaway':
       return t(self._num_streams).get_base_server()
+    elif self._testcase == 'no_df_padding_sanity_test':
+      return t(use_padding=False).get_base_server()
     else:
       return t().get_base_server()
 
@@ -78,11 +88,23 @@ def parse_arguments():
   parser.add_argument('--base_port', type=int, default=8080,
     help='base port to run the servers (default: 8080). One test server is '
     'started on each incrementing port, beginning with base_port, in the '
-    'following order: goaway,max_streams,ping,rst_after_data,rst_after_header,'
+    'following order: data_frame_padding,goaway,max_streams,'
+    'no_df_padding_sanity_test,ping,rst_after_data,rst_after_header,'
     'rst_during_data'
     )
   return parser.parse_args()
 
+def listen(endpoint, test_case):
+  deferred = endpoint.listen(H2Factory(test_case))
+  def listen_error(reason):
+    # If listening fails, we stop the reactor and exit the program
+    # with exit code 1.
+    global _exit_code
+    _exit_code = 1
+    logging.error('Listening failed: %s' % reason.value)
+    twisted.internet.reactor.stop()
+  deferred.addErrback(listen_error)
+
 def start_test_servers(base_port):
   """ Start one server per test case on incrementing port numbers
   beginning with base_port """
@@ -92,7 +114,9 @@ def start_test_servers(base_port):
     logging.warning('serving on port %d : %s'%(portnum, test_case))
     endpoint = twisted.internet.endpoints.TCP4ServerEndpoint(
       twisted.internet.reactor, portnum, backlog=128)
-    endpoint.listen(H2Factory(test_case))
+    # Wait until the reactor is running before calling endpoint.listen().
+    twisted.internet.reactor.callWhenRunning(listen, endpoint, test_case)
+
     index += 1
 
 if __name__ == '__main__':
@@ -102,3 +126,4 @@ if __name__ == '__main__':
   args = parse_arguments()
   start_test_servers(args.base_port)
   twisted.internet.reactor.run()
+  sys.exit(_exit_code)
diff --git a/test/http2_test/test_data_frame_padding.py b/test/http2_test/test_data_frame_padding.py
new file mode 100644
index 0000000000000000000000000000000000000000..e1db28faedc8790bab27c260759ec2f036322bc8
--- /dev/null
+++ b/test/http2_test/test_data_frame_padding.py
@@ -0,0 +1,94 @@
+# 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 http2_base_server
+import logging
+import messages_pb2
+
+# Set the number of padding bytes per data frame to be very large
+# relative to the number of data bytes for each data frame sent.
+_LARGE_PADDING_LENGTH = 255
+_SMALL_READ_CHUNK_SIZE = 5
+
+class TestDataFramePadding(object):
+  """
+    In response to an incoming request, this test sends headers, followed by
+    data, followed by a reset stream frame. Client asserts that the RPC failed.
+    Client needs to deliver the complete message to the application layer.
+  """
+  def __init__(self, use_padding=True):
+    self._base_server = http2_base_server.H2ProtocolBaseServer()
+    self._base_server._handlers['DataReceived'] = self.on_data_received
+    self._base_server._handlers['WindowUpdated'] = self.on_window_update
+    self._base_server._handlers['RequestReceived'] = self.on_request_received
+
+    # _total_updates maps stream ids to total flow control updates received
+    self._total_updates = {}
+    # zero window updates so far for connection window (stream id '0')
+    self._total_updates[0] = 0
+    self._read_chunk_size = _SMALL_READ_CHUNK_SIZE
+
+    if use_padding:
+      self._pad_length = _LARGE_PADDING_LENGTH
+    else:
+      self._pad_length = None
+
+  def get_base_server(self):
+    return self._base_server
+
+  def on_data_received(self, event):
+    logging.info('on data received. Stream id: %d. Data length: %d' % (event.stream_id, len(event.data)))
+    self._base_server.on_data_received_default(event)
+    if len(event.data) == 0:
+      return
+    sr = self._base_server.parse_received_data(event.stream_id)
+    stream_bytes = ''
+    # Check if full grpc msg has been read into the recv buffer yet
+    if sr:
+      response_data = self._base_server.default_response_data(sr.response_size)
+      logging.info('Stream id: %d. total resp size: %d' % (event.stream_id, len(response_data)))
+      # Begin sending the response. Add ``self._pad_length`` padding to each
+      # data frame and split the whole message into data frames each carrying
+      # only self._read_chunk_size of data.
+      # The purpose is to have the majority of the data frame response bytes
+      # be padding bytes, since ``self._pad_length`` >> ``self._read_chunk_size``.
+      self._base_server.setup_send(response_data , event.stream_id, pad_length=self._pad_length, read_chunk_size=self._read_chunk_size)
+
+  def on_request_received(self, event):
+    self._base_server.on_request_received_default(event)
+    logging.info('on request received. Stream id: %s.' % event.stream_id)
+    self._total_updates[event.stream_id] = 0
+
+  # Log debug info and try to resume sending on all currently active streams.
+  def on_window_update(self, event):
+    logging.info('on window update. Stream id: %s. Delta: %s' % (event.stream_id, event.delta))
+    self._total_updates[event.stream_id] += event.delta
+    total = self._total_updates[event.stream_id]
+    logging.info('... - total updates for stream %d : %d' % (event.stream_id, total))
+    self._base_server.on_window_update_default(event, pad_length=self._pad_length, read_chunk_size=self._read_chunk_size)
diff --git a/third_party/benchmark.BUILD b/third_party/benchmark.BUILD
new file mode 100644
index 0000000000000000000000000000000000000000..4c622f32a84e83765e2d1a481f6ff47c615f9751
--- /dev/null
+++ b/third_party/benchmark.BUILD
@@ -0,0 +1,15 @@
+cc_library(
+    name = "benchmark",
+    srcs = glob(["src/*.cc"]),
+    hdrs = glob(["include/**/*.h", "src/*.h"]),
+    includes = [
+        "include", "."
+    ],
+    copts = [
+        "-DHAVE_POSIX_REGEX"
+    ],
+    linkstatic = 1,
+    visibility = [
+        "//visibility:public",
+    ],
+)
diff --git a/third_party/cares/ares_build.h b/third_party/cares/ares_build.h
new file mode 100644
index 0000000000000000000000000000000000000000..d6b3d49f37f0ab0a47efdb7cf651f9a56cc809d7
--- /dev/null
+++ b/third_party/cares/ares_build.h
@@ -0,0 +1,264 @@
+#ifndef __CARES_BUILD_H
+#define __CARES_BUILD_H
+
+
+/* Copyright (C) 2009 - 2013 by Daniel Stenberg et al
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+/* ================================================================ */
+/*               NOTES FOR CONFIGURE CAPABLE SYSTEMS                */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * See file ares_build.h.in, run configure, and forget that this file
+ * exists it is only used for non-configure systems.
+ * But you can keep reading if you want ;-)
+ *
+ */
+
+/* ================================================================ */
+/*                 NOTES FOR NON-CONFIGURE SYSTEMS                  */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * Nothing in this file is intended to be modified or adjusted by the
+ * c-ares library user nor by the c-ares library builder.
+ *
+ * If you think that something actually needs to be changed, adjusted
+ * or fixed in this file, then, report it on the c-ares development
+ * mailing list: http://cool.haxx.se/mailman/listinfo/c-ares/
+ *
+ * Try to keep one section per platform, compiler and architecture,
+ * otherwise, if an existing section is reused for a different one and
+ * later on the original is adjusted, probably the piggybacking one can
+ * be adversely changed.
+ *
+ * In order to differentiate between platforms/compilers/architectures
+ * use only compiler built in predefined preprocessor symbols.
+ *
+ * This header file shall only export symbols which are 'cares' or 'CARES'
+ * prefixed, otherwise public name space would be polluted.
+ *
+ * NOTE 2:
+ * -------
+ *
+ * Right now you might be staring at file ares_build.h.dist or ares_build.h,
+ * this is due to the following reason: file ares_build.h.dist is renamed
+ * to ares_build.h when the c-ares source code distribution archive file is
+ * created.
+ *
+ * File ares_build.h.dist is not included in the distribution archive.
+ * File ares_build.h is not present in the git tree.
+ *
+ * The distributed ares_build.h file is only intended to be used on systems
+ * which can not run the also distributed configure script.
+ *
+ * On systems capable of running the configure script, the configure process
+ * will overwrite the distributed ares_build.h file with one that is suitable
+ * and specific to the library being configured and built, which is generated
+ * from the ares_build.h.in template file.
+ *
+ * If you check out from git on a non-configure platform, you must run the
+ * appropriate buildconf* script to set up ares_build.h and other local files.
+ *
+ */
+
+/* ================================================================ */
+/*  DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE  */
+/* ================================================================ */
+
+#ifdef CARES_SIZEOF_LONG
+#  error "CARES_SIZEOF_LONG shall not be defined except in ares_build.h"
+   Error Compilation_aborted_CARES_SIZEOF_LONG_already_defined
+#endif
+
+#ifdef CARES_TYPEOF_ARES_SOCKLEN_T
+#  error "CARES_TYPEOF_ARES_SOCKLEN_T shall not be defined except in ares_build.h"
+   Error Compilation_aborted_CARES_TYPEOF_ARES_SOCKLEN_T_already_defined
+#endif
+
+#ifdef CARES_SIZEOF_ARES_SOCKLEN_T
+#  error "CARES_SIZEOF_ARES_SOCKLEN_T shall not be defined except in ares_build.h"
+   Error Compilation_aborted_CARES_SIZEOF_ARES_SOCKLEN_T_already_defined
+#endif
+
+/* ================================================================ */
+/*    EXTERNAL INTERFACE SETTINGS FOR NON-CONFIGURE SYSTEMS ONLY    */
+/* ================================================================ */
+
+#if defined(__DJGPP__) || defined(__GO32__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__SALFORDC__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__BORLANDC__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__TURBOC__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__WATCOMC__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__POCC__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__LCC__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__SYMBIAN32__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T unsigned int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__MWERKS__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(_WIN32_WCE)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__MINGW32__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__VMS)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T unsigned int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__OS400__)
+#  if defined(__ILEC400__)
+#    define CARES_SIZEOF_LONG           4
+#    define CARES_TYPEOF_ARES_SOCKLEN_T socklen_t
+#    define CARES_SIZEOF_ARES_SOCKLEN_T 4
+#    define CARES_PULL_SYS_TYPES_H      1
+#    define CARES_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(__MVS__)
+#  if defined(__IBMC__) || defined(__IBMCPP__)
+#    if defined(_ILP32)
+#      define CARES_SIZEOF_LONG           4
+#    elif defined(_LP64)
+#      define CARES_SIZEOF_LONG           8
+#    endif
+#    define CARES_TYPEOF_ARES_SOCKLEN_T socklen_t
+#    define CARES_SIZEOF_ARES_SOCKLEN_T 4
+#    define CARES_PULL_SYS_TYPES_H      1
+#    define CARES_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(__370__)
+#  if defined(__IBMC__) || defined(__IBMCPP__)
+#    if defined(_ILP32)
+#      define CARES_SIZEOF_LONG           4
+#    elif defined(_LP64)
+#      define CARES_SIZEOF_LONG           8
+#    endif
+#    define CARES_TYPEOF_ARES_SOCKLEN_T socklen_t
+#    define CARES_SIZEOF_ARES_SOCKLEN_T 4
+#    define CARES_PULL_SYS_TYPES_H      1
+#    define CARES_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(TPF)
+#  define CARES_SIZEOF_LONG           8
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+/* ===================================== */
+/*    KEEP MSVC THE PENULTIMATE ENTRY    */
+/* ===================================== */
+
+#elif defined(_MSC_VER)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+/* ===================================== */
+/*    KEEP GENERIC GCC THE LAST ENTRY    */
+/* ===================================== */
+
+#elif defined(__GNUC__)
+#  if defined(__LP64__) || \
+        defined(__x86_64__) || defined(__ppc64__)
+#    define CARES_SIZEOF_LONG           8
+#  elif defined(__ILP32__) || \
+      defined(__i386__) || defined(__ppc__) || defined(__arm__)
+#    define CARES_SIZEOF_LONG           4
+#  endif
+#  define CARES_TYPEOF_ARES_SOCKLEN_T socklen_t
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+#  define CARES_PULL_SYS_TYPES_H      1
+#  define CARES_PULL_SYS_SOCKET_H     1
+
+#else
+#  error "Unknown non-configure build target!"
+   Error Compilation_aborted_Unknown_non_configure_build_target
+#endif
+
+/* CARES_PULL_SYS_TYPES_H is defined above when inclusion of header file  */
+/* sys/types.h is required here to properly make type definitions below.  */
+#ifdef CARES_PULL_SYS_TYPES_H
+#  include <sys/types.h>
+#endif
+
+/* CARES_PULL_SYS_SOCKET_H is defined above when inclusion of header file  */
+/* sys/socket.h is required here to properly make type definitions below.  */
+#ifdef CARES_PULL_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+
+/* Data type definition of ares_socklen_t. */
+
+#ifdef CARES_TYPEOF_ARES_SOCKLEN_T
+  typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t;
+#endif
+
+/* Undefine UNICODE, as c-ares does not use the ANSI version of functions */
+/* explicitly. */
+#ifdef UNICODE
+#  undef UNICODE
+#endif
+
+#ifdef _UNICODE
+#  undef _UNICODE
+#endif
+
+#endif /* __CARES_BUILD_H */
diff --git a/third_party/cares/cares b/third_party/cares/cares
new file mode 160000
index 0000000000000000000000000000000000000000..7691f773af79bf75a62d1863fd0f13ebf9dc51b1
--- /dev/null
+++ b/third_party/cares/cares
@@ -0,0 +1 @@
+Subproject commit 7691f773af79bf75a62d1863fd0f13ebf9dc51b1
diff --git a/third_party/cares/cares.BUILD b/third_party/cares/cares.BUILD
new file mode 100644
index 0000000000000000000000000000000000000000..3583720ef3dc29f2cb573f591b1c4ea1898f1886
--- /dev/null
+++ b/third_party/cares/cares.BUILD
@@ -0,0 +1,103 @@
+config_setting(
+    name = "darwin",
+    values = {"cpu": "darwin"},
+)
+
+cc_library(
+    name = "ares",
+    srcs = [
+        "cares/ares__close_sockets.c",
+        "cares/ares__get_hostent.c",
+        "cares/ares__read_line.c",
+        "cares/ares__timeval.c",
+        "cares/ares_cancel.c",
+        "cares/ares_create_query.c",
+        "cares/ares_data.c",
+        "cares/ares_destroy.c",
+        "cares/ares_expand_name.c",
+        "cares/ares_expand_string.c",
+        "cares/ares_fds.c",
+        "cares/ares_free_hostent.c",
+        "cares/ares_free_string.c",
+        "cares/ares_getenv.c",
+        "cares/ares_gethostbyaddr.c",
+        "cares/ares_gethostbyname.c",
+        "cares/ares_getnameinfo.c",
+        "cares/ares_getopt.c",
+        "cares/ares_getsock.c",
+        "cares/ares_init.c",
+        "cares/ares_library_init.c",
+        "cares/ares_llist.c",
+        "cares/ares_mkquery.c",
+        "cares/ares_nowarn.c",
+        "cares/ares_options.c",
+        "cares/ares_parse_a_reply.c",
+        "cares/ares_parse_aaaa_reply.c",
+        "cares/ares_parse_mx_reply.c",
+        "cares/ares_parse_naptr_reply.c",
+        "cares/ares_parse_ns_reply.c",
+        "cares/ares_parse_ptr_reply.c",
+        "cares/ares_parse_soa_reply.c",
+        "cares/ares_parse_srv_reply.c",
+        "cares/ares_parse_txt_reply.c",
+        "cares/ares_platform.c",
+        "cares/ares_process.c",
+        "cares/ares_query.c",
+        "cares/ares_search.c",
+        "cares/ares_send.c",
+        "cares/ares_strcasecmp.c",
+        "cares/ares_strdup.c",
+        "cares/ares_strerror.c",
+        "cares/ares_timeout.c",
+        "cares/ares_version.c",
+        "cares/ares_writev.c",
+        "cares/bitncmp.c",
+        "cares/inet_net_pton.c",
+        "cares/inet_ntop.c",
+        "cares/windows_port.c",
+    ],
+    hdrs = [
+        "ares_build.h",
+        "cares/ares.h",
+        "cares/ares_data.h",
+        "cares/ares_dns.h",
+        "cares/ares_getenv.h",
+        "cares/ares_getopt.h",
+        "cares/ares_inet_net_pton.h",
+        "cares/ares_iphlpapi.h",
+        "cares/ares_ipv6.h",
+        "cares/ares_library_init.h",
+        "cares/ares_llist.h",
+        "cares/ares_nowarn.h",
+        "cares/ares_platform.h",
+        "cares/ares_private.h",
+        "cares/ares_rules.h",
+        "cares/ares_setup.h",
+        "cares/ares_strcasecmp.h",
+        "cares/ares_strdup.h",
+        "cares/ares_version.h",
+        "cares/bitncmp.h",
+        "cares/config-win32.h",
+        "cares/setup_once.h",
+    ] + select({
+        ":darwin": ["config_darwin/ares_config.h"],
+        "//conditions:default": ["config_linux/ares_config.h"],
+    }),
+    includes = [
+        ".",
+        "cares"
+    ] + select({
+        ":darwin": ["config_darwin"],
+        "//conditions:default": ["config_linux"],
+    }),
+    linkstatic = 1,
+    visibility = [
+        "//visibility:public",
+    ],
+    copts = [
+        "-D_GNU_SOURCE",
+        "-D_HAS_EXCEPTIONS=0",
+        "-DNOMINMAX",
+        "-DHAVE_CONFIG_H",
+    ],
+)
diff --git a/third_party/cares/config_darwin/ares_config.h b/third_party/cares/config_darwin/ares_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..0f5bd4b6a537845ed7136859a803f24fe4dc5102
--- /dev/null
+++ b/third_party/cares/config_darwin/ares_config.h
@@ -0,0 +1,523 @@
+/* ares_config.h.  Generated from ares_config.h.in by configure.  */
+/* ares_config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* define this if ares is built for a big endian system */
+/* #undef ARES_BIG_ENDIAN */
+
+/* when building as static part of libcurl */
+/* #undef BUILDING_LIBCURL */
+
+/* Defined for build that exposes internal static functions for testing. */
+/* #undef CARES_EXPOSE_STATICS */
+
+/* Defined for build with symbol hiding. */
+#define CARES_SYMBOL_HIDING 1
+
+/* Definition to make a library symbol externally visible. */
+#define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((__visibility__ ("default")))
+
+/* Use resolver library to configure cares */
+/* #undef CARES_USE_LIBRESOLV */
+
+/* if a /etc/inet dir is being used */
+/* #undef ETC_INET */
+
+/* Define to the type of arg 2 for gethostname. */
+#define GETHOSTNAME_TYPE_ARG2 size_t
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 const
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 socklen_t
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 int
+
+/* Specifies the number of arguments to getservbyport_r */
+/* #undef GETSERVBYPORT_R_ARGS */
+
+/* Specifies the size of the buffer to pass to getservbyport_r */
+/* #undef GETSERVBYPORT_R_BUFSIZE */
+
+/* Define to 1 if you have AF_INET6. */
+#define HAVE_AF_INET6 1
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/nameser_compat.h> header file. */
+#define HAVE_ARPA_NAMESER_COMPAT_H 1
+
+/* Define to 1 if you have the <arpa/nameser.h> header file. */
+#define HAVE_ARPA_NAMESER_H 1
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the `bitncmp' function. */
+/* #undef HAVE_BITNCMP */
+
+/* Define to 1 if bool is an available type. */
+#define HAVE_BOOL_T 1
+
+/* Define to 1 if you have the clock_gettime function and monotonic timer. */
+/* #undef HAVE_CLOCK_GETTIME_MONOTONIC */
+
+/* Define to 1 if you have the closesocket function. */
+/* #undef HAVE_CLOSESOCKET */
+
+/* Define to 1 if you have the CloseSocket camel case function. */
+/* #undef HAVE_CLOSESOCKET_CAMEL */
+
+/* Define to 1 if you have the connect function. */
+#define HAVE_CONNECT 1
+
+/* define if the compiler supports basic C++11 syntax */
+#define HAVE_CXX11 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the fcntl function. */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
+#define HAVE_FCNTL_O_NONBLOCK 1
+
+/* Define to 1 if you have the freeaddrinfo function. */
+#define HAVE_FREEADDRINFO 1
+
+/* Define to 1 if you have a working getaddrinfo function. */
+#define HAVE_GETADDRINFO 1
+
+/* Define to 1 if the getaddrinfo function is threadsafe. */
+#define HAVE_GETADDRINFO_THREADSAFE 1
+
+/* Define to 1 if you have the getenv function. */
+#define HAVE_GETENV 1
+
+/* Define to 1 if you have the gethostbyaddr function. */
+#define HAVE_GETHOSTBYADDR 1
+
+/* Define to 1 if you have the gethostbyname function. */
+#define HAVE_GETHOSTBYNAME 1
+
+/* Define to 1 if you have the gethostname function. */
+#define HAVE_GETHOSTNAME 1
+
+/* Define to 1 if you have the getnameinfo function. */
+#define HAVE_GETNAMEINFO 1
+
+/* Define to 1 if you have the getservbyport_r function. */
+/* #undef HAVE_GETSERVBYPORT_R */
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have the `if_indextoname' function. */
+#define HAVE_IF_INDEXTONAME 1
+
+/* Define to 1 if you have a IPv6 capable working inet_net_pton function. */
+#define HAVE_INET_NET_PTON 1
+
+/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
+#define HAVE_INET_NTOP 1
+
+/* Define to 1 if you have a IPv6 capable working inet_pton function. */
+#define HAVE_INET_PTON 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the ioctl function. */
+#define HAVE_IOCTL 1
+
+/* Define to 1 if you have the ioctlsocket function. */
+/* #undef HAVE_IOCTLSOCKET */
+
+/* Define to 1 if you have the IoctlSocket camel case function. */
+/* #undef HAVE_IOCTLSOCKET_CAMEL */
+
+/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function.
+   */
+/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
+
+/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
+/* #undef HAVE_IOCTLSOCKET_FIONBIO */
+
+/* Define to 1 if you have a working ioctl FIONBIO function. */
+#define HAVE_IOCTL_FIONBIO 1
+
+/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */
+#define HAVE_IOCTL_SIOCGIFADDR 1
+
+/* Define to 1 if you have the `resolve' library (-lresolve). */
+/* #undef HAVE_LIBRESOLVE */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* if your compiler supports LL */
+#define HAVE_LL 1
+
+/* Define to 1 if the compiler supports the 'long long' data type. */
+#define HAVE_LONGLONG 1
+
+/* Define to 1 if you have the malloc.h header file. */
+/* #undef HAVE_MALLOC_H */
+
+/* Define to 1 if you have the memory.h header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the MSG_NOSIGNAL flag. */
+/* #undef HAVE_MSG_NOSIGNAL */
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+#define HAVE_NETINET_TCP_H 1
+
+/* Define to 1 if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H 1
+
+/* Define to 1 if you have PF_INET6. */
+#define HAVE_PF_INET6 1
+
+/* Define to 1 if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to 1 if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to 1 if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to 1 if you have the setsockopt function. */
+#define HAVE_SETSOCKOPT 1
+
+/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
+/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T 1
+
+/* Define to 1 if sig_atomic_t is already defined as volatile. */
+/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
+
+/* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* Define to 1 if you have the socket function. */
+#define HAVE_SOCKET 1
+
+/* Define to 1 if you have the <socket.h> header file. */
+/* #undef HAVE_SOCKET_H */
+
+/* Define to 1 if you have the <stdbool.h> header file. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the strcasecmp function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the strcmpi function. */
+/* #undef HAVE_STRCMPI */
+
+/* Define to 1 if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the stricmp function. */
+/* #undef HAVE_STRICMP */
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the strncasecmp function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the strncmpi function. */
+/* #undef HAVE_STRNCMPI */
+
+/* Define to 1 if you have the strnicmp function. */
+/* #undef HAVE_STRNICMP */
+
+/* Define to 1 if you have the <stropts.h> header file. */
+/* #undef HAVE_STROPTS_H */
+
+/* Define to 1 if you have struct addrinfo. */
+#define HAVE_STRUCT_ADDRINFO 1
+
+/* Define to 1 if you have struct in6_addr. */
+#define HAVE_STRUCT_IN6_ADDR 1
+
+/* Define to 1 if you have struct sockaddr_in6. */
+#define HAVE_STRUCT_SOCKADDR_IN6 1
+
+/* if struct sockaddr_storage is defined */
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+
+/* Define to 1 if you have the timeval struct. */
+#define HAVE_STRUCT_TIMEVAL 1
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the windows.h header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Define to 1 if you have the winsock2.h header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* Define to 1 if you have the winsock.h header file. */
+/* #undef HAVE_WINSOCK_H */
+
+/* Define to 1 if you have the writev function. */
+#define HAVE_WRITEV 1
+
+/* Define to 1 if you have the ws2tcpip.h header file. */
+/* #undef HAVE_WS2TCPIP_H */
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Define to 1 if you need the malloc.h header file even with stdlib.h */
+/* #undef NEED_MALLOC_H */
+
+/* Define to 1 if you need the memory.h header file even with stdlib.h */
+/* #undef NEED_MEMORY_H */
+
+/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
+/* #undef NEED_REENTRANT */
+
+/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */
+/* #undef NEED_THREAD_SAFE */
+
+/* cpu-machine-OS */
+#define OS "i386-apple-darwin9.8.0"
+
+/* Name of package */
+#define PACKAGE "c-ares"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "c-ares mailing list: http://cool.haxx.se/mailman/listinfo/c-ares"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "c-ares"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "c-ares -"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "c-ares"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "-"
+
+/* a suitable file/device to read random data from */
+#define RANDOM_FILE "/dev/urandom"
+
+/* Define to the type qualifier pointed by arg 5 for recvfrom. */
+#define RECVFROM_QUAL_ARG5
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 int
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 void
+
+/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */
+#define RECVFROM_TYPE_ARG2_IS_VOID 1
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */
+/* #undef RECVFROM_TYPE_ARG5_IS_VOID */
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 socklen_t
+
+/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */
+/* #undef RECVFROM_TYPE_ARG6_IS_VOID */
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV ssize_t
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV ssize_t
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV ssize_t
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 4
+
+/* The size of `struct in6_addr', as computed by sizeof. */
+#define SIZEOF_STRUCT_IN6_ADDR 16
+
+/* The size of `struct in_addr', as computed by sizeof. */
+#define SIZEOF_STRUCT_IN_ADDR 4
+
+/* The size of `time_t', as computed by sizeof. */
+#define SIZEOF_TIME_T 4
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to disable non-blocking sockets. */
+/* #undef USE_BLOCKING_SOCKETS */
+
+/* Version number of package */
+#define VERSION "-"
+
+/* Define to avoid automatic inclusion of winsock.h */
+/* #undef WIN32_LEAN_AND_MEAN */
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* #  undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Define to 1 if OS is AIX. */
+#ifndef _ALL_SOURCE
+/* #  undef _ALL_SOURCE */
+#endif
+
+/* Enable large inode numbers on Mac OS X 10.5.  */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Type to use in place of in_addr_t when system does not provide it. */
+/* #undef in_addr_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* the signed version of size_t */
+/* #undef ssize_t */
diff --git a/third_party/cares/config_freebsd/ares_config.h b/third_party/cares/config_freebsd/ares_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..605db129e2f40eb626bc6fe35fea0c48d07f4c9e
--- /dev/null
+++ b/third_party/cares/config_freebsd/ares_config.h
@@ -0,0 +1,502 @@
+/* ares_config.h.  Generated from ares_config.h.in by configure.  */
+/* ares_config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* define this if ares is built for a big endian system */
+/* #undef ARES_BIG_ENDIAN */
+
+/* when building as static part of libcurl */
+/* #undef BUILDING_LIBCURL */
+
+/* Defined for build that exposes internal static functions for testing. */
+/* #undef CARES_EXPOSE_STATICS */
+
+/* Defined for build with symbol hiding. */
+#define CARES_SYMBOL_HIDING 1
+
+/* Definition to make a library symbol externally visible. */
+#define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((__visibility__ ("default")))
+
+/* Use resolver library to configure cares */
+/* #undef CARES_USE_LIBRESOLV */
+
+/* if a /etc/inet dir is being used */
+/* #undef ETC_INET */
+
+/* Define to the type of arg 2 for gethostname. */
+#define GETHOSTNAME_TYPE_ARG2 size_t
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 const
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 size_t
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 int
+
+/* Specifies the number of arguments to getservbyport_r */
+#define GETSERVBYPORT_R_ARGS 6
+
+/* Specifies the size of the buffer to pass to getservbyport_r */
+#define GETSERVBYPORT_R_BUFSIZE 4096
+
+/* Define to 1 if you have AF_INET6. */
+#define HAVE_AF_INET6 1
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/nameser_compat.h> header file. */
+#define HAVE_ARPA_NAMESER_COMPAT_H 1
+
+/* Define to 1 if you have the <arpa/nameser.h> header file. */
+#define HAVE_ARPA_NAMESER_H 1
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the `bitncmp' function. */
+/* #undef HAVE_BITNCMP */
+
+/* Define to 1 if bool is an available type. */
+#define HAVE_BOOL_T 1
+
+/* Define to 1 if you have the clock_gettime function and monotonic timer. */
+#define HAVE_CLOCK_GETTIME_MONOTONIC 1
+
+/* Define to 1 if you have the closesocket function. */
+/* #undef HAVE_CLOSESOCKET */
+
+/* Define to 1 if you have the CloseSocket camel case function. */
+/* #undef HAVE_CLOSESOCKET_CAMEL */
+
+/* Define to 1 if you have the connect function. */
+#define HAVE_CONNECT 1
+
+/* define if the compiler supports basic C++11 syntax */
+#define HAVE_CXX11 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the fcntl function. */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
+#define HAVE_FCNTL_O_NONBLOCK 1
+
+/* Define to 1 if you have the freeaddrinfo function. */
+#define HAVE_FREEADDRINFO 1
+
+/* Define to 1 if you have a working getaddrinfo function. */
+#define HAVE_GETADDRINFO 1
+
+/* Define to 1 if the getaddrinfo function is threadsafe. */
+#define HAVE_GETADDRINFO_THREADSAFE 1
+
+/* Define to 1 if you have the getenv function. */
+#define HAVE_GETENV 1
+
+/* Define to 1 if you have the gethostbyaddr function. */
+#define HAVE_GETHOSTBYADDR 1
+
+/* Define to 1 if you have the gethostbyname function. */
+#define HAVE_GETHOSTBYNAME 1
+
+/* Define to 1 if you have the gethostname function. */
+#define HAVE_GETHOSTNAME 1
+
+/* Define to 1 if you have the getnameinfo function. */
+#define HAVE_GETNAMEINFO 1
+
+/* Define to 1 if you have the getservbyport_r function. */
+#define HAVE_GETSERVBYPORT_R 1
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have the `if_indextoname' function. */
+#define HAVE_IF_INDEXTONAME 1
+
+/* Define to 1 if you have a IPv6 capable working inet_net_pton function. */
+#define HAVE_INET_NET_PTON 1
+
+/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
+#define HAVE_INET_NTOP 1
+
+/* Define to 1 if you have a IPv6 capable working inet_pton function. */
+#define HAVE_INET_PTON 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the ioctl function. */
+#define HAVE_IOCTL 1
+
+/* Define to 1 if you have the ioctlsocket function. */
+/* #undef HAVE_IOCTLSOCKET */
+
+/* Define to 1 if you have the IoctlSocket camel case function. */
+/* #undef HAVE_IOCTLSOCKET_CAMEL */
+
+/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function.
+   */
+/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
+
+/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
+/* #undef HAVE_IOCTLSOCKET_FIONBIO */
+
+/* Define to 1 if you have a working ioctl FIONBIO function. */
+#define HAVE_IOCTL_FIONBIO 1
+
+/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */
+#define HAVE_IOCTL_SIOCGIFADDR 1
+
+/* Define to 1 if you have the `resolve' library (-lresolve). */
+/* #undef HAVE_LIBRESOLVE */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* if your compiler supports LL */
+#define HAVE_LL 1
+
+/* Define to 1 if the compiler supports the 'long long' data type. */
+#define HAVE_LONGLONG 1
+
+/* Define to 1 if you have the malloc.h header file. */
+/* #undef HAVE_MALLOC_H */
+
+/* Define to 1 if you have the memory.h header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the MSG_NOSIGNAL flag. */
+#define HAVE_MSG_NOSIGNAL 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+#define HAVE_NETINET_TCP_H 1
+
+/* Define to 1 if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H 1
+
+/* Define to 1 if you have PF_INET6. */
+#define HAVE_PF_INET6 1
+
+/* Define to 1 if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to 1 if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to 1 if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to 1 if you have the setsockopt function. */
+#define HAVE_SETSOCKOPT 1
+
+/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
+/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T 1
+
+/* Define to 1 if sig_atomic_t is already defined as volatile. */
+/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
+
+/* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* Define to 1 if you have the socket function. */
+#define HAVE_SOCKET 1
+
+/* Define to 1 if you have the <socket.h> header file. */
+/* #undef HAVE_SOCKET_H */
+
+/* Define to 1 if you have the <stdbool.h> header file. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the strcasecmp function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the strcmpi function. */
+/* #undef HAVE_STRCMPI */
+
+/* Define to 1 if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the stricmp function. */
+/* #undef HAVE_STRICMP */
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the strncasecmp function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the strncmpi function. */
+/* #undef HAVE_STRNCMPI */
+
+/* Define to 1 if you have the strnicmp function. */
+/* #undef HAVE_STRNICMP */
+
+/* Define to 1 if you have the <stropts.h> header file. */
+/* #undef HAVE_STROPTS_H */
+
+/* Define to 1 if you have struct addrinfo. */
+#define HAVE_STRUCT_ADDRINFO 1
+
+/* Define to 1 if you have struct in6_addr. */
+#define HAVE_STRUCT_IN6_ADDR 1
+
+/* Define to 1 if you have struct sockaddr_in6. */
+#define HAVE_STRUCT_SOCKADDR_IN6 1
+
+/* if struct sockaddr_storage is defined */
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+
+/* Define to 1 if you have the timeval struct. */
+#define HAVE_STRUCT_TIMEVAL 1
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the windows.h header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Define to 1 if you have the winsock2.h header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* Define to 1 if you have the winsock.h header file. */
+/* #undef HAVE_WINSOCK_H */
+
+/* Define to 1 if you have the writev function. */
+#define HAVE_WRITEV 1
+
+/* Define to 1 if you have the ws2tcpip.h header file. */
+/* #undef HAVE_WS2TCPIP_H */
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Define to 1 if you need the malloc.h header file even with stdlib.h */
+/* #undef NEED_MALLOC_H */
+
+/* Define to 1 if you need the memory.h header file even with stdlib.h */
+/* #undef NEED_MEMORY_H */
+
+/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
+/* #undef NEED_REENTRANT */
+
+/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */
+/* #undef NEED_THREAD_SAFE */
+
+/* cpu-machine-OS */
+#define OS "amd64-unknown-freebsd10.3"
+
+/* Name of package */
+#define PACKAGE "c-ares"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "c-ares mailing list: http://cool.haxx.se/mailman/listinfo/c-ares"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "c-ares"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "c-ares -"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "c-ares"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "-"
+
+/* a suitable file/device to read random data from */
+#define RANDOM_FILE "/dev/urandom"
+
+/* Define to the type qualifier pointed by arg 5 for recvfrom. */
+#define RECVFROM_QUAL_ARG5 
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 int
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 void
+
+/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */
+#define RECVFROM_TYPE_ARG2_IS_VOID 1
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */
+/* #undef RECVFROM_TYPE_ARG5_IS_VOID */
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 socklen_t
+
+/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */
+/* #undef RECVFROM_TYPE_ARG6_IS_VOID */
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV ssize_t
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV ssize_t
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV ssize_t
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to disable non-blocking sockets. */
+/* #undef USE_BLOCKING_SOCKETS */
+
+/* Version number of package */
+#define VERSION "-"
+
+/* Define to avoid automatic inclusion of winsock.h */
+/* #undef WIN32_LEAN_AND_MEAN */
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* #  undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Define to 1 if OS is AIX. */
+#ifndef _ALL_SOURCE
+/* #  undef _ALL_SOURCE */
+#endif
+
+/* Enable large inode numbers on Mac OS X 10.5.  */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Type to use in place of in_addr_t when system does not provide it. */
+/* #undef in_addr_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* the signed version of size_t */
+/* #undef ssize_t */
diff --git a/third_party/cares/config_linux/ares_config.h b/third_party/cares/config_linux/ares_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..265974cfae442812955a5913dfe08c1d796e920a
--- /dev/null
+++ b/third_party/cares/config_linux/ares_config.h
@@ -0,0 +1,524 @@
+/* ares_config.h.  Generated from ares_config.h.in by configure.  */
+/* ares_config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* define this if ares is built for a big endian system */
+/* #undef ARES_BIG_ENDIAN */
+
+/* when building as static part of libcurl */
+/* #undef BUILDING_LIBCURL */
+
+/* Defined for build that exposes internal static functions for testing. */
+/* #undef CARES_EXPOSE_STATICS */
+
+/* Defined for build with symbol hiding. */
+#define CARES_SYMBOL_HIDING 1
+
+/* Definition to make a library symbol externally visible. */
+#define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((__visibility__ ("default")))
+
+/* Use resolver library to configure cares */
+/* #undef CARES_USE_LIBRESOLV */
+
+/* if a /etc/inet dir is being used */
+/* #undef ETC_INET */
+
+/* Define to the type of arg 2 for gethostname. */
+#define GETHOSTNAME_TYPE_ARG2 size_t
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 const
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 socklen_t
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 int
+
+/* Specifies the number of arguments to getservbyport_r */
+#define GETSERVBYPORT_R_ARGS 6
+
+/* Specifies the size of the buffer to pass to getservbyport_r */
+#define GETSERVBYPORT_R_BUFSIZE 4096
+
+/* Define to 1 if you have AF_INET6. */
+#define HAVE_AF_INET6 1
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/nameser_compat.h> header file. */
+#define HAVE_ARPA_NAMESER_COMPAT_H 1
+
+/* Define to 1 if you have the <arpa/nameser.h> header file. */
+#define HAVE_ARPA_NAMESER_H 1
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the `bitncmp' function. */
+/* #undef HAVE_BITNCMP */
+
+/* Define to 1 if bool is an available type. */
+#define HAVE_BOOL_T 1
+
+/* Define to 1 if you have the clock_gettime function and monotonic timer. */
+#define HAVE_CLOCK_GETTIME_MONOTONIC 1
+
+/* Define to 1 if you have the closesocket function. */
+/* #undef HAVE_CLOSESOCKET */
+
+/* Define to 1 if you have the CloseSocket camel case function. */
+/* #undef HAVE_CLOSESOCKET_CAMEL */
+
+/* Define to 1 if you have the connect function. */
+#define HAVE_CONNECT 1
+
+/* define if the compiler supports basic C++11 syntax */
+#define HAVE_CXX11 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the fcntl function. */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
+#define HAVE_FCNTL_O_NONBLOCK 1
+
+/* Define to 1 if you have the freeaddrinfo function. */
+#define HAVE_FREEADDRINFO 1
+
+/* Define to 1 if you have a working getaddrinfo function. */
+#define HAVE_GETADDRINFO 1
+
+/* Define to 1 if the getaddrinfo function is threadsafe. */
+#define HAVE_GETADDRINFO_THREADSAFE 1
+
+/* Define to 1 if you have the getenv function. */
+#define HAVE_GETENV 1
+
+/* Define to 1 if you have the gethostbyaddr function. */
+#define HAVE_GETHOSTBYADDR 1
+
+/* Define to 1 if you have the gethostbyname function. */
+#define HAVE_GETHOSTBYNAME 1
+
+/* Define to 1 if you have the gethostname function. */
+#define HAVE_GETHOSTNAME 1
+
+/* Define to 1 if you have the getnameinfo function. */
+#define HAVE_GETNAMEINFO 1
+
+/* Define to 1 if you have the getservbyport_r function. */
+#define HAVE_GETSERVBYPORT_R 1
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have the `if_indextoname' function. */
+#define HAVE_IF_INDEXTONAME 1
+
+/* Define to 1 if you have a IPv6 capable working inet_net_pton function. */
+/* #undef HAVE_INET_NET_PTON */
+
+/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
+#define HAVE_INET_NTOP 1
+
+/* Define to 1 if you have a IPv6 capable working inet_pton function. */
+#define HAVE_INET_PTON 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the ioctl function. */
+#define HAVE_IOCTL 1
+
+/* Define to 1 if you have the ioctlsocket function. */
+/* #undef HAVE_IOCTLSOCKET */
+
+/* Define to 1 if you have the IoctlSocket camel case function. */
+/* #undef HAVE_IOCTLSOCKET_CAMEL */
+
+/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function.
+   */
+/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
+
+/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
+/* #undef HAVE_IOCTLSOCKET_FIONBIO */
+
+/* Define to 1 if you have a working ioctl FIONBIO function. */
+#define HAVE_IOCTL_FIONBIO 1
+
+/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */
+#define HAVE_IOCTL_SIOCGIFADDR 1
+
+/* Define to 1 if you have the `resolve' library (-lresolve). */
+/* #undef HAVE_LIBRESOLVE */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* if your compiler supports LL */
+#define HAVE_LL 1
+
+/* Define to 1 if the compiler supports the 'long long' data type. */
+#define HAVE_LONGLONG 1
+
+/* Define to 1 if you have the malloc.h header file. */
+#define HAVE_MALLOC_H 1
+
+/* Define to 1 if you have the memory.h header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the MSG_NOSIGNAL flag. */
+#define HAVE_MSG_NOSIGNAL 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+#define HAVE_NETINET_TCP_H 1
+
+/* Define to 1 if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H 1
+
+/* Define to 1 if you have PF_INET6. */
+#define HAVE_PF_INET6 1
+
+/* Define to 1 if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to 1 if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to 1 if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to 1 if you have the setsockopt function. */
+#define HAVE_SETSOCKOPT 1
+
+/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
+/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T 1
+
+/* Define to 1 if sig_atomic_t is already defined as volatile. */
+/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
+
+/* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* Define to 1 if you have the socket function. */
+#define HAVE_SOCKET 1
+
+/* Define to 1 if you have the <socket.h> header file. */
+/* #undef HAVE_SOCKET_H */
+
+/* Define to 1 if you have the <stdbool.h> header file. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the strcasecmp function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the strcmpi function. */
+/* #undef HAVE_STRCMPI */
+
+/* Define to 1 if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the stricmp function. */
+/* #undef HAVE_STRICMP */
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the strncasecmp function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the strncmpi function. */
+/* #undef HAVE_STRNCMPI */
+
+/* Define to 1 if you have the strnicmp function. */
+/* #undef HAVE_STRNICMP */
+
+/* Define to 1 if you have the <stropts.h> header file. */
+#define HAVE_STROPTS_H 1
+
+/* Define to 1 if you have struct addrinfo. */
+#define HAVE_STRUCT_ADDRINFO 1
+
+/* Define to 1 if you have struct in6_addr. */
+#define HAVE_STRUCT_IN6_ADDR 1
+
+/* Define to 1 if you have struct sockaddr_in6. */
+#define HAVE_STRUCT_SOCKADDR_IN6 1
+
+/* if struct sockaddr_storage is defined */
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+
+/* Define to 1 if you have the timeval struct. */
+#define HAVE_STRUCT_TIMEVAL 1
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the windows.h header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Define to 1 if you have the winsock2.h header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* Define to 1 if you have the winsock.h header file. */
+/* #undef HAVE_WINSOCK_H */
+
+/* Define to 1 if you have the writev function. */
+#define HAVE_WRITEV 1
+
+/* Define to 1 if you have the ws2tcpip.h header file. */
+/* #undef HAVE_WS2TCPIP_H */
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#define LT_OBJDIR ".libs/"
+
+/* Define to 1 if you need the malloc.h header file even with stdlib.h */
+/* #undef NEED_MALLOC_H */
+
+/* Define to 1 if you need the memory.h header file even with stdlib.h */
+/* #undef NEED_MEMORY_H */
+
+/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
+/* #undef NEED_REENTRANT */
+
+/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */
+/* #undef NEED_THREAD_SAFE */
+
+/* cpu-machine-OS */
+#define OS "i386-unknown-linux-gnu"
+
+/* Name of package */
+#define PACKAGE "c-ares"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "c-ares mailing list: http://cool.haxx.se/mailman/listinfo/c-ares"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "c-ares"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "c-ares -"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "c-ares"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "-"
+
+/* a suitable file/device to read random data from */
+#define RANDOM_FILE "/dev/urandom"
+
+/* Define to the type qualifier pointed by arg 5 for recvfrom. */
+#define RECVFROM_QUAL_ARG5 
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 int
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 void
+
+/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */
+#define RECVFROM_TYPE_ARG2_IS_VOID 1
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */
+/* #undef RECVFROM_TYPE_ARG5_IS_VOID */
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 socklen_t
+
+/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */
+/* #undef RECVFROM_TYPE_ARG6_IS_VOID */
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV ssize_t
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV ssize_t
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV ssize_t
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 4
+
+/* The size of `struct in6_addr', as computed by sizeof. */
+#define SIZEOF_STRUCT_IN6_ADDR 16
+
+/* The size of `struct in_addr', as computed by sizeof. */
+#define SIZEOF_STRUCT_IN_ADDR 4
+
+/* The size of `time_t', as computed by sizeof. */
+#define SIZEOF_TIME_T 4
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to disable non-blocking sockets. */
+/* #undef USE_BLOCKING_SOCKETS */
+
+/* Version number of package */
+#define VERSION "-"
+
+/* Define to avoid automatic inclusion of winsock.h */
+/* #undef WIN32_LEAN_AND_MEAN */
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* #  undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Define to 1 if OS is AIX. */
+#ifndef _ALL_SOURCE
+/* #  undef _ALL_SOURCE */
+#endif
+
+/* Enable large inode numbers on Mac OS X 10.5.  */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Type to use in place of in_addr_t when system does not provide it. */
+/* #undef in_addr_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* the signed version of size_t */
+/* #undef ssize_t */
diff --git a/third_party/googletest b/third_party/googletest
index c99458533a9b4c743ed51537e25989ea55944908..ec44c6c1675c25b9827aacd08c02433cccde7780 160000
--- a/third_party/googletest
+++ b/third_party/googletest
@@ -1 +1 @@
-Subproject commit c99458533a9b4c743ed51537e25989ea55944908
+Subproject commit ec44c6c1675c25b9827aacd08c02433cccde7780
diff --git a/third_party/gtest.BUILD b/third_party/gtest.BUILD
index a07db65b91b2732eeecdb6e0682ee1b2e2b910da..b70f2c51bcf3c1c7b7f943a1eee406c208f5400c 100644
--- a/third_party/gtest.BUILD
+++ b/third_party/gtest.BUILD
@@ -1,11 +1,15 @@
 cc_library(
     name = "gtest",
     srcs = [
-        "src/gtest-all.cc",
+        "googletest/src/gtest-all.cc",
+	"googlemock/src/gmock-all.cc"
     ],
-    hdrs = glob(["include/**/*.h", "src/*.cc", "src/*.h"]),
+    hdrs = glob(["googletest/include/**/*.h", "googletest/src/*.cc", "googletest/src/*.h", "googlemock/include/**/*.h", "googlemock/src/*.cc", "googlemock/src/*.h"]),
     includes = [
-        "include",
+        "googletest",
+        "googletest/include",
+	"googlemock",
+	"googlemock/include",
     ],
     linkstatic = 1,
     visibility = [
diff --git a/third_party/protobuf b/third_party/protobuf
index a428e42072765993ff674fda72863c9f1aa2d268..593e917c176b5bc5aafa57bf9f6030d749d91cd5 160000
--- a/third_party/protobuf
+++ b/third_party/protobuf
@@ -1 +1 @@
-Subproject commit a428e42072765993ff674fda72863c9f1aa2d268
+Subproject commit 593e917c176b5bc5aafa57bf9f6030d749d91cd5
diff --git a/third_party/thrift b/third_party/thrift
deleted file mode 160000
index bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c..0000000000000000000000000000000000000000
--- a/third_party/thrift
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c
diff --git a/third_party/zlib b/third_party/zlib
index 50893291621658f355bc5b4d450a8d06a563053d..cacf7f1d4e3d44d871b605da3b647f07d718623f 160000
--- a/third_party/zlib
+++ b/third_party/zlib
@@ -1 +1 @@
-Subproject commit 50893291621658f355bc5b4d450a8d06a563053d
+Subproject commit cacf7f1d4e3d44d871b605da3b647f07d718623f
diff --git a/tools/README.md b/tools/README.md
index d051846c33ea07b5e370cfd903c5d3fb3001d6d1..62e91246d0a41b56f8ad0334bf0d115602af36fb 100644
--- a/tools/README.md
+++ b/tools/README.md
@@ -16,3 +16,6 @@ internal_ci: Support for running tests on an internal CI platform.
 jenkins: Support for running tests on Jenkins.
 
 run_tests: Scripts to run gRPC tests in parallel.
+
+run_tests/performance: See the [README](./run_tests/performance/README.md) for
+more notes on the performance tests.
diff --git a/tools/buildgen/generate_build_additions.sh b/tools/buildgen/generate_build_additions.sh
index a4373ed350319f4e221bb0eac7fc7ea376b2f843..9b5e2113af855a3d58a29fab3d0506501bc19169 100644
--- a/tools/buildgen/generate_build_additions.sh
+++ b/tools/buildgen/generate_build_additions.sh
@@ -35,6 +35,7 @@ gen_build_yaml_dirs="  \
   src/benchmark \
   src/proto            \
   src/zlib             \
+  src/c-ares           \
   test/core/bad_client \
   test/core/bad_ssl    \
   test/core/end2end    \
diff --git a/tools/buildgen/plugins/expand_bin_attrs.py b/tools/buildgen/plugins/expand_bin_attrs.py
index dc72bf3b9d1370f9f549096bdfe671f24b0b9f27..f52168a9d3728fa649342c2f44a48416a2926dfc 100755
--- a/tools/buildgen/plugins/expand_bin_attrs.py
+++ b/tools/buildgen/plugins/expand_bin_attrs.py
@@ -52,9 +52,11 @@ def mako_plugin(dictionary):
     tgt['ci_platforms'] = sorted(tgt.get('ci_platforms', tgt['platforms']))
     tgt['boringssl'] = tgt.get('boringssl', False)
     tgt['zlib'] = tgt.get('zlib', False)
+    tgt['ares'] = tgt.get('ares', False)
     tgt['gtest'] = tgt.get('gtest', False)
 
   libs = dictionary.get('libs')
   for lib in libs:
     lib['boringssl'] = lib.get('boringssl', False)
     lib['zlib'] = lib.get('zlib', False)
+    lib['ares'] = lib.get('ares', False)
diff --git a/tools/buildgen/plugins/expand_filegroups.py b/tools/buildgen/plugins/expand_filegroups.py
index 46739f8f1006865ec1f01ccdb6cbb9c7c87a8148..9eaba463ec0b2cf448859d1a937b9a8d800d3f8b 100755
--- a/tools/buildgen/plugins/expand_filegroups.py
+++ b/tools/buildgen/plugins/expand_filegroups.py
@@ -57,6 +57,7 @@ FILEGROUP_DEFAULTS = {
   'language': 'c',
   'boringssl': False,
   'zlib': False,
+  'ares': False,
 }
 
 
diff --git a/tools/buildgen/plugins/make_fuzzer_tests.py b/tools/buildgen/plugins/make_fuzzer_tests.py
index ba9825acb91244c7cbc8d562aac7afda1f4fcfab..5fc28ddd31fd8cd74d1c96621b3eab1b0b9d5d06 100644
--- a/tools/buildgen/plugins/make_fuzzer_tests.py
+++ b/tools/buildgen/plugins/make_fuzzer_tests.py
@@ -52,7 +52,7 @@ def mako_plugin(dictionary):
               'exclude_iomgrs': ['uv'],
               'exclude_configs': ['tsan'],
               'uses_polling': False,
-              'platforms': ['linux'],
+              'platforms': ['mac', 'linux'],
               'ci_platforms': ['linux'],
               'flaky': False,
               'language': 'c',
diff --git a/tools/codegen/core/gen_nano_proto.sh b/tools/codegen/core/gen_nano_proto.sh
index 8600573e1cbdc0839947c8659b16d84e64cdbe1b..7bb9fc1cc4846a1d4ece952248f2ad67024e1ab0 100755
--- a/tools/codegen/core/gen_nano_proto.sh
+++ b/tools/codegen/core/gen_nano_proto.sh
@@ -32,8 +32,8 @@
 # Example usage:
 #   tools/codegen/core/gen_nano_proto.sh \
 #     src/proto/grpc/lb/v1/load_balancer.proto \
-#     $PWD/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1 \
-#     src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1
+#     $PWD/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1 \
+#     src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1
 #
 # Exit statuses:
 # 1: Incorrect number of arguments
diff --git a/tools/codegen/core/gen_settings_ids.py b/tools/codegen/core/gen_settings_ids.py
new file mode 100755
index 0000000000000000000000000000000000000000..a9861383371fb16e4588ffe0f023f9730e10b7e5
--- /dev/null
+++ b/tools/codegen/core/gen_settings_ids.py
@@ -0,0 +1,184 @@
+#!/usr/bin/env python2.7
+
+# Copyright 2017, 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 collections
+import perfection
+import sys
+
+_MAX_HEADER_LIST_SIZE = 16 * 1024 * 1024
+
+Setting = collections.namedtuple('Setting', 'id default min max on_error')
+OnError = collections.namedtuple('OnError', 'behavior code')
+clamp_invalid_value = OnError('CLAMP_INVALID_VALUE', 'PROTOCOL_ERROR')
+disconnect_on_invalid_value = lambda e: OnError('DISCONNECT_ON_INVALID_VALUE', e)
+DecoratedSetting = collections.namedtuple('DecoratedSetting', 'enum name setting')
+
+_SETTINGS = {
+  'HEADER_TABLE_SIZE': Setting(1, 4096, 0, 0xffffffff, clamp_invalid_value),
+  'ENABLE_PUSH': Setting(2, 1, 0, 1, disconnect_on_invalid_value('PROTOCOL_ERROR')),
+  'MAX_CONCURRENT_STREAMS': Setting(3, 0xffffffff, 0, 0xffffffff, disconnect_on_invalid_value('PROTOCOL_ERROR')),
+  'INITIAL_WINDOW_SIZE': Setting(4, 65535, 0, 0x7fffffff, disconnect_on_invalid_value('FLOW_CONTROL_ERROR')),
+  'MAX_FRAME_SIZE': Setting(5, 16384, 16384, 16777215, disconnect_on_invalid_value('PROTOCOL_ERROR')),
+  'MAX_HEADER_LIST_SIZE': Setting(6, _MAX_HEADER_LIST_SIZE, 0, _MAX_HEADER_LIST_SIZE, clamp_invalid_value),
+  'GRPC_ALLOW_TRUE_BINARY_METADATA': Setting(0xfe03, 0, 0, 1, clamp_invalid_value),
+}
+
+H = open('src/core/ext/transport/chttp2/transport/http2_settings.h', 'w')
+C = open('src/core/ext/transport/chttp2/transport/http2_settings.c', 'w')
+
+# utility: print a big comment block into a set of files
+def put_banner(files, banner):
+  for f in files:
+    print >>f, '/*'
+    for line in banner:
+      print >>f, ' * %s' % line
+    print >>f, ' */'
+    print >>f
+
+# copy-paste copyright notice from this file
+with open(sys.argv[0]) as my_source:
+  copyright = []
+  for line in my_source:
+    if line[0] != '#': break
+  for line in my_source:
+    if line[0] == '#':
+      copyright.append(line)
+      break
+  for line in my_source:
+    if line[0] != '#':
+      break
+    copyright.append(line)
+  put_banner([H,C], [line[2:].rstrip() for line in copyright])
+
+put_banner([H,C], ["Automatically generated by tools/codegen/core/gen_settings_ids.py"])
+
+print >>H, "#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H"
+print >>H, "#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H"
+print >>H
+print >>H, "#include <stdint.h>"
+print >>H, "#include <stdbool.h>"
+print >>H
+
+print >>C, "#include \"src/core/ext/transport/chttp2/transport/http2_settings.h\""
+print >>C
+print >>C, "#include <grpc/support/useful.h>"
+print >>C, "#include \"src/core/lib/transport/http2_errors.h\""
+print >>C
+
+p = perfection.hash_parameters(sorted(x.id for x in _SETTINGS.values()))
+print p
+
+def hash(i):
+  i += p.offset
+  x = i % p.t
+  y = i / p.t
+  return x + p.r[y]
+
+decorated_settings = [DecoratedSetting(hash(setting.id), name, setting)
+                      for name, setting in _SETTINGS.iteritems()]
+
+print >>H, 'typedef enum {'
+for decorated_setting in sorted(decorated_settings):
+  print >>H, '  GRPC_CHTTP2_SETTINGS_%s = %d, /* wire id %d */' % (
+      decorated_setting.name, decorated_setting.enum, decorated_setting.setting.id)
+print >>H, '} grpc_chttp2_setting_id;'
+print >>H
+print >>H, '#define GRPC_CHTTP2_NUM_SETTINGS %d' % (max(x.enum for x in decorated_settings) + 1)
+
+print >>H, 'extern const uint16_t grpc_setting_id_to_wire_id[];'
+print >>C, 'const uint16_t grpc_setting_id_to_wire_id[] = {%s};' % ','.join(
+    '%d' % s for s in p.slots)
+print >>H
+print >>H, "bool grpc_wire_id_to_setting_id(uint32_t wire_id, grpc_chttp2_setting_id *out);"
+cgargs = {
+      'r': ','.join('%d' % (r if r is not None else 0) for r in p.r),
+      't': p.t,
+      'offset': abs(p.offset),
+      'offset_sign': '+' if p.offset > 0 else '-'
+  }
+print >>C, """
+bool grpc_wire_id_to_setting_id(uint32_t wire_id, grpc_chttp2_setting_id *out) {
+  uint32_t i = wire_id %(offset_sign)s %(offset)d;
+  uint32_t x = i %% %(t)d;
+  uint32_t y = i / %(t)d;
+  uint32_t h = x;
+  switch (y) {
+""" % cgargs
+for i, r in enumerate(p.r):
+  if not r: continue
+  if r < 0: print >>C, 'case %d: h -= %d; break;' % (i, -r)
+  else: print >>C, 'case %d: h += %d; break;' % (i, r)
+print >>C, """
+  }
+  *out = (grpc_chttp2_setting_id)h;
+  return h < GPR_ARRAY_SIZE(grpc_setting_id_to_wire_id) && grpc_setting_id_to_wire_id[h] == wire_id;
+}
+""" % cgargs
+
+print >>H, """
+typedef enum {
+  GRPC_CHTTP2_CLAMP_INVALID_VALUE,
+  GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE
+} grpc_chttp2_invalid_value_behavior;
+
+typedef struct {
+  const char *name;
+  uint32_t default_value;
+  uint32_t min_value;
+  uint32_t max_value;
+  grpc_chttp2_invalid_value_behavior invalid_value_behavior;
+  uint32_t error_value;
+} grpc_chttp2_setting_parameters;
+
+extern const grpc_chttp2_setting_parameters grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS];
+"""
+print >>C, "const grpc_chttp2_setting_parameters grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS] = {"
+i = 0
+for decorated_setting in sorted(decorated_settings):
+  while i < decorated_setting.enum:
+    print >>C, "{NULL, 0, 0, 0, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR},"
+    i += 1
+  print >>C, "{\"%s\", %du, %du, %du, GRPC_CHTTP2_%s, GRPC_HTTP2_%s}," % (
+    decorated_setting.name,
+    decorated_setting.setting.default,
+    decorated_setting.setting.min,
+    decorated_setting.setting.max,
+    decorated_setting.setting.on_error.behavior,
+    decorated_setting.setting.on_error.code,
+  )
+  i += 1
+print >>C, "};"
+
+print >>H
+print >>H, "#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H */"
+
+H.close()
+C.close()
diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py
index 109701f740b57753602c1eb2dc04d37c049e3bc6..360b0f56e9248c30e05909a2111b5c6f7cfca13c 100755
--- a/tools/codegen/core/gen_static_metadata.py
+++ b/tools/codegen/core/gen_static_metadata.py
@@ -56,8 +56,9 @@ CONFIG = [
     ':authority',
     'grpc-message',
     'grpc-status',
-    'grpc-tracing-bin',
-    'grpc-stats-bin',
+    'grpc-server-stats-bin',
+    'grpc-tags-bin',
+    'grpc-trace-bin',
     '',
     # channel arg keys
     'grpc.wait_for_ready',
@@ -123,6 +124,7 @@ CONFIG = [
     ('if-unmodified-since', ''),
     ('last-modified', ''),
     ('lb-token', ''),
+    ('lb-cost-bin', ''),
     ('link', ''),
     ('location', ''),
     ('max-forwards', ''),
@@ -154,6 +156,9 @@ METADATA_BATCH_CALLOUTS = [
     'grpc-payload-bin',
     'grpc-encoding',
     'grpc-accept-encoding',
+    'grpc-server-stats-bin',
+    'grpc-tags-bin',
+    'grpc-trace-bin',
     'content-type',
     'grpc-internal-encoding-request',
     'user-agent',
@@ -167,6 +172,7 @@ COMPRESSION_ALGORITHMS = [
     'gzip',
 ]
 
+
 # utility: mangle the name of a config
 def mangle(elem, name=None):
   xl = {
@@ -177,43 +183,56 @@ def mangle(elem, name=None):
       ',': 'comma',
       ' ': '_',
   }
+
   def m0(x):
-    if not x: return 'empty'
+    if not x:
+      return 'empty'
     r = ''
     for c in x:
       put = xl.get(c, c.lower())
-      if not put: continue
+      if not put:
+        continue
       last_is_underscore = r[-1] == '_' if r else True
-      if last_is_underscore and put == '_': continue
+      if last_is_underscore and put == '_':
+        continue
       elif len(put) > 1:
-        if not last_is_underscore: r += '_'
+        if not last_is_underscore:
+          r += '_'
         r += put
         r += '_'
       else:
         r += put
-    if r[-1] == '_': r = r[:-1]
+    if r[-1] == '_':
+      r = r[:-1]
     return r
+
   def n(default, name=name):
-    if name is None: return 'grpc_%s_' % default
-    if name == '': return ''
+    if name is None:
+      return 'grpc_%s_' % default
+    if name == '':
+      return ''
     return 'grpc_%s_' % name
+
   if isinstance(elem, tuple):
     return '%s%s_%s' % (n('mdelem'), m0(elem[0]), m0(elem[1]))
   else:
     return '%s%s' % (n('mdstr'), m0(elem))
 
+
 # utility: generate some hash value for a string
 def fake_hash(elem):
   return hashlib.md5(elem).hexdigest()[0:8]
 
+
 # utility: print a big comment block into a set of files
 def put_banner(files, banner):
   for f in files:
-    print >>f, '/*'
+    print >> f, '/*'
     for line in banner:
-      print >>f, ' * %s' % line
-    print >>f, ' */'
-    print >>f
+      print >> f, ' * %s' % line
+    print >> f, ' */'
+    print >> f
+
 
 # build a list of all the strings we need
 all_strs = list()
@@ -236,7 +255,7 @@ for elem in CONFIG:
     if elem not in all_strs:
       all_strs.append(elem)
 compression_elems = []
-for mask in range(1, 1<<len(COMPRESSION_ALGORITHMS)):
+for mask in range(1, 1 << len(COMPRESSION_ALGORITHMS)):
   val = ','.join(COMPRESSION_ALGORITHMS[alg]
                  for alg in range(0, len(COMPRESSION_ALGORITHMS))
                  if (1 << alg) & mask)
@@ -267,18 +286,25 @@ if args:
   else:
     D = open('/dev/null', 'w')
 else:
-  H = open(os.path.join(
-      os.path.dirname(sys.argv[0]), '../../../src/core/lib/transport/static_metadata.h'), 'w')
-  C = open(os.path.join(
-      os.path.dirname(sys.argv[0]), '../../../src/core/lib/transport/static_metadata.c'), 'w')
-  D = open(os.path.join(
-      os.path.dirname(sys.argv[0]), '../../../test/core/end2end/fuzzers/hpack.dictionary'), 'w')
+  H = open(
+      os.path.join(
+          os.path.dirname(sys.argv[0]),
+          '../../../src/core/lib/transport/static_metadata.h'), 'w')
+  C = open(
+      os.path.join(
+          os.path.dirname(sys.argv[0]),
+          '../../../src/core/lib/transport/static_metadata.c'), 'w')
+  D = open(
+      os.path.join(
+          os.path.dirname(sys.argv[0]),
+          '../../../test/core/end2end/fuzzers/hpack.dictionary'), 'w')
 
 # copy-paste copyright notice from this file
 with open(sys.argv[0]) as my_source:
   copyright = []
   for line in my_source:
-    if line[0] != '#': break
+    if line[0] != '#':
+      break
   for line in my_source:
     if line[0] == '#':
       copyright.append(line)
@@ -287,10 +313,9 @@ with open(sys.argv[0]) as my_source:
     if line[0] != '#':
       break
     copyright.append(line)
-  put_banner([H,C], [line[2:].rstrip() for line in copyright])
+  put_banner([H, C], [line[2:].rstrip() for line in copyright])
 
-
-hex_bytes = [ord(c) for c in "abcdefABCDEF0123456789"]
+hex_bytes = [ord(c) for c in 'abcdefABCDEF0123456789']
 
 
 def esc_dict(line):
@@ -302,11 +327,11 @@ def esc_dict(line):
       else:
         out += "\\\""
     else:
-      out += "\\x%02X" % c
+      out += '\\x%02X' % c
   return out + "\""
 
-put_banner([H,C],
-"""WARNING: Auto-generated code.
+
+put_banner([H, C], """WARNING: Auto-generated code.
 
 To make changes to this file, change
 tools/codegen/core/gen_static_metadata.py, and then re-run it.
@@ -315,108 +340,143 @@ See metadata.h for an explanation of the interface here, and metadata.c for
 an explanation of what's going on.
 """.splitlines())
 
-print >>H, '#ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H'
-print >>H, '#define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H'
-print >>H
-print >>H, '#include "src/core/lib/transport/metadata.h"'
-print >>H
+print >> H, '#ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H'
+print >> H, '#define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H'
+print >> H
+print >> H, '#include "src/core/lib/transport/metadata.h"'
+print >> H
 
-print >>C, '#include "src/core/lib/transport/static_metadata.h"'
-print >>C
-print >>C, '#include "src/core/lib/slice/slice_internal.h"'
-print >>C
+print >> C, '#include "src/core/lib/transport/static_metadata.h"'
+print >> C
+print >> C, '#include "src/core/lib/slice/slice_internal.h"'
+print >> C
 
 str_ofs = 0
 id2strofs = {}
 for i, elem in enumerate(all_strs):
   id2strofs[i] = str_ofs
-  str_ofs += len(elem);
+  str_ofs += len(elem)
+
+
 def slice_def(i):
-  return '{.refcount = &grpc_static_metadata_refcounts[%d], .data.refcounted = {g_bytes+%d, %d}}' % (i, id2strofs[i], len(all_strs[i]))
+  return ('{.refcount = &grpc_static_metadata_refcounts[%d], .data.refcounted ='
+          ' {g_bytes+%d, %d}}') % (
+      i, id2strofs[i], len(all_strs[i]))
+
 
 # validate configuration
 for elem in METADATA_BATCH_CALLOUTS:
   assert elem in all_strs
 
-print >>H, '#define GRPC_STATIC_MDSTR_COUNT %d' % len(all_strs)
-print >>H, 'extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];'
+print >> H, '#define GRPC_STATIC_MDSTR_COUNT %d' % len(all_strs)
+print >> H, ('extern const grpc_slice '
+             'grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];')
 for i, elem in enumerate(all_strs):
-  print >>H, '/* "%s" */' % elem
-  print >>H, '#define %s (grpc_static_slice_table[%d])' % (mangle(elem).upper(), i)
-print >>H
-print >>C, 'static uint8_t g_bytes[] = {%s};' % (','.join('%d' % ord(c) for c in ''.join(all_strs)))
-print >>C
-print >>C, 'static void static_ref(void *unused) {}'
-print >>C, 'static void static_unref(grpc_exec_ctx *exec_ctx, void *unused) {}'
-print >>C, 'static const grpc_slice_refcount_vtable static_sub_vtable = {static_ref, static_unref, grpc_slice_default_eq_impl, grpc_slice_default_hash_impl};';
-print >>H, 'extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable;';
-print >>C, 'const grpc_slice_refcount_vtable grpc_static_metadata_vtable = {static_ref, static_unref, grpc_static_slice_eq, grpc_static_slice_hash};';
-print >>C, 'static grpc_slice_refcount static_sub_refcnt = {&static_sub_vtable, &static_sub_refcnt};';
-print >>H, 'extern grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT];'
-print >>C, 'grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = {'
+  print >> H, '/* "%s" */' % elem
+  print >> H, '#define %s (grpc_static_slice_table[%d])' % (
+      mangle(elem).upper(), i)
+print >> H
+print >> C, 'static uint8_t g_bytes[] = {%s};' % (
+    ','.join('%d' % ord(c) for c in ''.join(all_strs)))
+print >> C
+print >> C, 'static void static_ref(void *unused) {}'
+print >> C, 'static void static_unref(grpc_exec_ctx *exec_ctx, void *unused) {}'
+print >> C, ('static const grpc_slice_refcount_vtable static_sub_vtable = '
+             '{static_ref, static_unref, grpc_slice_default_eq_impl, '
+             'grpc_slice_default_hash_impl};')
+print >> H, ('extern const grpc_slice_refcount_vtable '
+             'grpc_static_metadata_vtable;')
+print >> C, ('const grpc_slice_refcount_vtable grpc_static_metadata_vtable = '
+             '{static_ref, static_unref, grpc_static_slice_eq, '
+             'grpc_static_slice_hash};')
+print >> C, ('static grpc_slice_refcount static_sub_refcnt = '
+             '{&static_sub_vtable, &static_sub_refcnt};')
+print >> H, ('extern grpc_slice_refcount '
+             'grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT];')
+print >> C, ('grpc_slice_refcount '
+             'grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = {')
 for i, elem in enumerate(all_strs):
-  print >>C, '  {&grpc_static_metadata_vtable, &static_sub_refcnt},'
-print >>C, '};'
-print >>C
-print >>H, '#define GRPC_IS_STATIC_METADATA_STRING(slice) \\'
-print >>H, '  ((slice).refcount != NULL && (slice).refcount->vtable == &grpc_static_metadata_vtable)'
-print >>H
-print >>C, 'const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {'
+  print >> C, '  {&grpc_static_metadata_vtable, &static_sub_refcnt},'
+print >> C, '};'
+print >> C
+print >> H, '#define GRPC_IS_STATIC_METADATA_STRING(slice) \\'
+print >> H, ('  ((slice).refcount != NULL && (slice).refcount->vtable == '
+             '&grpc_static_metadata_vtable)')
+print >> H
+print >> C, ('const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]'
+             ' = {')
 for i, elem in enumerate(all_strs):
-  print >>C, slice_def(i) + ','
-print >>C, '};'
-print >>C
-print >>H, '#define GRPC_STATIC_METADATA_INDEX(static_slice) \\'
-print >>H, '  ((int)((static_slice).refcount - grpc_static_metadata_refcounts))'
-print >>H
-
-print >>D, '# hpack fuzzing dictionary'
+  print >> C, slice_def(i) + ','
+print >> C, '};'
+print >> C
+print >> H, '#define GRPC_STATIC_METADATA_INDEX(static_slice) \\'
+print >> H, ('  ((int)((static_slice).refcount - '
+             'grpc_static_metadata_refcounts))')
+print >> H
+
+print >> D, '# hpack fuzzing dictionary'
 for i, elem in enumerate(all_strs):
-  print >>D, '%s' % (esc_dict([len(elem)] + [ord(c) for c in elem]))
+  print >> D, '%s' % (esc_dict([len(elem)] + [ord(c) for c in elem]))
 for i, elem in enumerate(all_elems):
-  print >>D, '%s' % (esc_dict([0, len(elem[0])] + [ord(c) for c in elem[0]] +
-                              [len(elem[1])] + [ord(c) for c in elem[1]]))
-
-print >>H, '#define GRPC_STATIC_MDELEM_COUNT %d' % len(all_elems)
-print >>H, 'extern grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];'
-print >>H, 'extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];'
+  print >> D, '%s' % (esc_dict([0, len(elem[0])] + [ord(c) for c in elem[0]] +
+                               [len(elem[1])] + [ord(c) for c in elem[1]]))
+
+print >> H, '#define GRPC_STATIC_MDELEM_COUNT %d' % len(all_elems)
+print >> H, ('extern grpc_mdelem_data '
+             'grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];')
+print >> H, ('extern uintptr_t '
+             'grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];')
 for i, elem in enumerate(all_elems):
-  print >>H, '/* "%s": "%s" */' % elem
-  print >>H, '#define %s (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[%d], GRPC_MDELEM_STORAGE_STATIC))' % (mangle(elem).upper(), i)
-print >>H
-print >>C, 'uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {'
-print >>C, '  %s' % ','.join('%d' % static_userdata.get(elem, 0) for elem in all_elems)
-print >>C, '};'
-print >>C
+  print >> H, '/* "%s": "%s" */' % elem
+  print >> H, ('#define %s (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[%d], '
+               'GRPC_MDELEM_STORAGE_STATIC))') % (
+      mangle(elem).upper(), i)
+print >> H
+print >> C, ('uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] '
+             '= {')
+print >> C, '  %s' % ','.join('%d' % static_userdata.get(elem, 0)
+                              for elem in all_elems)
+print >> C, '};'
+print >> C
+
 
 def str_idx(s):
   for i, s2 in enumerate(all_strs):
     if s == s2:
       return i
 
+
 def md_idx(m):
   for i, m2 in enumerate(all_elems):
     if m == m2:
       return i
 
+
 def offset_trials(mink):
   yield 0
   for i in range(1, 100):
     for mul in [-1, 1]:
       yield mul * i
 
+
 def perfect_hash(keys, name):
   p = perfection.hash_parameters(keys)
+
   def f(i, p=p):
     i += p.offset
     x = i % p.t
     y = i / p.t
     return x + p.r[y]
+
   return {
-    'PHASHRANGE': p.t - 1 + max(p.r),
-    'PHASHNKEYS': len(p.slots),
-    'pyfunc': f,
-    'code': """
+      'PHASHRANGE':
+          p.t - 1 + max(p.r),
+      'PHASHNKEYS':
+          len(p.slots),
+      'pyfunc':
+          f,
+      'code':
+          """
 static const int8_t %(name)s_r[] = {%(r)s};
 static uint32_t %(name)s_phash(uint32_t i) {
   i %(offset_sign)s= %(offset)d;
@@ -430,71 +490,77 @@ static uint32_t %(name)s_phash(uint32_t i) {
   return h;
 }
     """ % {
-      'name': name,
-      'r': ','.join('%d' % (r if r is not None else 0) for r in p.r),
-      't': p.t,
-      'offset': abs(p.offset),
-      'offset_sign': '+' if p.offset > 0 else '-'
+        'name': name,
+        'r': ','.join('%d' % (r if r is not None else 0) for r in p.r),
+        't': p.t,
+        'offset': abs(p.offset),
+        'offset_sign': '+' if p.offset > 0 else '-'
     }
   }
 
 
-elem_keys = [str_idx(elem[0]) * len(all_strs) + str_idx(elem[1]) for elem in all_elems]
-elem_hash = perfect_hash(elem_keys, "elems")
-print >>C, elem_hash['code']
+elem_keys = [
+    str_idx(elem[0]) * len(all_strs) + str_idx(elem[1]) for elem in all_elems
+]
+elem_hash = perfect_hash(elem_keys, 'elems')
+print >> C, elem_hash['code']
 
 keys = [0] * int(elem_hash['PHASHRANGE'])
 idxs = [255] * int(elem_hash['PHASHNKEYS'])
 for i, k in enumerate(elem_keys):
-    h = elem_hash['pyfunc'](k)
-    assert keys[h] == 0
-    keys[h] = k
-    idxs[h] = i
-print >>C, 'static const uint16_t elem_keys[] = {%s};' % ','.join('%d' % k for k in keys)
-print >>C, 'static const uint8_t elem_idxs[] = {%s};' % ','.join('%d' % i for i in idxs)
-print >>C
-
-print >>H, 'grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b);'
-print >>C, 'grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {'
-print >>C, '  if (a == -1 || b == -1) return GRPC_MDNULL;'
-print >>C, '  uint32_t k = (uint32_t)(a * %d + b);' % len(all_strs)
-print >>C, '  uint32_t h = elems_phash(k);'
-print >>C, '  return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], GRPC_MDELEM_STORAGE_STATIC) : GRPC_MDNULL;'
-print >>C, '}'
-print >>C
-
-print >>C, 'grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {'
+  h = elem_hash['pyfunc'](k)
+  assert keys[h] == 0
+  keys[h] = k
+  idxs[h] = i
+print >> C, 'static const uint16_t elem_keys[] = {%s};' % ','.join(
+    '%d' % k for k in keys)
+print >> C, 'static const uint8_t elem_idxs[] = {%s};' % ','.join(
+    '%d' % i for i in idxs)
+print >> C
+
+print >> H, 'grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b);'
+print >> C, 'grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {'
+print >> C, '  if (a == -1 || b == -1) return GRPC_MDNULL;'
+print >> C, '  uint32_t k = (uint32_t)(a * %d + b);' % len(all_strs)
+print >> C, '  uint32_t h = elems_phash(k);'
+print >> C, '  return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], GRPC_MDELEM_STORAGE_STATIC) : GRPC_MDNULL;'
+print >> C, '}'
+print >> C
+
+print >> C, 'grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {'
 for a, b in all_elems:
-  print >>C, '{%s,%s},' % (slice_def(str_idx(a)), slice_def(str_idx(b)))
-print >>C, '};'
+  print >> C, '{%s,%s},' % (slice_def(str_idx(a)), slice_def(str_idx(b)))
+print >> C, '};'
 
-print >>H, 'typedef enum {'
+print >> H, 'typedef enum {'
 for elem in METADATA_BATCH_CALLOUTS:
-  print >>H, '  %s,' % mangle(elem, 'batch').upper()
-print >>H, '  GRPC_BATCH_CALLOUTS_COUNT'
-print >>H, '} grpc_metadata_batch_callouts_index;'
-print >>H
-print >>H, 'typedef union {'
-print >>H, '  struct grpc_linked_mdelem *array[GRPC_BATCH_CALLOUTS_COUNT];'
-print >>H, '  struct {'
+  print >> H, '  %s,' % mangle(elem, 'batch').upper()
+print >> H, '  GRPC_BATCH_CALLOUTS_COUNT'
+print >> H, '} grpc_metadata_batch_callouts_index;'
+print >> H
+print >> H, 'typedef union {'
+print >> H, '  struct grpc_linked_mdelem *array[GRPC_BATCH_CALLOUTS_COUNT];'
+print >> H, '  struct {'
 for elem in METADATA_BATCH_CALLOUTS:
-  print >>H, '  struct grpc_linked_mdelem *%s;' % mangle(elem, '').lower()
-print >>H, '  } named;'
-print >>H, '} grpc_metadata_batch_callouts;'
-print >>H
-print >>H, '#define GRPC_BATCH_INDEX_OF(slice) \\'
-print >>H, '  (GRPC_IS_STATIC_METADATA_STRING((slice)) ? (grpc_metadata_batch_callouts_index)GPR_CLAMP(GRPC_STATIC_METADATA_INDEX((slice)), 0, GRPC_BATCH_CALLOUTS_COUNT) : GRPC_BATCH_CALLOUTS_COUNT)'
-print >>H
-
-print >>H, 'extern const uint8_t grpc_static_accept_encoding_metadata[%d];' % (1 << len(COMPRESSION_ALGORITHMS))
-print >>C, 'const uint8_t grpc_static_accept_encoding_metadata[%d] = {' % (1 << len(COMPRESSION_ALGORITHMS))
-print >>C, '0,%s' % ','.join('%d' % md_idx(elem) for elem in compression_elems)
-print >>C, '};'
-print >>C
-
-print >>H, '#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC))'
-
-print >>H, '#endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */'
+  print >> H, '  struct grpc_linked_mdelem *%s;' % mangle(elem, '').lower()
+print >> H, '  } named;'
+print >> H, '} grpc_metadata_batch_callouts;'
+print >> H
+print >> H, '#define GRPC_BATCH_INDEX_OF(slice) \\'
+print >> H, '  (GRPC_IS_STATIC_METADATA_STRING((slice)) ? (grpc_metadata_batch_callouts_index)GPR_CLAMP(GRPC_STATIC_METADATA_INDEX((slice)), 0, GRPC_BATCH_CALLOUTS_COUNT) : GRPC_BATCH_CALLOUTS_COUNT)'
+print >> H
+
+print >> H, 'extern const uint8_t grpc_static_accept_encoding_metadata[%d];' % (
+    1 << len(COMPRESSION_ALGORITHMS))
+print >> C, 'const uint8_t grpc_static_accept_encoding_metadata[%d] = {' % (
+    1 << len(COMPRESSION_ALGORITHMS))
+print >> C, '0,%s' % ','.join('%d' % md_idx(elem) for elem in compression_elems)
+print >> C, '};'
+print >> C
+
+print >> H, '#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC))'
+
+print >> H, '#endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */'
 
 H.close()
 C.close()
diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py
index 611a9f40ae97d203d4158bfe2362ddb01937f6b1..0a58adf2f0aa542737acaf2a81c8d22ab6e2db90 100755
--- a/tools/distrib/check_copyright.py
+++ b/tools/distrib/check_copyright.py
@@ -104,13 +104,17 @@ _EXEMPT = frozenset((
   'examples/python/route_guide/route_guide_pb2.py',
   'examples/python/route_guide/route_guide_pb2_grpc.py',
 
-  'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
-  'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
+  'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
+  'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
   'src/cpp/server/health/health.pb.h',
   'src/cpp/server/health/health.pb.c',
 
   # An older file originally from outside gRPC.
   'src/php/tests/bootstrap.php',
+  # census.proto copied from github
+  'tools/grpcz/census.proto',
+  # status.proto copied from googleapis
+  'src/proto/grpc/status/status.proto',
 ))
 
 
@@ -125,7 +129,9 @@ RE_LICENSE = dict(
 if args.precommit:
   FILE_LIST_COMMAND = 'git status -z | grep -Poz \'(?<=^[MARC][MARCD ] )[^\s]+\''
 else:
-  FILE_LIST_COMMAND = 'git ls-tree -r --name-only -r HEAD | grep -v ^third_party/'
+  FILE_LIST_COMMAND = 'git ls-tree -r --name-only -r HEAD | ' \
+                      'grep -v ^third_party/ |' \
+                      'grep -v "\(ares_config.h\|ares_build.h\)"'
 
 def load(name):
   with open(name) as f:
diff --git a/tools/distrib/check_include_guards.py b/tools/distrib/check_include_guards.py
index 28312813f65774aeacb34d7b78c5fa2f6de6df74..c7c267836d4d90da50c4967d77f2a031e27c9a1d 100755
--- a/tools/distrib/check_include_guards.py
+++ b/tools/distrib/check_include_guards.py
@@ -171,7 +171,7 @@ argp.add_argument('--precommit',
 args = argp.parse_args()
 
 KNOWN_BAD = set([
-    'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
+    'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
     'include/grpc++/ext/reflection.grpc.pb.h',
     'include/grpc++/ext/reflection.pb.h',
 ])
diff --git a/tools/distrib/check_nanopb_output.sh b/tools/distrib/check_nanopb_output.sh
index eb64e23daf760dc5b93603d6208a3e3bc86d162a..ba5028220743bf802898f36abc9a966b0a4610be 100755
--- a/tools/distrib/check_nanopb_output.sh
+++ b/tools/distrib/check_nanopb_output.sh
@@ -58,7 +58,7 @@ popd
 #
 # Checks for load_balancer.proto
 #
-readonly LOAD_BALANCER_GRPC_OUTPUT_PATH='src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1'
+readonly LOAD_BALANCER_GRPC_OUTPUT_PATH='src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1'
 # nanopb-compile the proto to a temp location
 ./tools/codegen/core/gen_nano_proto.sh \
   src/proto/grpc/lb/v1/load_balancer.proto \
@@ -66,7 +66,7 @@ readonly LOAD_BALANCER_GRPC_OUTPUT_PATH='src/core/ext/lb_policy/grpclb/proto/grp
   "$LOAD_BALANCER_GRPC_OUTPUT_PATH"
 
 # compare outputs to checked compiled code
-if ! diff -r $NANOPB_TMP_OUTPUT src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1; then
+if ! diff -r $NANOPB_TMP_OUTPUT src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1; then
   echo "Outputs differ: $NANOPB_TMP_OUTPUT vs $LOAD_BALANCER_GRPC_OUTPUT_PATH"
   exit 2
 fi
diff --git a/tools/distrib/python/bazel_deps.sh b/tools/distrib/python/bazel_deps.sh
index de3ee079708c6ce7aaf1186939780cb90c8431ce..f6d42d29eb6891c2b07a2fcf49dbb4b8b1abc8b9 100755
--- a/tools/distrib/python/bazel_deps.sh
+++ b/tools/distrib/python/bazel_deps.sh
@@ -33,14 +33,14 @@ cd $(dirname $0)/../../../
 
 # First check if bazel is installed on the machine. If it is, then we don't need
 # to invoke the docker bazel.
-if [ "bazel version" ]
+if [ -x "$(command -v bazel)" ]
 then
   cd third_party/protobuf
   bazel query 'deps('$1')'
 else
-  docker build -t bazel `realpath ./tools/dockerfile/bazel/`
-  docker run -v "`realpath .`:/src/grpc/"          \
-    -w /src/grpc/third_party/protobuf              \
-    bazel                                          \
+  docker build -t bazel_local_img tools/dockerfile/test/sanity
+  docker run -v "$(realpath .):/src/grpc/:ro" \
+    -w /src/grpc/third_party/protobuf         \
+    bazel_local_img                           \
     bazel query 'deps('$1')'
 fi
diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/protobuf_generated_well_known_types_embed.cc b/tools/distrib/python/grpcio_tools/grpc_tools/protobuf_generated_well_known_types_embed.cc
new file mode 100644
index 0000000000000000000000000000000000000000..682837a27f0c06610c07b55157beb81459ea48ea
--- /dev/null
+++ b/tools/distrib/python/grpcio_tools/grpc_tools/protobuf_generated_well_known_types_embed.cc
@@ -0,0 +1,343 @@
+// Copyright 2017, 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.
+
+// HACK: Embed the generated well_known_types_js.cc to make
+// grpc-tools python package compilation easy.
+#include <google/protobuf/compiler/js/well_known_types_embed.h>
+struct FileToc well_known_types_js[] = {
+{"any.js",
+  "// Protocol Buffers - Google's data interchange format\n"
+  "// Copyright 2008 Google Inc.  All rights reserved.\n"
+  "// https://developers.google.com/protocol-buffers/\n"
+  "//\n"
+  "// Redistribution and use in source and binary forms, with or without\n"
+  "// modification, are permitted provided that the following conditions are\n"
+  "// met:\n"
+  "//\n"
+  "//     * Redistributions of source code must retain the above copyright\n"
+  "// notice, this list of conditions and the following disclaimer.\n"
+  "//     * Redistributions in binary form must reproduce the above\n"
+  "// copyright notice, this list of conditions and the following disclaimer\n"
+  "// in the documentation and/or other materials provided with the\n"
+  "// distribution.\n"
+  "//     * Neither the name of Google Inc. nor the names of its\n"
+  "// contributors may be used to endorse or promote products derived from\n"
+  "// this software without specific prior written permission.\n"
+  "//\n"
+  "// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
+  "// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
+  "// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
+  "// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
+  "// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
+  "// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
+  "// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
+  "// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
+  "// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
+  "// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
+  "// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
+  "\n"
+  "/* This code will be inserted into generated code for\n"
+  " * google/protobuf/any.proto. */\n"
+  "\n"
+  "/**\n"
+  " * Returns the type name contained in this instance, if any.\n"
+  " * @return {string|undefined}\n"
+  " */\n"
+  "proto.google.protobuf.Any.prototype.getTypeName = function() {\n"
+  "  return this.getTypeUrl().split('/').pop();\n"
+  "};\n"
+  "\n"
+  "\n"
+  "/**\n"
+  " * Packs the given message instance into this Any.\n"
+  " * @param {!Uint8Array} serialized The serialized data to pack.\n"
+  " * @param {string} name The type name of this message object.\n"
+  " * @param {string=} opt_typeUrlPrefix the type URL prefix.\n"
+  " */\n"
+  "proto.google.protobuf.Any.prototype.pack = function(serialized, name,\n"
+  "                                                    opt_typeUrlPrefix) {\n"
+  "  if (!opt_typeUrlPrefix) {\n"
+  "    opt_typeUrlPrefix = 'type.googleapis.com/';\n"
+  "  }\n"
+  "\n"
+  "  if (opt_typeUrlPrefix.substr(-1) != '/') {\n"
+  "    this.setTypeUrl(opt_typeUrlPrefix + '/' + name);\n"
+  "  } else {\n"
+  "    this.setTypeUrl(opt_typeUrlPrefix + name);\n"
+  "  }\n"
+  "\n"
+  "  this.setValue(serialized);\n"
+  "};\n"
+  "\n"
+  "\n"
+  "/**\n"
+  " * @template T\n"
+  " * Unpacks this Any into the given message object.\n"
+  " * @param {function(Uint8Array):T} deserialize Function that will deserialize\n"
+  " *     the binary data properly.\n"
+  " * @param {string} name The expected type name of this message object.\n"
+  " * @return {?T} If the name matched the expected name, returns the deserialized\n"
+  " *     object, otherwise returns undefined.\n"
+  " */\n"
+  "proto.google.protobuf.Any.prototype.unpack = function(deserialize, name) {\n"
+  "  if (this.getTypeName() == name) {\n"
+  "    return deserialize(this.getValue_asU8());\n"
+  "  } else {\n"
+  "    return null;\n"
+  "  }\n"
+  "};\n"
+},
+{"struct.js",
+  "// Protocol Buffers - Google's data interchange format\n"
+  "// Copyright 2008 Google Inc.  All rights reserved.\n"
+  "// https://developers.google.com/protocol-buffers/\n"
+  "//\n"
+  "// Redistribution and use in source and binary forms, with or without\n"
+  "// modification, are permitted provided that the following conditions are\n"
+  "// met:\n"
+  "//\n"
+  "//     * Redistributions of source code must retain the above copyright\n"
+  "// notice, this list of conditions and the following disclaimer.\n"
+  "//     * Redistributions in binary form must reproduce the above\n"
+  "// copyright notice, this list of conditions and the following disclaimer\n"
+  "// in the documentation and/or other materials provided with the\n"
+  "// distribution.\n"
+  "//     * Neither the name of Google Inc. nor the names of its\n"
+  "// contributors may be used to endorse or promote products derived from\n"
+  "// this software without specific prior written permission.\n"
+  "//\n"
+  "// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
+  "// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
+  "// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
+  "// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
+  "// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
+  "// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
+  "// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
+  "// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
+  "// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
+  "// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
+  "// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
+  "\n"
+  "/* This code will be inserted into generated code for\n"
+  " * google/protobuf/struct.proto. */\n"
+  "\n"
+  "/**\n"
+  " * Typedef representing plain JavaScript values that can go into a\n"
+  " *     Struct.\n"
+  " * @typedef {null|number|string|boolean|Array|Object}\n"
+  " */\n"
+  "proto.google.protobuf.JavaScriptValue;\n"
+  "\n"
+  "\n"
+  "/**\n"
+  " * Converts this Value object to a plain JavaScript value.\n"
+  " * @return {?proto.google.protobuf.JavaScriptValue} a plain JavaScript\n"
+  " *     value representing this Struct.\n"
+  " */\n"
+  "proto.google.protobuf.Value.prototype.toJavaScript = function() {\n"
+  "  var kindCase = proto.google.protobuf.Value.KindCase;\n"
+  "  switch (this.getKindCase()) {\n"
+  "    case kindCase.NULL_VALUE:\n"
+  "      return null;\n"
+  "    case kindCase.NUMBER_VALUE:\n"
+  "      return this.getNumberValue();\n"
+  "    case kindCase.STRING_VALUE:\n"
+  "      return this.getStringValue();\n"
+  "    case kindCase.BOOL_VALUE:\n"
+  "      return this.getBoolValue();\n"
+  "    case kindCase.STRUCT_VALUE:\n"
+  "      return this.getStructValue().toJavaScript();\n"
+  "    case kindCase.LIST_VALUE:\n"
+  "      return this.getListValue().toJavaScript();\n"
+  "    default:\n"
+  "      throw new Error('Unexpected struct type');\n"
+  "  }\n"
+  "};\n"
+  "\n"
+  "\n"
+  "/**\n"
+  " * Converts this JavaScript value to a new Value proto.\n"
+  " * @param {!proto.google.protobuf.JavaScriptValue} value The value to\n"
+  " *     convert.\n"
+  " * @return {!proto.google.protobuf.Value} The newly constructed value.\n"
+  " */\n"
+  "proto.google.protobuf.Value.fromJavaScript = function(value) {\n"
+  "  var ret = new proto.google.protobuf.Value();\n"
+  "  switch (goog.typeOf(value)) {\n"
+  "    case 'string':\n"
+  "      ret.setStringValue(/** @type {string} */ (value));\n"
+  "      break;\n"
+  "    case 'number':\n"
+  "      ret.setNumberValue(/** @type {number} */ (value));\n"
+  "      break;\n"
+  "    case 'boolean':\n"
+  "      ret.setBoolValue(/** @type {boolean} */ (value));\n"
+  "      break;\n"
+  "    case 'null':\n"
+  "      ret.setNullValue(proto.google.protobuf.NullValue.NULL_VALUE);\n"
+  "      break;\n"
+  "    case 'array':\n"
+  "      ret.setListValue(proto.google.protobuf.ListValue.fromJavaScript(\n"
+  "          /** @type{!Array} */ (value)));\n"
+  "      break;\n"
+  "    case 'object':\n"
+  "      ret.setStructValue(proto.google.protobuf.Struct.fromJavaScript(\n"
+  "          /** @type{!Object} */ (value)));\n"
+  "      break;\n"
+  "    default:\n"
+  "      throw new Error('Unexpected struct type.');\n"
+  "  }\n"
+  "\n"
+  "  return ret;\n"
+  "};\n"
+  "\n"
+  "\n"
+  "/**\n"
+  " * Converts this ListValue object to a plain JavaScript array.\n"
+  " * @return {!Array} a plain JavaScript array representing this List.\n"
+  " */\n"
+  "proto.google.protobuf.ListValue.prototype.toJavaScript = function() {\n"
+  "  var ret = [];\n"
+  "  var values = this.getValuesList();\n"
+  "\n"
+  "  for (var i = 0; i < values.length; i++) {\n"
+  "    ret[i] = values[i].toJavaScript();\n"
+  "  }\n"
+  "\n"
+  "  return ret;\n"
+  "};\n"
+  "\n"
+  "\n"
+  "/**\n"
+  " * Constructs a ListValue protobuf from this plain JavaScript array.\n"
+  " * @param {!Array} array a plain JavaScript array\n"
+  " * @return {proto.google.protobuf.ListValue} a new ListValue object\n"
+  " */\n"
+  "proto.google.protobuf.ListValue.fromJavaScript = function(array) {\n"
+  "  var ret = new proto.google.protobuf.ListValue();\n"
+  "\n"
+  "  for (var i = 0; i < array.length; i++) {\n"
+  "    ret.addValues(proto.google.protobuf.Value.fromJavaScript(array[i]));\n"
+  "  }\n"
+  "\n"
+  "  return ret;\n"
+  "};\n"
+  "\n"
+  "\n"
+  "/**\n"
+  " * Converts this Struct object to a plain JavaScript object.\n"
+  " * @return {!Object<string, !proto.google.protobuf.JavaScriptValue>} a plain\n"
+  " *     JavaScript object representing this Struct.\n"
+  " */\n"
+  "proto.google.protobuf.Struct.prototype.toJavaScript = function() {\n"
+  "  var ret = {};\n"
+  "\n"
+  "  this.getFieldsMap().forEach(function(value, key) {\n"
+  "    ret[key] = value.toJavaScript();\n"
+  "  });\n"
+  "\n"
+  "  return ret;\n"
+  "};\n"
+  "\n"
+  "\n"
+  "/**\n"
+  " * Constructs a Struct protobuf from this plain JavaScript object.\n"
+  " * @param {!Object} obj a plain JavaScript object\n"
+  " * @return {proto.google.protobuf.Struct} a new Struct object\n"
+  " */\n"
+  "proto.google.protobuf.Struct.fromJavaScript = function(obj) {\n"
+  "  var ret = new proto.google.protobuf.Struct();\n"
+  "  var map = ret.getFieldsMap();\n"
+  "\n"
+  "  for (var property in obj) {\n"
+  "    var val = obj[property];\n"
+  "    map.set(property, proto.google.protobuf.Value.fromJavaScript(val));\n"
+  "  }\n"
+  "\n"
+  "  return ret;\n"
+  "};\n"
+},
+{"timestamp.js",
+  "// Protocol Buffers - Google's data interchange format\n"
+  "// Copyright 2008 Google Inc.  All rights reserved.\n"
+  "// https://developers.google.com/protocol-buffers/\n"
+  "//\n"
+  "// Redistribution and use in source and binary forms, with or without\n"
+  "// modification, are permitted provided that the following conditions are\n"
+  "// met:\n"
+  "//\n"
+  "//     * Redistributions of source code must retain the above copyright\n"
+  "// notice, this list of conditions and the following disclaimer.\n"
+  "//     * Redistributions in binary form must reproduce the above\n"
+  "// copyright notice, this list of conditions and the following disclaimer\n"
+  "// in the documentation and/or other materials provided with the\n"
+  "// distribution.\n"
+  "//     * Neither the name of Google Inc. nor the names of its\n"
+  "// contributors may be used to endorse or promote products derived from\n"
+  "// this software without specific prior written permission.\n"
+  "//\n"
+  "// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
+  "// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
+  "// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
+  "// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
+  "// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
+  "// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
+  "// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
+  "// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
+  "// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
+  "// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
+  "// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
+  "\n"
+  "/* This code will be inserted into generated code for\n"
+  " * google/protobuf/timestamp.proto. */\n"
+  "\n"
+  "/**\n"
+  " * Returns a JavaScript 'Date' object corresponding to this Timestamp.\n"
+  " * @return {!Date}\n"
+  " */\n"
+  "proto.google.protobuf.Timestamp.prototype.toDate = function() {\n"
+  "  var seconds = this.getSeconds();\n"
+  "  var nanos = this.getNanos();\n"
+  "\n"
+  "  return new Date((seconds * 1000) + (nanos / 1000000));\n"
+  "};\n"
+  "\n"
+  "\n"
+  "/**\n"
+  " * Sets the value of this Timestamp object to be the given Date.\n"
+  " * @param {!Date} value The value to set.\n"
+  " */\n"
+  "proto.google.protobuf.Timestamp.prototype.fromDate = function(value) {\n"
+  "  var millis = value.getTime();\n"
+  "  this.setSeconds(Math.floor(value.getTime() / 1000));\n"
+  "  this.setNanos(value.getMilliseconds() * 1000000);\n"
+  "};\n"
+},
+  {NULL, NULL}  // Terminate the list.
+};
diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py
index 263785b774b6a1e8239dfd189606dc95b3373f11..1f2aa81c850aaa782cee069c0ceea02b7c12b463 100644
--- a/tools/distrib/python/grpcio_tools/grpc_version.py
+++ b/tools/distrib/python/grpcio_tools/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
 
-VERSION='1.2.0.dev0'
+VERSION='1.4.0.dev0'
diff --git a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
index 569328e57eab5f500b29df74c20141852f58f4bd..c2aa6198b3d7c442548f2f1c4fa9dd5c18a76e63 100644
--- a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
+++ b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
@@ -29,7 +29,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 # AUTO-GENERATED BY make_grpcio_tools.py!
-CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/php/php_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/javanano/javanano_primitive_field.cc', 'google/protobuf/compiler/javanano/javanano_message_field.cc', 'google/protobuf/compiler/javanano/javanano_message.cc', 'google/protobuf/compiler/javanano/javanano_map_field.cc', 'google/protobuf/compiler/javanano/javanano_helpers.cc', 'google/protobuf/compiler/javanano/javanano_generator.cc', 'google/protobuf/compiler/javanano/javanano_file.cc', 'google/protobuf/compiler/javanano/javanano_field.cc', 'google/protobuf/compiler/javanano/javanano_extension.cc', 'google/protobuf/compiler/javanano/javanano_enum_field.cc', 'google/protobuf/compiler/javanano/javanano_enum.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_lazy_message_field_lite.cc', 'google/protobuf/compiler/java/java_lazy_message_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/stubs/mathlimits.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/once.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/stubs/atomicops_internals_x86_msvc.cc', 'google/protobuf/stubs/atomicops_internals_x86_gcc.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arenastring.cc', 'google/protobuf/arena.cc']
+CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/php/php_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/well_known_types_embed.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/javanano/javanano_primitive_field.cc', 'google/protobuf/compiler/javanano/javanano_message_field.cc', 'google/protobuf/compiler/javanano/javanano_message.cc', 'google/protobuf/compiler/javanano/javanano_map_field.cc', 'google/protobuf/compiler/javanano/javanano_helpers.cc', 'google/protobuf/compiler/javanano/javanano_generator.cc', 'google/protobuf/compiler/javanano/javanano_file.cc', 'google/protobuf/compiler/javanano/javanano_field.cc', 'google/protobuf/compiler/javanano/javanano_extension.cc', 'google/protobuf/compiler/javanano/javanano_enum_field.cc', 'google/protobuf/compiler/javanano/javanano_enum.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_lazy_message_field_lite.cc', 'google/protobuf/compiler/java/java_lazy_message_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/stubs/mathlimits.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/once.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/stubs/atomicops_internals_x86_msvc.cc', 'google/protobuf/stubs/atomicops_internals_x86_gcc.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arenastring.cc', 'google/protobuf/arena.cc', 'google/protobuf/compiler/js/embed.cc']
 PROTO_FILES=['google/protobuf/wrappers.proto', 'google/protobuf/type.proto', 'google/protobuf/timestamp.proto', 'google/protobuf/struct.proto', 'google/protobuf/source_context.proto', 'google/protobuf/field_mask.proto', 'google/protobuf/empty.proto', 'google/protobuf/duration.proto', 'google/protobuf/descriptor.proto', 'google/protobuf/compiler/plugin.proto', 'google/protobuf/api.proto', 'google/protobuf/any.proto']
 
 CC_INCLUDE='third_party/protobuf/src'
diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py
index 502d7ef27b81d54d7e9568b6285bf98f4cee2baf..211d442f1767462adf0f3c6d616812c2d3a83408 100644
--- a/tools/distrib/python/grpcio_tools/setup.py
+++ b/tools/distrib/python/grpcio_tools/setup.py
@@ -157,11 +157,28 @@ def extension_modules():
     plugin_sources = [os.path.join('grpc_tools', '_protoc_compiler.pyx')]
   else:
     plugin_sources = [os.path.join('grpc_tools', '_protoc_compiler.cpp')]
+
   plugin_sources += [
     os.path.join('grpc_tools', 'main.cc'),
-    os.path.join('grpc_root', 'src', 'compiler', 'python_generator.cc')] + [
-    os.path.join(CC_INCLUDE, cc_file)
-    for cc_file in CC_FILES]
+    os.path.join('grpc_root', 'src', 'compiler', 'python_generator.cc')]
+
+  #HACK: Substitute the embed.cc, which is a JS to C++
+  #      preprocessor with the generated code.
+  #      The generated code should not be material
+  #      to the parts of protoc we use (it affects
+  #      the JavaScript code generator, supposedly),
+  #      but we need to be cautious about it.
+  cc_files_clone = list(CC_FILES)
+  embed_cc_file = os.path.normpath('google/protobuf/compiler/js/embed.cc')
+  well_known_types_file = os.path.normpath(
+      'google/protobuf/compiler/js/well_known_types_embed.cc')
+  if embed_cc_file in cc_files_clone:
+    cc_files_clone.remove(embed_cc_file)
+  if well_known_types_file in cc_files_clone:
+    cc_files_clone.remove(well_known_types_file)
+    plugin_sources += [os.path.join('grpc_tools', 'protobuf_generated_well_known_types_embed.cc')]
+  plugin_sources += [os.path.join(CC_INCLUDE, cc_file) for cc_file in cc_files_clone]
+
   plugin_ext = extension.Extension(
       name='grpc_tools._protoc_compiler',
       sources=plugin_sources,
@@ -186,11 +203,15 @@ def extension_modules():
 setuptools.setup(
   name='grpcio-tools',
   version=grpc_version.VERSION,
+  description='Protobuf code generator for gRPC',
+  author='The gRPC Authors',
+  author_email='grpc-io@googlegroups.com',
+  url='http://www.grpc.io',
   license='3-clause BSD',
   ext_modules=extension_modules(),
   packages=setuptools.find_packages('.'),
   install_requires=[
-    'protobuf>=3.0.0',
+    'protobuf>=3.2.0',
     'grpcio>={version}'.format(version=grpc_version.VERSION),
   ],
   package_data=package_data(),
diff --git a/tools/distrib/yapf_code.sh b/tools/distrib/yapf_code.sh
index 007b14810eb9e01cdac3d9c9ca01e43042dafc2d..f28a1ce8baeb756444487adfa66e4d8b40794210 100755
--- a/tools/distrib/yapf_code.sh
+++ b/tools/distrib/yapf_code.sh
@@ -31,31 +31,48 @@
 set -ex
 
 # change to root directory
-cd $(dirname $0)/../..
+cd "$(dirname "${0}")/../.."
 
-DIRS=src/python
-EXCLUSIONS='src/python/grpcio/grpc_*.py src/python/grpcio_health_checking/grpc_*.py src/python/grpcio_reflection/grpc_*.py src/python/grpcio_tests/grpc_*.py'
+DIRS=(
+    'src/python'
+)
+EXCLUSIONS=(
+    'grpcio/grpc_*.py'
+    'grpcio_health_checking/grpc_*.py'
+    'grpcio_reflection/grpc_*.py'
+    'grpcio_tests/grpc_*.py'
+)
 
-VIRTUALENV=python_format_venv
+VIRTUALENV=yapf_virtual_environment
 
 virtualenv $VIRTUALENV
-PYTHON=`realpath $VIRTUALENV/bin/python`
-$PYTHON -m pip install futures
+PYTHON=$(realpath "${VIRTUALENV}/bin/python")
+$PYTHON -m pip install --upgrade pip
+$PYTHON -m pip install --upgrade futures
 $PYTHON -m pip install yapf==0.16.0
 
-exclusion_args=""
-for exclusion in $EXCLUSIONS; do
-  exclusion_args="$exclusion_args --exclude $exclusion"
-done
+yapf() {
+    local exclusion exclusion_args=()
+    for exclusion in "${EXCLUSIONS[@]}"; do
+        exclusion_args+=( "--exclude" "$1/${exclusion}" )
+    done
+    $PYTHON -m yapf -i -r --style=setup.cfg -p "${exclusion_args[@]}" "${1}"
+}
 
-script_result=0
-for dir in $DIRS; do
-  tempdir=`mktemp -d`
-  cp -RT $dir $tempdir
-  $PYTHON -m yapf -i -r -p $exclusion_args $dir
-  if ! diff -r $dir $tempdir; then
-    script_result=1
-  fi
-  rm -rf $tempdir
-done
-exit $script_result
+if [[ -z "${TEST}" ]]; then
+    for dir in "${DIRS[@]}"; do
+	yapf "${dir}"
+    done
+else
+    ok=yes
+    for dir in "${DIRS[@]}"; do
+	tempdir=$(mktemp -d)
+	cp -RT "${dir}" "${tempdir}"
+	yapf "${tempdir}"
+	diff -ru "${dir}" "${tempdir}" || ok=no
+	rm -rf "${tempdir}"
+    done
+    if [[ ${ok} == no ]]; then
+	false
+    fi
+fi
diff --git a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile
index 669e3557b8923a825b808a155d0eee29896f2b4c..34799447171e16434682d0110aa96a87af80a4bb 100644
--- a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile
+++ b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0
 
 
 ##################
diff --git a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile
index 860b8f4fb94b0ac33ea70380487f00d58a0302d7..75d156f6d850b5f1c6afa05171a1dfb16717f63b 100644
--- a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile
+++ b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0
 
 
 ##################
diff --git a/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile
index 71098629112ce5f7528f0ae815e72f816417c16e..06be7bec184f42546ae600fcc85e5b1b9406b2e2 100644
--- a/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile
+++ b/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile
@@ -39,7 +39,7 @@ RUN yum update -y
 RUN yum remove -y git
 RUN yum install -y curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc
 RUN cd /usr/src && \
-  wget https://kernel.org/pub/software/scm/git/git-2.0.5.tar.gz && \
+  curl -O -L https://kernel.org/pub/software/scm/git/git-2.0.5.tar.gz && \
   tar xzf git-2.0.5.tar.gz
 RUN cd /usr/src/git-2.0.5 && \
   make prefix=/usr/local/git all && \
diff --git a/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile
index 36286bca53df06c5a70e2e92f1b3d413c422be86..8693e30cb4a58f38ebe6a9d9a004ff07195d3b39 100644
--- a/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile
+++ b/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile
@@ -39,7 +39,7 @@ RUN yum update -y
 RUN yum remove -y git
 RUN yum install -y curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc
 RUN cd /usr/src && \
-  wget https://kernel.org/pub/software/scm/git/git-2.0.5.tar.gz && \
+  curl -O -L https://kernel.org/pub/software/scm/git/git-2.0.5.tar.gz && \
   tar xzf git-2.0.5.tar.gz
 RUN cd /usr/src/git-2.0.5 && \
   make prefix=/usr/local/git all && \
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 c6e4aabfe63fcb88f4e961451699275f753c1bb5..82b96e086e047f79e80edaad130d1d0e05b0a7b9 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
@@ -31,7 +31,7 @@
 set -e
 
 # directories to run against
-DIRS="src/core/lib src/core/ext src/cpp test/core test/cpp include src/compiler"
+DIRS="src/core/lib src/core/tsi src/core/ext src/cpp test/core test/cpp include src/compiler src/node src/csharp src/ruby"
 
 # file matching patterns to check
 GLOB="*.h *.c *.cc"
diff --git a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile
index 087cc4e2bb4de74c198a46061484069733179649..f9e709dccb1fbfc6a9bc0aa4ae28f7742f76838f 100644
--- a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #================
 # C# dependencies
@@ -86,7 +86,6 @@ RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
 
 # Install dependencies
 RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
@@ -97,6 +96,24 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
 
 RUN nuget update -self
 
+# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
+RUN apt-get update && apt-get install -y curl libunwind8 gettext
+# dotnet-dev-1.0.0-preview2-003131
+RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530
+RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet
+# dotnet-dev-1.0.1
+RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453
+RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet
+RUN ln -s /opt/dotnet/dotnet /usr/local/bin
+
+# Trigger the population of the local package cache
+ENV NUGET_XMLDOC_MODE skip
+RUN mkdir warmup \
+    && cd warmup \
+    && dotnet new \
+    && cd .. \
+    && rm -rf warmup
+
 # Prepare ccache
 RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
 RUN ln -s /usr/bin/ccache /usr/local/bin/g++
diff --git a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile
index efe6e39118b74c9e37fbf48bab759bd9d1044cbf..f9e709dccb1fbfc6a9bc0aa4ae28f7742f76838f 100644
--- a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #================
 # C# dependencies
@@ -86,7 +86,6 @@ RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
 
 # Install dependencies
 RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
@@ -99,8 +98,12 @@ RUN nuget update -self
 
 # Install dotnet SDK based on https://www.microsoft.com/net/core#debian
 RUN apt-get update && apt-get install -y curl libunwind8 gettext
-RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130
-RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet
+# dotnet-dev-1.0.0-preview2-003131
+RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530
+RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet
+# dotnet-dev-1.0.1
+RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453
+RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet
 RUN ln -s /opt/dotnet/dotnet /usr/local/bin
 
 # Trigger the population of the local package cache
diff --git a/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile
index aa77d5f1272492d446c25eabfccded7ea4bd858a..2d10e3fdfefa86e512b86d71680452c126df9d62 100644
--- a/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #=================
 # C++ dependencies
diff --git a/tools/dockerfile/interoptest/grpc_interop_go/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_go/Dockerfile
index 05e963d1e67eb121d8eda30188dbc1c46f09d605..d7a0b1786b9811bd346a743120b5134447f34a5c 100644
--- a/tools/dockerfile/interoptest/grpc_interop_go/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_go/Dockerfile
@@ -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.
 
-FROM golang:1.5
+FROM golang:latest
 
 # Using login shell removes Go from path, so we add it.
 RUN ln -s /usr/local/go/bin/go /usr/local/bin
@@ -45,7 +45,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 # Define the default command.
 CMD ["bash"]
diff --git a/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile
index 3a5e15d21bd2a0d3a4e9a8d5f70ca6a6410d76b4..094a4e096df6e1227d644618ccfb18aadb7a6739 100644
--- a/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile
@@ -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.
 
-FROM golang:1.5
+FROM golang:latest
 
 # Using login shell removes Go from path, so we add it.
 RUN ln -s /usr/local/go/bin/go /usr/local/bin
@@ -45,9 +45,9 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
-RUN pip install twisted h2
+RUN pip install twisted h2==2.6.1 hyper
 
 # Define the default command.
 CMD ["bash"]
diff --git a/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile
index b5fe54f99185e8b9e1fad67e6628c0601cdc2c8f..2023467d593b4c6cdb807788356220b864bca7ff 100644
--- a/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile
@@ -60,7 +60,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 
 # Trigger download of as many Gradle artifacts as possible.
diff --git a/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile
index d9a75018295323351de516df0149f8f838e50013..9945260ea4afdc7f00d995f0575f6f8ab7515f7c 100644
--- a/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #==================
 # Node dependencies
diff --git a/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile
index 10a88916ada1219735e89ac7a10fef9f72ba00d5..94c17078d342177cea1b330709e38a35a08d621f 100644
--- a/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 # Prepare ccache
 RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
diff --git a/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile
index dae64e5c8cb199cce992a3220ce4be28a763d4cb..679c8ff47a699c66a01959c0d248aa905f04fc78 100644
--- a/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #==================
 # Ruby dependencies
diff --git a/tools/dockerfile/push_testing_images.sh b/tools/dockerfile/push_testing_images.sh
index 9dceb29a8774ee34a64e261d0303cecb886cd289..973e045ffe422e29f6a3f3702c94b1c9220cb043 100755
--- a/tools/dockerfile/push_testing_images.sh
+++ b/tools/dockerfile/push_testing_images.sh
@@ -44,7 +44,7 @@ cd -
 
 DOCKERHUB_ORGANIZATION=grpctesting
 
-for DOCKERFILE_DIR in tools/dockerfile/test/fuzzer tools/dockerfile/test/sanity
+for DOCKERFILE_DIR in tools/dockerfile/test/*
 do
   # Generate image name based on Dockerfile checksum. That works well as long
   # as can count on dockerfiles being written in a way that changing the logical 
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile
index 328825392b798ef0ed780745ac602c4e0e830ef5..12d8d091848444787da1ad59c1103727a99a48d7 100644
--- a/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 # Prepare ccache
 RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
@@ -103,7 +103,6 @@ RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
 
 # Install dependencies
 RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_cxx/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_cxx/Dockerfile
index e082da648b3b69dca13b37b0bc9ed9b7dbf1d2aa..d0f66d9955623c6714800aabd00a59feec761edb 100644
--- a/tools/dockerfile/stress_test/grpc_interop_stress_cxx/Dockerfile
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_cxx/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 # Prepare ccache
 RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile
index 1e2b7d8c67197da899ffeed69bd41803f13ddce9..c099f339aeee5607f02a0718a239690bcede2de2 100644
--- a/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile
@@ -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.
 
-FROM golang:1.5
+FROM golang:latest
 
 # Google Cloud platform API libraries
 RUN apt-get update && apt-get install -y python-pip && apt-get clean
@@ -47,7 +47,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 # Using login shell removes Go from path, so we add it.
 RUN ln -s /usr/local/go/bin/go /usr/local/bin
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_java/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_java/Dockerfile
index 0c17ff595ef9ce9bfe7bfd842147022a88ef6d9d..229ea469c42fa0acd389018256bf4962948b7a77 100644
--- a/tools/dockerfile/stress_test/grpc_interop_stress_java/Dockerfile
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_java/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 # Prepare ccache
 RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_node/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_node/Dockerfile
index 0594f69a5b8645cf82b37251ecab578dceae115b..5fd0bc0eb2148937705a0984aea313df78c5bfcb 100644
--- a/tools/dockerfile/stress_test/grpc_interop_stress_node/Dockerfile
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_node/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #==================
 # Node dependencies
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile
index 0fe9c151e53b4ff49bcfac6dff797e99c6b6621a..b5198b46529d102d4d92943c8b781996bb1f9bf7 100644
--- a/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #==================
 # Ruby dependencies
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_python/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_python/Dockerfile
index 20d2d3f57bedf12a72a0208660a53db61d2563ad..8e1de51f33171cb2ea9005dc261a0390f7c443dd 100644
--- a/tools/dockerfile/stress_test/grpc_interop_stress_python/Dockerfile
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_python/Dockerfile
@@ -93,7 +93,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 
 RUN pip install coverage
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_ruby/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_ruby/Dockerfile
index f459153fe5420c4c717d0f253eb828a8c98910ee..9d291aac5830fed2d7e949dcf60cf645f9452d45 100644
--- a/tools/dockerfile/stress_test/grpc_interop_stress_ruby/Dockerfile
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_ruby/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 # Prepare ccache
 RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
diff --git a/tools/dockerfile/test/bazel/Dockerfile b/tools/dockerfile/test/bazel/Dockerfile
index cc41384833796c76186f054d842cbea4f02a2d9a..6ea8ef316c6fe8cf749e1e9df721bee265ff7574 100644
--- a/tools/dockerfile/test/bazel/Dockerfile
+++ b/tools/dockerfile/test/bazel/Dockerfile
@@ -72,6 +72,13 @@ RUN curl https://bazel.build/bazel-release.pub.gpg | apt-key add -
 RUN apt-get -y update
 RUN apt-get -y install bazel
 
+# Pin Bazel to 0.4.4
+# Installing Bazel via apt-get first is required before installing 0.4.4 to
+# allow gRPC to build without errors. See https://github.com/grpc/grpc/issues/10553
+RUN curl -fSsL -O https://github.com/bazelbuild/bazel/releases/download/0.4.4/bazel-0.4.4-installer-linux-x86_64.sh
+RUN chmod +x ./bazel-0.4.4-installer-linux-x86_64.sh
+RUN ./bazel-0.4.4-installer-linux-x86_64.sh
+
 RUN mkdir -p /var/local/jenkins
 
 # Define the default command.
diff --git a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile
index efe6e39118b74c9e37fbf48bab759bd9d1044cbf..f9e709dccb1fbfc6a9bc0aa4ae28f7742f76838f 100644
--- a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile
+++ b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #================
 # C# dependencies
@@ -86,7 +86,6 @@ RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
 
 # Install dependencies
 RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
@@ -99,8 +98,12 @@ RUN nuget update -self
 
 # Install dotnet SDK based on https://www.microsoft.com/net/core#debian
 RUN apt-get update && apt-get install -y curl libunwind8 gettext
-RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130
-RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet
+# dotnet-dev-1.0.0-preview2-003131
+RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530
+RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet
+# dotnet-dev-1.0.1
+RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453
+RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet
 RUN ln -s /opt/dotnet/dotnet /usr/local/bin
 
 # Trigger the population of the local package cache
diff --git a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile b/tools/dockerfile/test/csharp_jessie_x64/Dockerfile
index 087cc4e2bb4de74c198a46061484069733179649..f9e709dccb1fbfc6a9bc0aa4ae28f7742f76838f 100644
--- a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/csharp_jessie_x64/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #================
 # C# dependencies
@@ -86,7 +86,6 @@ RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
 
 # Install dependencies
 RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
@@ -97,6 +96,24 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
 
 RUN nuget update -self
 
+# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
+RUN apt-get update && apt-get install -y curl libunwind8 gettext
+# dotnet-dev-1.0.0-preview2-003131
+RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530
+RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet
+# dotnet-dev-1.0.1
+RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453
+RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet
+RUN ln -s /opt/dotnet/dotnet /usr/local/bin
+
+# Trigger the population of the local package cache
+ENV NUGET_XMLDOC_MODE skip
+RUN mkdir warmup \
+    && cd warmup \
+    && dotnet new \
+    && cd .. \
+    && rm -rf warmup
+
 # Prepare ccache
 RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
 RUN ln -s /usr/bin/ccache /usr/local/bin/g++
diff --git a/tools/dockerfile/test/cxx_alpine_x64/Dockerfile b/tools/dockerfile/test/cxx_alpine_x64/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..f9468757da206d4f455d6c1afbb1a55ca90c83aa
--- /dev/null
+++ b/tools/dockerfile/test/cxx_alpine_x64/Dockerfile
@@ -0,0 +1,72 @@
+# 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.
+
+FROM alpine:3.3
+
+# Install Git and basic packages.
+RUN apk update && apk add \
+  autoconf \
+  automake \
+  bzip2 \
+  build-base \
+  cmake \
+  ccache \
+  curl \
+  gcc \
+  git \
+  libtool \
+  make \
+  perl \
+  strace \
+  python-dev \
+  py-pip \
+  unzip \
+  wget \
+  zip
+
+# Install Python packages from PyPI
+RUN pip install pip --upgrade
+RUN pip install virtualenv
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
+
+# 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++
+
+# Install gflags
+RUN git clone https://github.com/gflags/gflags.git && cd gflags && git checkout v2.2.0
+RUN cd gflags && cmake . && make && make install
+RUN ln -s /usr/local/include/gflags /usr/include/gflags
+
+RUN mkdir -p /var/local/jenkins
+
+# Define the default command.
+CMD ["bash"]
diff --git a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile
index e968a0f589b896583b32445b7cc01413f49d23cf..4bb97c7aa9e5b97048df3b47ce6c30a076e77d9f 100644
--- a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #=================
 # C++ dependencies
diff --git a/tools/dockerfile/test/cxx_jessie_x86/Dockerfile b/tools/dockerfile/test/cxx_jessie_x86/Dockerfile
index f985480254631bbcdfeb69fde6ffbb8ac40bd77a..c4b710b5dfb96c842b6f8c0d9d4d5ffbd3479945 100644
--- a/tools/dockerfile/test/cxx_jessie_x86/Dockerfile
+++ b/tools/dockerfile/test/cxx_jessie_x86/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #=================
 # C++ dependencies
diff --git a/tools/dockerfile/test/cxx_ubuntu1404_x64/Dockerfile b/tools/dockerfile/test/cxx_ubuntu1404_x64/Dockerfile
index 2b3f4af3e6de978e3fe927ff325787a22adc5c9e..bd742dff341732c5a13e2e63165520780ce72f75 100644
--- a/tools/dockerfile/test/cxx_ubuntu1404_x64/Dockerfile
+++ b/tools/dockerfile/test/cxx_ubuntu1404_x64/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #=================
 # C++ dependencies
diff --git a/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile b/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile
index 2d282276d31fd0b8fa73494e27316b24e9406427..bc46b3055a6df1b54f8ad79c5bd141716052b59c 100644
--- a/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile
+++ b/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #=================
 # C++ dependencies
diff --git a/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile b/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile
index f22fcacc1399d88242ae49a548d2e07575f91d8b..f7d7f542c11e61f0f2b0aee4191d55b43b8af63a 100644
--- a/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile
+++ b/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #=================
 # C++ dependencies
diff --git a/tools/dockerfile/test/fuzzer/Dockerfile b/tools/dockerfile/test/fuzzer/Dockerfile
index bd04f07cea516ebcb14a9c6c67977190866ead20..b398b70b64fff8704d88f734050f6267d587e4e2 100644
--- a/tools/dockerfile/test/fuzzer/Dockerfile
+++ b/tools/dockerfile/test/fuzzer/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #=================
 # C++ dependencies
diff --git a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile
index 2540b52ec8f57e425ca4eaac92eb5805c336bdbd..c1cce0a1417097fe4a6a4790c0789d692d800dc6 100644
--- a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile
@@ -71,7 +71,6 @@ RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
 RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
 
 # Install dependencies
 RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
@@ -133,7 +132,11 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
+
+# Install coverage for Python test coverage reporting
+RUN pip install coverage
+ENV PATH ~/.local/bin:$PATH
 
 # Prepare ccache
 RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
diff --git a/tools/dockerfile/test/node_jessie_x64/Dockerfile b/tools/dockerfile/test/node_jessie_x64/Dockerfile
index 7f93933ecacf7562847dab5688c97e98b27d6ff3..4595aa6bea1235ff62374f04751b4d19e1297950 100644
--- a/tools/dockerfile/test/node_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/node_jessie_x64/Dockerfile
@@ -87,7 +87,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #==================
 # Node dependencies
diff --git a/tools/dockerfile/test/php7_jessie_x64/Dockerfile b/tools/dockerfile/test/php7_jessie_x64/Dockerfile
index 221338956efc68b300b033f9dc509fbe6ec625be..0e2c103afd137da4184773c676a482ac357d2eda 100644
--- a/tools/dockerfile/test/php7_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/php7_jessie_x64/Dockerfile
@@ -88,7 +88,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 # Prepare ccache
 RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
diff --git a/tools/dockerfile/test/php_jessie_x64/Dockerfile b/tools/dockerfile/test/php_jessie_x64/Dockerfile
index 17ea36b76c4983b2c41d1292f5788c1b2166f70e..c6f3dde39a5cc86ab284975316f663fb859f97db 100644
--- a/tools/dockerfile/test/php_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/php_jessie_x64/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #=================
 # PHP dependencies
diff --git a/tools/dockerfile/test/python_alpine_x64/Dockerfile b/tools/dockerfile/test/python_alpine_x64/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..bdffbd35982bb9e09eb6f2c6322f91ef950318b0
--- /dev/null
+++ b/tools/dockerfile/test/python_alpine_x64/Dockerfile
@@ -0,0 +1,67 @@
+# 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.
+
+FROM alpine:3.3
+
+# Install Git and basic packages.
+RUN apk update && apk add \
+  autoconf \
+  automake \
+  bzip2 \
+  build-base \
+  cmake \
+  ccache \
+  curl \
+  gcc \
+  git \
+  libtool \
+  make \
+  perl \
+  strace \
+  python-dev \
+  py-pip \
+  unzip \
+  wget \
+  zip
+
+# Install Python packages from PyPI
+RUN pip install pip --upgrade
+RUN pip install virtualenv
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
+
+# 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 mkdir -p /var/local/jenkins
+
+# Define the default command.
+CMD ["bash"]
diff --git a/tools/dockerfile/test/python_jessie_x64/Dockerfile b/tools/dockerfile/test/python_jessie_x64/Dockerfile
index 10a88916ada1219735e89ac7a10fef9f72ba00d5..94c17078d342177cea1b330709e38a35a08d621f 100644
--- a/tools/dockerfile/test/python_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/python_jessie_x64/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 # Prepare ccache
 RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
diff --git a/tools/dockerfile/test/python_pyenv_x64/Dockerfile b/tools/dockerfile/test/python_pyenv_x64/Dockerfile
index ecd785a86d37671887bb14aba1f8bba54633df03..435a9fdc978feb2accde7745c25057c78de94709 100644
--- a/tools/dockerfile/test/python_pyenv_x64/Dockerfile
+++ b/tools/dockerfile/test/python_pyenv_x64/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 # Install dependencies for pyenv
 RUN apt-get update && apt-get install -y \
@@ -92,6 +92,9 @@ RUN apt-get update && apt-get install -y \
 
 # Install Pyenv and dev Python versions 3.5 and 3.6
 RUN curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash
+ENV PATH /root/.pyenv/bin:$PATH
+RUN eval "$(pyenv init -)"
+RUN eval "$(pyenv virtualenv-init -)"
 RUN pyenv update
 RUN pyenv install 3.5-dev
 RUN pyenv install 3.6-dev
diff --git a/tools/dockerfile/test/ruby_jessie_x64/Dockerfile b/tools/dockerfile/test/ruby_jessie_x64/Dockerfile
index dae64e5c8cb199cce992a3220ce4be28a763d4cb..679c8ff47a699c66a01959c0d248aa905f04fc78 100644
--- a/tools/dockerfile/test/ruby_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/ruby_jessie_x64/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #==================
 # Ruby dependencies
diff --git a/tools/dockerfile/test/sanity/Dockerfile b/tools/dockerfile/test/sanity/Dockerfile
index 811384fda14f996fae5606e83af4cf852e6064d2..0da2a1914acffb92cb7784c8c949ce2e92a8437b 100644
--- a/tools/dockerfile/test/sanity/Dockerfile
+++ b/tools/dockerfile/test/sanity/Dockerfile
@@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \
 # Install Python packages from PyPI
 RUN pip install pip --upgrade
 RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
 
 #========================
 # Sanity test dependencies
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 965259746cf123449ec1eae9c56a5bd088c35bec..1d2aa9595570c0b492c48310a6f4bc84de5676dc 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -40,7 +40,7 @@ PROJECT_NAME           = "GRPC C++"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 1.2.0-dev
+PROJECT_NUMBER         = 1.4.0-dev
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
@@ -764,6 +764,7 @@ INPUT                  = doc/PROTOCOL-HTTP2.md \
 doc/PROTOCOL-WEB.md \
 doc/binary-logging.md \
 doc/c-style-guide.md \
+doc/combiner-explainer.md \
 doc/command_line_tool.md \
 doc/compression.md \
 doc/compression_cookbook.md \
@@ -779,15 +780,16 @@ doc/fail_fast.md \
 doc/g_stands_for.md \
 doc/health-checking.md \
 doc/http-grpc-status-mapping.md \
+doc/http2-interop-test-descriptions.md \
 doc/internationalization.md \
 doc/interop-test-descriptions.md \
 doc/load-balancing.md \
 doc/naming.md \
-doc/negative-http2-interop-test-descriptions.md \
 doc/server-reflection.md \
 doc/server_reflection_tutorial.md \
 doc/server_side_auth.md \
 doc/service_config.md \
+doc/status_ordering.md \
 doc/statuscodes.md \
 doc/stress_test_framework.md \
 doc/wait-for-ready.md \
@@ -803,6 +805,7 @@ include/grpc++/generic/generic_stub.h \
 include/grpc++/grpc++.h \
 include/grpc++/health_check_service_interface.h \
 include/grpc++/impl/call.h \
+include/grpc++/impl/channel_argument_option.h \
 include/grpc++/impl/client_unary_call.h \
 include/grpc++/impl/codegen/async_stream.h \
 include/grpc++/impl/codegen/async_unary_call.h \
@@ -832,7 +835,6 @@ include/grpc++/impl/codegen/service_type.h \
 include/grpc++/impl/codegen/slice.h \
 include/grpc++/impl/codegen/status.h \
 include/grpc++/impl/codegen/status_code_enum.h \
-include/grpc++/impl/codegen/status_helper.h \
 include/grpc++/impl/codegen/string_ref.h \
 include/grpc++/impl/codegen/stub_options.h \
 include/grpc++/impl/codegen/sync_stream.h \
@@ -867,6 +869,12 @@ include/grpc++/support/string_ref.h \
 include/grpc++/support/stub_options.h \
 include/grpc++/support/sync_stream.h \
 include/grpc++/support/time.h \
+include/grpc/byte_buffer.h \
+include/grpc/byte_buffer_reader.h \
+include/grpc/compression.h \
+include/grpc/grpc.h \
+include/grpc/grpc_posix.h \
+include/grpc/grpc_security_constants.h \
 include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
@@ -885,7 +893,11 @@ include/grpc/impl/codegen/status.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_windows.h
+include/grpc/impl/codegen/sync_windows.h \
+include/grpc/load_reporting.h \
+include/grpc/slice.h \
+include/grpc/slice_buffer.h \
+include/grpc/status.h
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index d98475fb00c71807ae58bb1ad00dad28b938db5a..9664234f9f4d0855e37c280d6bb79b7eaf94e91d 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -40,7 +40,7 @@ PROJECT_NAME           = "GRPC C++"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 1.2.0-dev
+PROJECT_NUMBER         = 1.4.0-dev
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
@@ -764,6 +764,7 @@ INPUT                  = doc/PROTOCOL-HTTP2.md \
 doc/PROTOCOL-WEB.md \
 doc/binary-logging.md \
 doc/c-style-guide.md \
+doc/combiner-explainer.md \
 doc/command_line_tool.md \
 doc/compression.md \
 doc/compression_cookbook.md \
@@ -779,15 +780,16 @@ doc/fail_fast.md \
 doc/g_stands_for.md \
 doc/health-checking.md \
 doc/http-grpc-status-mapping.md \
+doc/http2-interop-test-descriptions.md \
 doc/internationalization.md \
 doc/interop-test-descriptions.md \
 doc/load-balancing.md \
 doc/naming.md \
-doc/negative-http2-interop-test-descriptions.md \
 doc/server-reflection.md \
 doc/server_reflection_tutorial.md \
 doc/server_side_auth.md \
 doc/service_config.md \
+doc/status_ordering.md \
 doc/statuscodes.md \
 doc/stress_test_framework.md \
 doc/wait-for-ready.md \
@@ -803,6 +805,7 @@ include/grpc++/generic/generic_stub.h \
 include/grpc++/grpc++.h \
 include/grpc++/health_check_service_interface.h \
 include/grpc++/impl/call.h \
+include/grpc++/impl/channel_argument_option.h \
 include/grpc++/impl/client_unary_call.h \
 include/grpc++/impl/codegen/async_stream.h \
 include/grpc++/impl/codegen/async_unary_call.h \
@@ -833,7 +836,6 @@ include/grpc++/impl/codegen/service_type.h \
 include/grpc++/impl/codegen/slice.h \
 include/grpc++/impl/codegen/status.h \
 include/grpc++/impl/codegen/status_code_enum.h \
-include/grpc++/impl/codegen/status_helper.h \
 include/grpc++/impl/codegen/string_ref.h \
 include/grpc++/impl/codegen/stub_options.h \
 include/grpc++/impl/codegen/sync_stream.h \
@@ -868,6 +870,12 @@ include/grpc++/support/string_ref.h \
 include/grpc++/support/stub_options.h \
 include/grpc++/support/sync_stream.h \
 include/grpc++/support/time.h \
+include/grpc/byte_buffer.h \
+include/grpc/byte_buffer_reader.h \
+include/grpc/compression.h \
+include/grpc/grpc.h \
+include/grpc/grpc_posix.h \
+include/grpc/grpc_security_constants.h \
 include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
@@ -887,6 +895,236 @@ 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_windows.h \
+include/grpc/load_reporting.h \
+include/grpc/slice.h \
+include/grpc/slice_buffer.h \
+include/grpc/status.h \
+src/core/lib/channel/channel_args.c \
+src/core/lib/channel/channel_args.h \
+src/core/lib/channel/channel_stack.c \
+src/core/lib/channel/channel_stack.h \
+src/core/lib/channel/channel_stack_builder.c \
+src/core/lib/channel/channel_stack_builder.h \
+src/core/lib/channel/connected_channel.c \
+src/core/lib/channel/connected_channel.h \
+src/core/lib/channel/context.h \
+src/core/lib/channel/handshaker.c \
+src/core/lib/channel/handshaker.h \
+src/core/lib/channel/handshaker_factory.c \
+src/core/lib/channel/handshaker_factory.h \
+src/core/lib/channel/handshaker_registry.c \
+src/core/lib/channel/handshaker_registry.h \
+src/core/lib/compression/algorithm_metadata.h \
+src/core/lib/compression/compression.c \
+src/core/lib/compression/message_compress.c \
+src/core/lib/compression/message_compress.h \
+src/core/lib/debug/trace.c \
+src/core/lib/debug/trace.h \
+src/core/lib/http/format_request.c \
+src/core/lib/http/format_request.h \
+src/core/lib/http/httpcli.c \
+src/core/lib/http/httpcli.h \
+src/core/lib/http/parser.c \
+src/core/lib/http/parser.h \
+src/core/lib/iomgr/closure.c \
+src/core/lib/iomgr/closure.h \
+src/core/lib/iomgr/combiner.c \
+src/core/lib/iomgr/combiner.h \
+src/core/lib/iomgr/endpoint.c \
+src/core/lib/iomgr/endpoint.h \
+src/core/lib/iomgr/endpoint_pair.h \
+src/core/lib/iomgr/endpoint_pair_posix.c \
+src/core/lib/iomgr/endpoint_pair_uv.c \
+src/core/lib/iomgr/endpoint_pair_windows.c \
+src/core/lib/iomgr/error.c \
+src/core/lib/iomgr/error.h \
+src/core/lib/iomgr/error_internal.h \
+src/core/lib/iomgr/ev_epoll_linux.c \
+src/core/lib/iomgr/ev_epoll_linux.h \
+src/core/lib/iomgr/ev_poll_posix.c \
+src/core/lib/iomgr/ev_poll_posix.h \
+src/core/lib/iomgr/ev_posix.c \
+src/core/lib/iomgr/ev_posix.h \
+src/core/lib/iomgr/exec_ctx.c \
+src/core/lib/iomgr/exec_ctx.h \
+src/core/lib/iomgr/executor.c \
+src/core/lib/iomgr/executor.h \
+src/core/lib/iomgr/iocp_windows.c \
+src/core/lib/iomgr/iocp_windows.h \
+src/core/lib/iomgr/iomgr.c \
+src/core/lib/iomgr/iomgr.h \
+src/core/lib/iomgr/iomgr_internal.h \
+src/core/lib/iomgr/iomgr_posix.c \
+src/core/lib/iomgr/iomgr_posix.h \
+src/core/lib/iomgr/iomgr_uv.c \
+src/core/lib/iomgr/iomgr_windows.c \
+src/core/lib/iomgr/load_file.c \
+src/core/lib/iomgr/load_file.h \
+src/core/lib/iomgr/lockfree_event.c \
+src/core/lib/iomgr/lockfree_event.h \
+src/core/lib/iomgr/network_status_tracker.c \
+src/core/lib/iomgr/network_status_tracker.h \
+src/core/lib/iomgr/polling_entity.c \
+src/core/lib/iomgr/polling_entity.h \
+src/core/lib/iomgr/pollset.h \
+src/core/lib/iomgr/pollset_set.h \
+src/core/lib/iomgr/pollset_set_uv.c \
+src/core/lib/iomgr/pollset_set_windows.c \
+src/core/lib/iomgr/pollset_set_windows.h \
+src/core/lib/iomgr/pollset_uv.c \
+src/core/lib/iomgr/pollset_uv.h \
+src/core/lib/iomgr/pollset_windows.c \
+src/core/lib/iomgr/pollset_windows.h \
+src/core/lib/iomgr/port.h \
+src/core/lib/iomgr/resolve_address.h \
+src/core/lib/iomgr/resolve_address_posix.c \
+src/core/lib/iomgr/resolve_address_uv.c \
+src/core/lib/iomgr/resolve_address_windows.c \
+src/core/lib/iomgr/resource_quota.c \
+src/core/lib/iomgr/resource_quota.h \
+src/core/lib/iomgr/sockaddr.h \
+src/core/lib/iomgr/sockaddr_posix.h \
+src/core/lib/iomgr/sockaddr_utils.c \
+src/core/lib/iomgr/sockaddr_utils.h \
+src/core/lib/iomgr/sockaddr_windows.h \
+src/core/lib/iomgr/socket_factory_posix.c \
+src/core/lib/iomgr/socket_factory_posix.h \
+src/core/lib/iomgr/socket_mutator.c \
+src/core/lib/iomgr/socket_mutator.h \
+src/core/lib/iomgr/socket_utils.h \
+src/core/lib/iomgr/socket_utils_common_posix.c \
+src/core/lib/iomgr/socket_utils_linux.c \
+src/core/lib/iomgr/socket_utils_posix.c \
+src/core/lib/iomgr/socket_utils_posix.h \
+src/core/lib/iomgr/socket_utils_uv.c \
+src/core/lib/iomgr/socket_utils_windows.c \
+src/core/lib/iomgr/socket_windows.c \
+src/core/lib/iomgr/socket_windows.h \
+src/core/lib/iomgr/tcp_client.h \
+src/core/lib/iomgr/tcp_client_posix.c \
+src/core/lib/iomgr/tcp_client_posix.h \
+src/core/lib/iomgr/tcp_client_uv.c \
+src/core/lib/iomgr/tcp_client_windows.c \
+src/core/lib/iomgr/tcp_posix.c \
+src/core/lib/iomgr/tcp_posix.h \
+src/core/lib/iomgr/tcp_server.h \
+src/core/lib/iomgr/tcp_server_posix.c \
+src/core/lib/iomgr/tcp_server_utils_posix.h \
+src/core/lib/iomgr/tcp_server_utils_posix_common.c \
+src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c \
+src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c \
+src/core/lib/iomgr/tcp_server_uv.c \
+src/core/lib/iomgr/tcp_server_windows.c \
+src/core/lib/iomgr/tcp_uv.c \
+src/core/lib/iomgr/tcp_uv.h \
+src/core/lib/iomgr/tcp_windows.c \
+src/core/lib/iomgr/tcp_windows.h \
+src/core/lib/iomgr/time_averaged_stats.c \
+src/core/lib/iomgr/time_averaged_stats.h \
+src/core/lib/iomgr/timer.h \
+src/core/lib/iomgr/timer_generic.c \
+src/core/lib/iomgr/timer_generic.h \
+src/core/lib/iomgr/timer_heap.c \
+src/core/lib/iomgr/timer_heap.h \
+src/core/lib/iomgr/timer_uv.c \
+src/core/lib/iomgr/timer_uv.h \
+src/core/lib/iomgr/udp_server.c \
+src/core/lib/iomgr/udp_server.h \
+src/core/lib/iomgr/unix_sockets_posix.c \
+src/core/lib/iomgr/unix_sockets_posix.h \
+src/core/lib/iomgr/unix_sockets_posix_noop.c \
+src/core/lib/iomgr/wakeup_fd_cv.c \
+src/core/lib/iomgr/wakeup_fd_cv.h \
+src/core/lib/iomgr/wakeup_fd_eventfd.c \
+src/core/lib/iomgr/wakeup_fd_nospecial.c \
+src/core/lib/iomgr/wakeup_fd_pipe.c \
+src/core/lib/iomgr/wakeup_fd_pipe.h \
+src/core/lib/iomgr/wakeup_fd_posix.c \
+src/core/lib/iomgr/wakeup_fd_posix.h \
+src/core/lib/iomgr/workqueue.h \
+src/core/lib/iomgr/workqueue_uv.c \
+src/core/lib/iomgr/workqueue_uv.h \
+src/core/lib/iomgr/workqueue_windows.c \
+src/core/lib/iomgr/workqueue_windows.h \
+src/core/lib/json/json.c \
+src/core/lib/json/json.h \
+src/core/lib/json/json_common.h \
+src/core/lib/json/json_reader.c \
+src/core/lib/json/json_reader.h \
+src/core/lib/json/json_string.c \
+src/core/lib/json/json_writer.c \
+src/core/lib/json/json_writer.h \
+src/core/lib/slice/b64.c \
+src/core/lib/slice/b64.h \
+src/core/lib/slice/percent_encoding.c \
+src/core/lib/slice/percent_encoding.h \
+src/core/lib/slice/slice.c \
+src/core/lib/slice/slice_buffer.c \
+src/core/lib/slice/slice_hash_table.c \
+src/core/lib/slice/slice_hash_table.h \
+src/core/lib/slice/slice_intern.c \
+src/core/lib/slice/slice_internal.h \
+src/core/lib/slice/slice_string_helpers.c \
+src/core/lib/slice/slice_string_helpers.h \
+src/core/lib/surface/alarm.c \
+src/core/lib/surface/api_trace.c \
+src/core/lib/surface/api_trace.h \
+src/core/lib/surface/byte_buffer.c \
+src/core/lib/surface/byte_buffer_reader.c \
+src/core/lib/surface/call.c \
+src/core/lib/surface/call.h \
+src/core/lib/surface/call_details.c \
+src/core/lib/surface/call_log_batch.c \
+src/core/lib/surface/call_test_only.h \
+src/core/lib/surface/channel.c \
+src/core/lib/surface/channel.h \
+src/core/lib/surface/channel_init.c \
+src/core/lib/surface/channel_init.h \
+src/core/lib/surface/channel_ping.c \
+src/core/lib/surface/channel_stack_type.c \
+src/core/lib/surface/channel_stack_type.h \
+src/core/lib/surface/completion_queue.c \
+src/core/lib/surface/completion_queue.h \
+src/core/lib/surface/completion_queue_factory.c \
+src/core/lib/surface/completion_queue_factory.h \
+src/core/lib/surface/event_string.c \
+src/core/lib/surface/event_string.h \
+src/core/lib/surface/init.h \
+src/core/lib/surface/lame_client.cc \
+src/core/lib/surface/lame_client.h \
+src/core/lib/surface/metadata_array.c \
+src/core/lib/surface/server.c \
+src/core/lib/surface/server.h \
+src/core/lib/surface/validate_metadata.c \
+src/core/lib/surface/validate_metadata.h \
+src/core/lib/surface/version.c \
+src/core/lib/transport/bdp_estimator.c \
+src/core/lib/transport/bdp_estimator.h \
+src/core/lib/transport/byte_stream.c \
+src/core/lib/transport/byte_stream.h \
+src/core/lib/transport/connectivity_state.c \
+src/core/lib/transport/connectivity_state.h \
+src/core/lib/transport/error_utils.c \
+src/core/lib/transport/error_utils.h \
+src/core/lib/transport/http2_errors.h \
+src/core/lib/transport/metadata.c \
+src/core/lib/transport/metadata.h \
+src/core/lib/transport/metadata_batch.c \
+src/core/lib/transport/metadata_batch.h \
+src/core/lib/transport/pid_controller.c \
+src/core/lib/transport/pid_controller.h \
+src/core/lib/transport/service_config.c \
+src/core/lib/transport/service_config.h \
+src/core/lib/transport/static_metadata.c \
+src/core/lib/transport/static_metadata.h \
+src/core/lib/transport/status_conversion.c \
+src/core/lib/transport/status_conversion.h \
+src/core/lib/transport/timeout_encoding.c \
+src/core/lib/transport/timeout_encoding.h \
+src/core/lib/transport/transport.c \
+src/core/lib/transport/transport.h \
+src/core/lib/transport/transport_impl.h \
+src/core/lib/transport/transport_op_string.c \
 src/cpp/README.md \
 src/cpp/client/channel_cc.cc \
 src/cpp/client/client_context.cc \
@@ -914,6 +1152,7 @@ src/cpp/common/secure_channel_arguments.cc \
 src/cpp/common/secure_create_auth_context.cc \
 src/cpp/common/version_cc.cc \
 src/cpp/server/async_generic_service.cc \
+src/cpp/server/channel_argument_option.cc \
 src/cpp/server/create_default_thread_pool.cc \
 src/cpp/server/dynamic_thread_pool.cc \
 src/cpp/server/dynamic_thread_pool.h \
@@ -938,7 +1177,14 @@ src/cpp/util/byte_buffer_cc.cc \
 src/cpp/util/slice_cc.cc \
 src/cpp/util/status.cc \
 src/cpp/util/string_ref.cc \
-src/cpp/util/time_cc.cc
+src/cpp/util/time_cc.cc \
+third_party/nanopb/pb.h \
+third_party/nanopb/pb_common.c \
+third_party/nanopb/pb_common.h \
+third_party/nanopb/pb_decode.c \
+third_party/nanopb/pb_decode.h \
+third_party/nanopb/pb_encode.c \
+third_party/nanopb/pb_encode.h
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index 478bdb2d0427530c8e5f563b33e5e6fa5a69a62b..c3bfc6c4a8e32b15d63163976bd87f59b9d1df35 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -40,7 +40,7 @@ PROJECT_NAME           = "GRPC Core"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 3.0.0-dev
+PROJECT_NUMBER         = 4.0.0-dev
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
@@ -764,12 +764,14 @@ INPUT                  = doc/PROTOCOL-HTTP2.md \
 doc/PROTOCOL-WEB.md \
 doc/binary-logging.md \
 doc/c-style-guide.md \
+doc/combiner-explainer.md \
 doc/command_line_tool.md \
 doc/compression.md \
 doc/compression_cookbook.md \
 doc/connection-backoff-interop-test-description.md \
 doc/connection-backoff.md \
 doc/connectivity-semantics-and-api.md \
+doc/core/grpc-error.md \
 doc/core/pending_api_cleanups.md \
 doc/cpp-style-guide.md \
 doc/environment_variables.md \
@@ -778,15 +780,16 @@ doc/fail_fast.md \
 doc/g_stands_for.md \
 doc/health-checking.md \
 doc/http-grpc-status-mapping.md \
+doc/http2-interop-test-descriptions.md \
 doc/internationalization.md \
 doc/interop-test-descriptions.md \
 doc/load-balancing.md \
 doc/naming.md \
-doc/negative-http2-interop-test-descriptions.md \
 doc/server-reflection.md \
 doc/server_reflection_tutorial.md \
 doc/server_side_auth.md \
 doc/service_config.md \
+doc/status_ordering.md \
 doc/statuscodes.md \
 doc/stress_test_framework.md \
 doc/wait-for-ready.md \
@@ -819,7 +822,6 @@ include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/propagation_bits.h \
 include/grpc/impl/codegen/slice.h \
-include/grpc/impl/codegen/slice.h \
 include/grpc/impl/codegen/status.h \
 include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index a7d6aaeb9ef221a8c7c8d93dcdcdf6f6c6b662a3..51d77c2b521731da0e646b487a0cfb56c37e221e 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -40,7 +40,7 @@ PROJECT_NAME           = "GRPC Core"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 3.0.0-dev
+PROJECT_NUMBER         = 4.0.0-dev
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
@@ -764,12 +764,14 @@ INPUT                  = doc/PROTOCOL-HTTP2.md \
 doc/PROTOCOL-WEB.md \
 doc/binary-logging.md \
 doc/c-style-guide.md \
+doc/combiner-explainer.md \
 doc/command_line_tool.md \
 doc/compression.md \
 doc/compression_cookbook.md \
 doc/connection-backoff-interop-test-description.md \
 doc/connection-backoff.md \
 doc/connectivity-semantics-and-api.md \
+doc/core/grpc-error.md \
 doc/core/pending_api_cleanups.md \
 doc/cpp-style-guide.md \
 doc/environment_variables.md \
@@ -778,15 +780,16 @@ doc/fail_fast.md \
 doc/g_stands_for.md \
 doc/health-checking.md \
 doc/http-grpc-status-mapping.md \
+doc/http2-interop-test-descriptions.md \
 doc/internationalization.md \
 doc/interop-test-descriptions.md \
 doc/load-balancing.md \
 doc/naming.md \
-doc/negative-http2-interop-test-descriptions.md \
 doc/server-reflection.md \
 doc/server_reflection_tutorial.md \
 doc/server_side_auth.md \
 doc/service_config.md \
+doc/status_ordering.md \
 doc/statuscodes.md \
 doc/stress_test_framework.md \
 doc/wait-for-ready.md \
@@ -819,7 +822,6 @@ include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/propagation_bits.h \
 include/grpc/impl/codegen/slice.h \
-include/grpc/impl/codegen/slice.h \
 include/grpc/impl/codegen/status.h \
 include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync.h \
@@ -893,65 +895,86 @@ src/core/ext/census/trace_status.h \
 src/core/ext/census/trace_string.h \
 src/core/ext/census/tracing.c \
 src/core/ext/census/tracing.h \
-src/core/ext/client_channel/README.md \
-src/core/ext/client_channel/channel_connectivity.c \
-src/core/ext/client_channel/client_channel.c \
-src/core/ext/client_channel/client_channel.h \
-src/core/ext/client_channel/client_channel_factory.c \
-src/core/ext/client_channel/client_channel_factory.h \
-src/core/ext/client_channel/client_channel_plugin.c \
-src/core/ext/client_channel/connector.c \
-src/core/ext/client_channel/connector.h \
-src/core/ext/client_channel/default_initial_connect_string.c \
-src/core/ext/client_channel/http_connect_handshaker.c \
-src/core/ext/client_channel/http_connect_handshaker.h \
-src/core/ext/client_channel/http_proxy.c \
-src/core/ext/client_channel/http_proxy.h \
-src/core/ext/client_channel/initial_connect_string.c \
-src/core/ext/client_channel/initial_connect_string.h \
-src/core/ext/client_channel/lb_policy.c \
-src/core/ext/client_channel/lb_policy.h \
-src/core/ext/client_channel/lb_policy_factory.c \
-src/core/ext/client_channel/lb_policy_factory.h \
-src/core/ext/client_channel/lb_policy_registry.c \
-src/core/ext/client_channel/lb_policy_registry.h \
-src/core/ext/client_channel/parse_address.c \
-src/core/ext/client_channel/parse_address.h \
-src/core/ext/client_channel/proxy_mapper.c \
-src/core/ext/client_channel/proxy_mapper.h \
-src/core/ext/client_channel/proxy_mapper_registry.c \
-src/core/ext/client_channel/proxy_mapper_registry.h \
-src/core/ext/client_channel/resolver.c \
-src/core/ext/client_channel/resolver.h \
-src/core/ext/client_channel/resolver_factory.c \
-src/core/ext/client_channel/resolver_factory.h \
-src/core/ext/client_channel/resolver_registry.c \
-src/core/ext/client_channel/resolver_registry.h \
-src/core/ext/client_channel/subchannel.c \
-src/core/ext/client_channel/subchannel.h \
-src/core/ext/client_channel/subchannel_index.c \
-src/core/ext/client_channel/subchannel_index.h \
-src/core/ext/client_channel/uri_parser.c \
-src/core/ext/client_channel/uri_parser.h \
-src/core/ext/lb_policy/grpclb/grpclb.c \
-src/core/ext/lb_policy/grpclb/grpclb.h \
-src/core/ext/lb_policy/grpclb/grpclb_channel.h \
-src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c \
-src/core/ext/lb_policy/grpclb/load_balancer_api.c \
-src/core/ext/lb_policy/grpclb/load_balancer_api.h \
-src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
-src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h \
-src/core/ext/lb_policy/pick_first/pick_first.c \
-src/core/ext/lb_policy/round_robin/round_robin.c \
-src/core/ext/load_reporting/load_reporting.c \
-src/core/ext/load_reporting/load_reporting.h \
-src/core/ext/load_reporting/load_reporting_filter.c \
-src/core/ext/load_reporting/load_reporting_filter.h \
-src/core/ext/resolver/README.md \
-src/core/ext/resolver/dns/native/README.md \
-src/core/ext/resolver/dns/native/dns_resolver.c \
-src/core/ext/resolver/sockaddr/README.md \
-src/core/ext/resolver/sockaddr/sockaddr_resolver.c \
+src/core/ext/filters/client_channel/README.md \
+src/core/ext/filters/client_channel/channel_connectivity.c \
+src/core/ext/filters/client_channel/client_channel.c \
+src/core/ext/filters/client_channel/client_channel.h \
+src/core/ext/filters/client_channel/client_channel_factory.c \
+src/core/ext/filters/client_channel/client_channel_factory.h \
+src/core/ext/filters/client_channel/client_channel_plugin.c \
+src/core/ext/filters/client_channel/connector.c \
+src/core/ext/filters/client_channel/connector.h \
+src/core/ext/filters/client_channel/http_connect_handshaker.c \
+src/core/ext/filters/client_channel/http_connect_handshaker.h \
+src/core/ext/filters/client_channel/http_proxy.c \
+src/core/ext/filters/client_channel/http_proxy.h \
+src/core/ext/filters/client_channel/lb_policy.c \
+src/core/ext/filters/client_channel/lb_policy.h \
+src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c \
+src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h \
+src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c \
+src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h \
+src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h \
+src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c \
+src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c \
+src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h \
+src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c \
+src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h \
+src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
+src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h \
+src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c \
+src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c \
+src/core/ext/filters/client_channel/lb_policy_factory.c \
+src/core/ext/filters/client_channel/lb_policy_factory.h \
+src/core/ext/filters/client_channel/lb_policy_registry.c \
+src/core/ext/filters/client_channel/lb_policy_registry.h \
+src/core/ext/filters/client_channel/parse_address.c \
+src/core/ext/filters/client_channel/parse_address.h \
+src/core/ext/filters/client_channel/proxy_mapper.c \
+src/core/ext/filters/client_channel/proxy_mapper.h \
+src/core/ext/filters/client_channel/proxy_mapper_registry.c \
+src/core/ext/filters/client_channel/proxy_mapper_registry.h \
+src/core/ext/filters/client_channel/resolver.c \
+src/core/ext/filters/client_channel/resolver.h \
+src/core/ext/filters/client_channel/resolver/README.md \
+src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c \
+src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h \
+src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c \
+src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c \
+src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h \
+src/core/ext/filters/client_channel/resolver/dns/native/README.md \
+src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c \
+src/core/ext/filters/client_channel/resolver/sockaddr/README.md \
+src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c \
+src/core/ext/filters/client_channel/resolver_factory.c \
+src/core/ext/filters/client_channel/resolver_factory.h \
+src/core/ext/filters/client_channel/resolver_registry.c \
+src/core/ext/filters/client_channel/resolver_registry.h \
+src/core/ext/filters/client_channel/retry_throttle.c \
+src/core/ext/filters/client_channel/retry_throttle.h \
+src/core/ext/filters/client_channel/subchannel.c \
+src/core/ext/filters/client_channel/subchannel.h \
+src/core/ext/filters/client_channel/subchannel_index.c \
+src/core/ext/filters/client_channel/subchannel_index.h \
+src/core/ext/filters/client_channel/uri_parser.c \
+src/core/ext/filters/client_channel/uri_parser.h \
+src/core/ext/filters/deadline/deadline_filter.c \
+src/core/ext/filters/deadline/deadline_filter.h \
+src/core/ext/filters/http/client/http_client_filter.c \
+src/core/ext/filters/http/client/http_client_filter.h \
+src/core/ext/filters/http/http_filters_plugin.c \
+src/core/ext/filters/http/message_compress/message_compress_filter.c \
+src/core/ext/filters/http/message_compress/message_compress_filter.h \
+src/core/ext/filters/http/server/http_server_filter.c \
+src/core/ext/filters/http/server/http_server_filter.h \
+src/core/ext/filters/load_reporting/load_reporting.c \
+src/core/ext/filters/load_reporting/load_reporting.h \
+src/core/ext/filters/load_reporting/load_reporting_filter.c \
+src/core/ext/filters/load_reporting/load_reporting_filter.h \
+src/core/ext/filters/max_age/max_age_filter.c \
+src/core/ext/filters/max_age/max_age_filter.h \
+src/core/ext/filters/message_size/message_size_filter.c \
+src/core/ext/filters/message_size/message_size_filter.h \
 src/core/ext/transport/README.md \
 src/core/ext/transport/chttp2/README.md \
 src/core/ext/transport/chttp2/alpn/alpn.c \
@@ -997,6 +1020,8 @@ src/core/ext/transport/chttp2/transport/hpack_parser.c \
 src/core/ext/transport/chttp2/transport/hpack_parser.h \
 src/core/ext/transport/chttp2/transport/hpack_table.c \
 src/core/ext/transport/chttp2/transport/hpack_table.h \
+src/core/ext/transport/chttp2/transport/http2_settings.c \
+src/core/ext/transport/chttp2/transport/http2_settings.h \
 src/core/ext/transport/chttp2/transport/huffsyms.c \
 src/core/ext/transport/chttp2/transport/huffsyms.h \
 src/core/ext/transport/chttp2/transport/incoming_metadata.c \
@@ -1017,25 +1042,15 @@ src/core/lib/channel/channel_stack.c \
 src/core/lib/channel/channel_stack.h \
 src/core/lib/channel/channel_stack_builder.c \
 src/core/lib/channel/channel_stack_builder.h \
-src/core/lib/channel/compress_filter.c \
-src/core/lib/channel/compress_filter.h \
 src/core/lib/channel/connected_channel.c \
 src/core/lib/channel/connected_channel.h \
 src/core/lib/channel/context.h \
-src/core/lib/channel/deadline_filter.c \
-src/core/lib/channel/deadline_filter.h \
 src/core/lib/channel/handshaker.c \
 src/core/lib/channel/handshaker.h \
 src/core/lib/channel/handshaker_factory.c \
 src/core/lib/channel/handshaker_factory.h \
 src/core/lib/channel/handshaker_registry.c \
 src/core/lib/channel/handshaker_registry.h \
-src/core/lib/channel/http_client_filter.c \
-src/core/lib/channel/http_client_filter.h \
-src/core/lib/channel/http_server_filter.c \
-src/core/lib/channel/http_server_filter.h \
-src/core/lib/channel/message_size_filter.c \
-src/core/lib/channel/message_size_filter.h \
 src/core/lib/compression/algorithm_metadata.h \
 src/core/lib/compression/compression.c \
 src/core/lib/compression/message_compress.c \
@@ -1084,6 +1099,8 @@ src/core/lib/iomgr/iomgr_uv.c \
 src/core/lib/iomgr/iomgr_windows.c \
 src/core/lib/iomgr/load_file.c \
 src/core/lib/iomgr/load_file.h \
+src/core/lib/iomgr/lockfree_event.c \
+src/core/lib/iomgr/lockfree_event.h \
 src/core/lib/iomgr/network_status_tracker.c \
 src/core/lib/iomgr/network_status_tracker.h \
 src/core/lib/iomgr/polling_entity.c \
@@ -1109,6 +1126,8 @@ src/core/lib/iomgr/sockaddr_posix.h \
 src/core/lib/iomgr/sockaddr_utils.c \
 src/core/lib/iomgr/sockaddr_utils.h \
 src/core/lib/iomgr/sockaddr_windows.h \
+src/core/lib/iomgr/socket_factory_posix.c \
+src/core/lib/iomgr/socket_factory_posix.h \
 src/core/lib/iomgr/socket_mutator.c \
 src/core/lib/iomgr/socket_mutator.h \
 src/core/lib/iomgr/socket_utils.h \
@@ -1129,6 +1148,10 @@ src/core/lib/iomgr/tcp_posix.c \
 src/core/lib/iomgr/tcp_posix.h \
 src/core/lib/iomgr/tcp_server.h \
 src/core/lib/iomgr/tcp_server_posix.c \
+src/core/lib/iomgr/tcp_server_utils_posix.h \
+src/core/lib/iomgr/tcp_server_utils_posix_common.c \
+src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c \
+src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c \
 src/core/lib/iomgr/tcp_server_uv.c \
 src/core/lib/iomgr/tcp_server_windows.c \
 src/core/lib/iomgr/tcp_uv.c \
@@ -1212,10 +1235,10 @@ src/core/lib/security/transport/security_handshaker.h \
 src/core/lib/security/transport/server_auth_filter.c \
 src/core/lib/security/transport/tsi_error.c \
 src/core/lib/security/transport/tsi_error.h \
-src/core/lib/security/util/b64.c \
-src/core/lib/security/util/b64.h \
 src/core/lib/security/util/json_util.c \
 src/core/lib/security/util/json_util.h \
+src/core/lib/slice/b64.c \
+src/core/lib/slice/b64.h \
 src/core/lib/slice/percent_encoding.c \
 src/core/lib/slice/percent_encoding.h \
 src/core/lib/slice/slice.c \
@@ -1227,6 +1250,12 @@ src/core/lib/slice/slice_internal.h \
 src/core/lib/slice/slice_string_helpers.c \
 src/core/lib/slice/slice_string_helpers.h \
 src/core/lib/support/alloc.c \
+src/core/lib/support/arena.c \
+src/core/lib/support/arena.h \
+src/core/lib/support/atm.c \
+src/core/lib/support/atomic.h \
+src/core/lib/support/atomic_with_atm.h \
+src/core/lib/support/atomic_with_std.h \
 src/core/lib/support/avl.c \
 src/core/lib/support/backoff.c \
 src/core/lib/support/backoff.h \
@@ -1247,6 +1276,7 @@ src/core/lib/support/log_android.c \
 src/core/lib/support/log_linux.c \
 src/core/lib/support/log_posix.c \
 src/core/lib/support/log_windows.c \
+src/core/lib/support/memory.h \
 src/core/lib/support/mpscq.c \
 src/core/lib/support/mpscq.h \
 src/core/lib/support/murmur_hash.c \
@@ -1300,12 +1330,14 @@ src/core/lib/surface/channel_stack_type.c \
 src/core/lib/surface/channel_stack_type.h \
 src/core/lib/surface/completion_queue.c \
 src/core/lib/surface/completion_queue.h \
+src/core/lib/surface/completion_queue_factory.c \
+src/core/lib/surface/completion_queue_factory.h \
 src/core/lib/surface/event_string.c \
 src/core/lib/surface/event_string.h \
 src/core/lib/surface/init.c \
 src/core/lib/surface/init.h \
 src/core/lib/surface/init_secure.c \
-src/core/lib/surface/lame_client.c \
+src/core/lib/surface/lame_client.cc \
 src/core/lib/surface/lame_client.h \
 src/core/lib/surface/metadata_array.c \
 src/core/lib/surface/server.c \
@@ -1341,16 +1373,18 @@ src/core/lib/transport/transport.c \
 src/core/lib/transport/transport.h \
 src/core/lib/transport/transport_impl.h \
 src/core/lib/transport/transport_op_string.c \
-src/core/lib/tsi/README.md \
-src/core/lib/tsi/fake_transport_security.c \
-src/core/lib/tsi/fake_transport_security.h \
-src/core/lib/tsi/ssl_transport_security.c \
-src/core/lib/tsi/ssl_transport_security.h \
-src/core/lib/tsi/ssl_types.h \
-src/core/lib/tsi/transport_security.c \
-src/core/lib/tsi/transport_security.h \
-src/core/lib/tsi/transport_security_interface.h \
 src/core/plugin_registry/grpc_plugin_registry.c \
+src/core/tsi/README.md \
+src/core/tsi/fake_transport_security.c \
+src/core/tsi/fake_transport_security.h \
+src/core/tsi/ssl_transport_security.c \
+src/core/tsi/ssl_transport_security.h \
+src/core/tsi/ssl_types.h \
+src/core/tsi/transport_security.c \
+src/core/tsi/transport_security.h \
+src/core/tsi/transport_security_adapter.c \
+src/core/tsi/transport_security_adapter.h \
+src/core/tsi/transport_security_interface.h \
 third_party/nanopb/pb.h \
 third_party/nanopb/pb_common.c \
 third_party/nanopb/pb_common.h \
diff --git a/tools/fuzzer/options/api_fuzzer.options b/tools/fuzzer/options/api_fuzzer.options
new file mode 100644
index 0000000000000000000000000000000000000000..8871ae21b6a54997ef74793be722295fa281d3ab
--- /dev/null
+++ b/tools/fuzzer/options/api_fuzzer.options
@@ -0,0 +1,3 @@
+[libfuzzer]
+max_len = 2048
+dict = api_fuzzer.dictionary
diff --git a/tools/fuzzer/options/client_fuzzer.options b/tools/fuzzer/options/client_fuzzer.options
new file mode 100644
index 0000000000000000000000000000000000000000..fd2eebf7d2532faddab0109c63117ad62105e125
--- /dev/null
+++ b/tools/fuzzer/options/client_fuzzer.options
@@ -0,0 +1,3 @@
+[libfuzzer]
+max_len = 2048
+dict = hpack.dictionary
diff --git a/tools/fuzzer/options/fuzzer.options b/tools/fuzzer/options/fuzzer.options
new file mode 100644
index 0000000000000000000000000000000000000000..5d468bc6e480feedf7560222fc9a36e7cee246ff
--- /dev/null
+++ b/tools/fuzzer/options/fuzzer.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 512
diff --git a/tools/fuzzer/options/fuzzer_response.options b/tools/fuzzer/options/fuzzer_response.options
new file mode 100644
index 0000000000000000000000000000000000000000..5dcdfac7a69dacd251fe1a6b7a2123247dcb8446
--- /dev/null
+++ b/tools/fuzzer/options/fuzzer_response.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 128
diff --git a/tools/fuzzer/options/fuzzer_serverlist.options b/tools/fuzzer/options/fuzzer_serverlist.options
new file mode 100644
index 0000000000000000000000000000000000000000..5dcdfac7a69dacd251fe1a6b7a2123247dcb8446
--- /dev/null
+++ b/tools/fuzzer/options/fuzzer_serverlist.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 128
diff --git a/tools/fuzzer/options/hpack_parser_fuzzer_test.options b/tools/fuzzer/options/hpack_parser_fuzzer_test.options
new file mode 100644
index 0000000000000000000000000000000000000000..584487fafc2f535b73b812337a82d1a2db3976f5
--- /dev/null
+++ b/tools/fuzzer/options/hpack_parser_fuzzer_test.options
@@ -0,0 +1,3 @@
+[libfuzzer]
+max_len = 512
+dict = hpack.dictionary
diff --git a/tools/fuzzer/options/percent_decode_fuzzer.options b/tools/fuzzer/options/percent_decode_fuzzer.options
new file mode 100644
index 0000000000000000000000000000000000000000..ea2785e1104a1e005c4165dd1fba518325f924fa
--- /dev/null
+++ b/tools/fuzzer/options/percent_decode_fuzzer.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 32
diff --git a/tools/fuzzer/options/percent_encode_fuzzer.options b/tools/fuzzer/options/percent_encode_fuzzer.options
new file mode 100644
index 0000000000000000000000000000000000000000..ea2785e1104a1e005c4165dd1fba518325f924fa
--- /dev/null
+++ b/tools/fuzzer/options/percent_encode_fuzzer.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 32
diff --git a/tools/fuzzer/options/request_fuzzer.options b/tools/fuzzer/options/request_fuzzer.options
new file mode 100644
index 0000000000000000000000000000000000000000..fd32ac16e1bae39375eda07c8a03758b3666caa6
--- /dev/null
+++ b/tools/fuzzer/options/request_fuzzer.options
@@ -0,0 +1,3 @@
+[libfuzzer]
+max_len = 2048
+
diff --git a/tools/fuzzer/options/response_fuzzer.options b/tools/fuzzer/options/response_fuzzer.options
new file mode 100644
index 0000000000000000000000000000000000000000..fd32ac16e1bae39375eda07c8a03758b3666caa6
--- /dev/null
+++ b/tools/fuzzer/options/response_fuzzer.options
@@ -0,0 +1,3 @@
+[libfuzzer]
+max_len = 2048
+
diff --git a/tools/fuzzer/options/server_fuzzer.options b/tools/fuzzer/options/server_fuzzer.options
new file mode 100644
index 0000000000000000000000000000000000000000..fd2eebf7d2532faddab0109c63117ad62105e125
--- /dev/null
+++ b/tools/fuzzer/options/server_fuzzer.options
@@ -0,0 +1,3 @@
+[libfuzzer]
+max_len = 2048
+dict = hpack.dictionary
diff --git a/tools/fuzzer/options/ssl_server_fuzzer.options b/tools/fuzzer/options/ssl_server_fuzzer.options
new file mode 100644
index 0000000000000000000000000000000000000000..60bd9b0b2fa5c5f3589793030eeac07111535333
--- /dev/null
+++ b/tools/fuzzer/options/ssl_server_fuzzer.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 2048
diff --git a/tools/fuzzer/options/uri_fuzzer_test.options b/tools/fuzzer/options/uri_fuzzer_test.options
new file mode 100644
index 0000000000000000000000000000000000000000..5dcdfac7a69dacd251fe1a6b7a2123247dcb8446
--- /dev/null
+++ b/tools/fuzzer/options/uri_fuzzer_test.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 128
diff --git a/tools/gce/create_linux_performance_worker.sh b/tools/gce/create_linux_performance_worker.sh
index 2c8cf0b96b308c019dfe0a5a5f9ca0c63f09dfb6..68710e13b0790f6fe148af1d5cccbb16715270f7 100755
--- a/tools/gce/create_linux_performance_worker.sh
+++ b/tools/gce/create_linux_performance_worker.sh
@@ -42,14 +42,14 @@ CLOUD_PROJECT=grpc-testing
 ZONE=us-central1-b  # this zone allows 32core machines
 
 INSTANCE_NAME="${1:-grpc-performance-server1}"
-MACHINE_TYPE=n1-standard-8
+MACHINE_TYPE=n1-standard-32
 
 gcloud compute instances create $INSTANCE_NAME \
     --project="$CLOUD_PROJECT" \
     --zone "$ZONE" \
     --machine-type $MACHINE_TYPE \
     --image-project ubuntu-os-cloud \
-    --image-family ubuntu-1604-lts \
+    --image-family ubuntu-1610 \
     --boot-disk-size 300 \
     --scopes https://www.googleapis.com/auth/bigquery
 
diff --git a/tools/gce/linux_performance_worker_init.sh b/tools/gce/linux_performance_worker_init.sh
index 3380f3de3e5c9b8625dad0a60be5899260edd898..78cdd31f0b0f2949906f4628a140f62c89b6f6a5 100755
--- a/tools/gce/linux_performance_worker_init.sh
+++ b/tools/gce/linux_performance_worker_init.sh
@@ -40,11 +40,6 @@ sudo apt-get update
 sudo apt-get install -y openjdk-8-jdk
 sudo apt-get install -y unzip lsof
 
-# Add pubkey of jenkins@grpc-jenkins-master to authorized keys of jenkins@
-# This needs to happen as the last step to prevent Jenkins master from connecting
-# to a machine that hasn't been properly setup yet.
-cat jenkins_master.pub | sudo tee --append ~jenkins/.ssh/authorized_keys
-
 sudo apt-get install -y \
   autoconf \
   autotools-dev \
@@ -60,7 +55,10 @@ sudo apt-get install -y \
   libc6 \
   libc6-dbg \
   libc6-dev \
+  libcurl4-openssl-dev \
   libgtest-dev \
+  libreadline-dev \
+  libssl-dev \
   libtool \
   make \
   strace \
@@ -76,7 +74,8 @@ sudo apt-get install -y \
   telnet \
   unzip \
   wget \
-  zip
+  zip \
+  zlib1g-dev
 
 # perftools
 sudo apt-get install -y google-perftools libgoogle-perftools-dev
@@ -92,14 +91,15 @@ sudo pip install tabulate
 sudo pip install google-api-python-client
 sudo pip install virtualenv
 
-# TODO(jtattermusch): For some reason, building gRPC Python depends on python3.4
-# being installed, but python3.4 is not available on Ubuntu 16.04.
-# Temporarily fixing this by adding a PPA with python3.4, but we should
-# really remove this hack once possible.
-sudo add-apt-repository -y ppa:fkrull/deadsnakes
-sudo apt-get update
-sudo apt-get install -y python3.4 python3.4-dev
-python3.4 -m pip install virtualenv
+# Building gRPC Python depends on python3.4 being installed, but python3.4
+# is not available on Ubuntu 16.10, so install from source
+curl -O https://www.python.org/ftp/python/3.4.6/Python-3.4.6.tgz
+tar xzvf Python-3.4.6.tgz
+cd Python-3.4.6
+./configure --enable-shared --prefix=/usr/local LDFLAGS="-Wl,--rpath=/usr/local/lib"
+sudo make altinstall
+cd ..
+rm Python-3.4.6.tgz
 
 curl -O https://bootstrap.pypa.io/get-pip.py
 sudo pypy get-pip.py
@@ -122,17 +122,25 @@ sudo apt-get update
 sudo apt-get install -y mono-devel nuget
 
 # C# .NET Core dependencies (https://www.microsoft.com/net/core#ubuntu)
-sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ xenial main" > /etc/apt/sources.list.d/dotnetdev.list'
+sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ yakkety main" > /etc/apt/sources.list.d/dotnetdev.list'
 sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893
 sudo apt-get update
-sudo apt-get install -y dotnet-dev-1.0.0-preview2-003131
+sudo apt-get install -y dotnet-dev-1.0.0-preview2.1-003155
+sudo apt-get install -y dotnet-dev-1.0.1
 
 # Ruby dependencies
-gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
-curl -sSL https://get.rvm.io | bash -s stable --ruby
+git clone https://github.com/rbenv/rbenv.git ~/.rbenv
+export PATH="$HOME/.rbenv/bin:$PATH"
+eval "$(rbenv init -)"
+
+git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
+export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"
+
+rbenv install 2.4.0
+rbenv global 2.4.0
+ruby -v
 
 # Install bundler (prerequisite for gRPC Ruby)
-source ~/.rvm/scripts/rvm
 gem install bundler
 
 # Java dependencies - nothing as we already have Java JDK 8
@@ -166,3 +174,15 @@ echo 4096 | sudo tee /proc/sys/kernel/perf_event_mlock_kb
 # on benchmarks
 git clone -v https://github.com/brendangregg/FlameGraph ~/FlameGraph
 
+# Install scipy and numpy for benchmarking scripts
+sudo apt-get install -y python-scipy python-numpy
+
+# Add pubkey of jenkins@grpc-jenkins-master to authorized keys of jenkins@
+# This needs to happen as the last step to prevent Jenkins master from connecting
+# to a machine that hasn't been properly setup yet.
+cat jenkins_master.pub | sudo tee --append ~jenkins/.ssh/authorized_keys
+
+# Restart for VM to pick up kernel update
+echo 'Successfully initialized the linux worker, going for reboot in 10 seconds'
+sleep 10
+sudo reboot
diff --git a/tools/gce/linux_worker_init.sh b/tools/gce/linux_worker_init.sh
index 9230acdca6d88bba031be7efceb78f887720f658..d552343bde611917ef4a457f788d23c285651a8d 100755
--- a/tools/gce/linux_worker_init.sh
+++ b/tools/gce/linux_worker_init.sh
@@ -59,19 +59,27 @@ sudo usermod -aG docker jenkins
 
 # Use "overlay" storage driver for docker
 # see https://github.com/grpc/grpc/issues/4988
-echo 'DOCKER_OPTS="${DOCKER_OPTS} --storage-driver=overlay"' | sudo tee --append /etc/default/docker
+printf "{\n\t\"storage-driver\": \"overlay\"\n}" | sudo tee /etc/docker/daemon.json
 
 # Install RVM
 # TODO(jtattermusch): why is RVM needed?
 gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
 curl -sSL https://get.rvm.io | bash -s stable --ruby
 
+# Upgrade Linux kernel to 4.9
+wget \
+  kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.20/linux-headers-4.9.20-040920_4.9.20-040920.201703310531_all.deb \
+  kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.20/linux-headers-4.9.20-040920-generic_4.9.20-040920.201703310531_amd64.deb \
+  kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.20/linux-image-4.9.20-040920-generic_4.9.20-040920.201703310531_amd64.deb
+sudo dpkg -i linux-headers-4.9*.deb linux-image-4.9*.deb
+rm linux-*
+
 # Add pubkey of jenkins@grpc-jenkins-master to authorized keys of jenkins@
 # This needs to happen as the last step to prevent Jenkins master from connecting
 # to a machine that hasn't been properly setup yet.
 cat jenkins_master.pub | sudo tee --append ~jenkins/.ssh/authorized_keys
 
-# Restart for docker to pickup the config changes.
+# Restart for docker to pick up the config changes.
 echo 'Successfully initialized the linux worker, going for reboot in 10 seconds'
 sleep 10
 
diff --git a/tools/gcp/utils/gcr_upload.py b/tools/gcp/utils/gcr_upload.py
new file mode 100755
index 0000000000000000000000000000000000000000..b22f8731f68ecdaa4a13afb8b3208f0f4a9949f2
--- /dev/null
+++ b/tools/gcp/utils/gcr_upload.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python2.7
+# Copyright 2017, 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.
+
+"""Upload docker images to Google Container Registry."""
+
+from __future__ import print_function
+
+import argparse
+import atexit
+import os
+import shutil
+import subprocess
+import tempfile
+
+argp = argparse.ArgumentParser(description='Run interop tests.')
+argp.add_argument('--gcr_path',
+                  default='gcr.io/grpc-testing',
+                  help='Path of docker images in Google Container Registry')
+
+argp.add_argument('--gcr_tag',
+                  default='latest',
+                  help='the tag string for the images to upload')
+
+argp.add_argument('--with_files',
+                  default=[],
+                  nargs='+',
+                  help='additional files to include in the docker image')
+
+argp.add_argument('--with_file_dest',
+                  default='/var/local/image_info',
+                  help='Destination directory for with_files inside docker image')
+
+argp.add_argument('--images',
+                  default=[],
+                  nargs='+',
+                  help='local docker images in the form of repo:tag ' +
+                  '(i.e. grpc_interop_java:26328ad8) to upload')
+
+argp.add_argument('--keep',
+                  action='store_true',
+                  help='keep the created local images after uploading to GCR')
+
+
+args = argp.parse_args()
+
+def upload_to_gcr(image):
+  """Tags and Pushes a docker image in Google Containger Registry.
+
+  image: docker image name, i.e. grpc_interop_java:26328ad8
+
+  A docker image image_foo:tag_old will be uploaded as
+     <gcr_path>/image_foo:<gcr_tag>
+  after inserting extra with_files under with_file_dest in the image.  The
+  original image name will be stored as label original_name:"image_foo:tag_old".
+  """
+  tag_idx = image.find(':')
+  if tag_idx == -1:
+    print('Failed to parse docker image name %s' % image)
+    return False
+  new_tag = '%s/%s:%s' % (args.gcr_path, image[:tag_idx], args.gcr_tag)
+
+  lines = ['FROM ' + image]
+  lines.append('LABEL original_name="%s"' % image)
+
+  temp_dir = tempfile.mkdtemp()
+  atexit.register(lambda: subprocess.call(['rm', '-rf', temp_dir]))
+
+  # Copy with_files inside the tmp directory, which will be the docker build
+  # context.
+  for f in args.with_files:
+    shutil.copy(f, temp_dir)
+    lines.append('COPY %s %s/' % (os.path.basename(f), args.with_file_dest))
+
+  # Create a Dockerfile.
+  with open(os.path.join(temp_dir, 'Dockerfile'), 'w') as f:
+     f.write('\n'.join(lines))
+
+  build_cmd = ['docker', 'build', '--rm', '--tag', new_tag, temp_dir]
+  subprocess.check_output(build_cmd)
+
+  if not args.keep:
+    atexit.register(lambda: subprocess.call(['docker', 'rmi', new_tag]))
+
+  # Upload to GCR.
+  if args.gcr_path:
+    subprocess.call(['gcloud', 'docker', '--', 'push', new_tag])
+
+  return True
+
+
+for image in args.images:
+  upload_to_gcr(image)
diff --git a/tools/grift/README.md b/tools/grift/README.md
index 7cbbdc567bf3cecb7a90b7be65411e6753baa76f..2b5fa5ae14b14bab4ad583adf55f8e37ee45a46a 100644
--- a/tools/grift/README.md
+++ b/tools/grift/README.md
@@ -1,6 +1,4 @@
-Copyright 2016 Google Inc.
-
-#Documentation
+# Documentation
 
 grift is integration of [Apache Thrift](https://github.com/apache/thrift.git) Serializer with gRPC.
 
@@ -8,19 +6,19 @@ This integration allows you to use grpc to send thrift messages in C++ and java.
 
 grift uses Compact Protocol to serialize thrift messages. 
 
-##generating grpc plugins for thrift services
+## generating grpc plugins for thrift services
 
-###CPP
+### C++
 ```sh
  $ thrift --gen cpp <thrift-file>
 ```
 
-###JAVA
+### Java
 ```sh
  $ thrift --gen java <thrift-file>
 ```
 
-#Installation
+# Installation
 
 Before Installing thrift make sure to apply this [patch](grpc_plugins_generator.patch) to third_party/thrift.
 Go to third_party/thrift and follow the [INSTALLATION](https://github.com/apache/thrift.git) instructions to install thrift with commit id bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c.
\ No newline at end of file
diff --git a/tools/grpcz/BUILD b/tools/grpcz/BUILD
new file mode 100644
index 0000000000000000000000000000000000000000..cc887a53751983458028378dded0a9db4ef8759c
--- /dev/null
+++ b/tools/grpcz/BUILD
@@ -0,0 +1,63 @@
+# Copyright 2017, 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.
+
+licenses(["notice"])  # 3-clause BSD
+
+package(default_visibility = ["//visibility:public"])
+
+load("//:bazel/grpc_build_system.bzl", "grpc_proto_library")
+
+grpc_proto_library(
+    name = "monitoring_proto",
+    srcs = [
+        "monitoring.proto",
+    ],
+    well_known_protos = "@com_google_protobuf//:well_known_protos",
+    deps = [
+        ":census_proto",
+    ],
+)
+
+grpc_proto_library(
+    name = "census_proto",
+    srcs = [
+        "census.proto",
+    ],
+    well_known_protos = "@com_google_protobuf//:well_known_protos",
+)
+
+cc_binary(
+    name = "grpcz_client",
+    srcs = ["grpcz_client.cc"],
+    deps = [
+        "monitoring_proto",
+        "//external:gflags",
+        "@mongoose_repo//:mongoose_lib",
+    ],
+)
diff --git a/tools/grpcz/census.proto b/tools/grpcz/census.proto
new file mode 100644
index 0000000000000000000000000000000000000000..d1ff69400b05231382af485949ff0b408e1a11f5
--- /dev/null
+++ b/tools/grpcz/census.proto
@@ -0,0 +1,318 @@
+// Copyright 2017, Google Inc.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//     http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//TODO(ericgribkoff) Depend on this directly from the instrumentation-proto
+//repository.
+
+syntax = "proto3";
+
+package google.instrumentation;
+
+option java_package = "com.google.instrumentation.stats.proto";
+option java_outer_classname = "CensusProto";
+
+// All the census protos.
+//
+// Nomenclature notes:
+//   * Capitalized names below (like View) are protos.
+//   * Protos which describe types are named with a Descriptor suffix (e.g.
+//     MesurementDescriptor).
+//
+// Census lets you define the type and description of the data being measured
+// (e.g. the latency of an RPC or the number of CPU cycles spent on an
+// operation using MeasurementDescriptor. As individual measurements (a double
+// value) for are recorded, they are aggregated together into an
+// Aggregation. There are two Aggregation types available: Distribution
+// (describes the distribution of all measurements, possibly with a histogram)
+// and IntervalStats (the count and mean of measurements across specified time
+// periods). An Aggregation is described by an AggregationDescriptor.
+//
+// You can define how your measurements (described by a MeasurementDescriptor)
+// are broken down by Tag values and which Aggregations to use through a
+// ViewDescriptor. The output (all measurements broken down by tag values into
+// specific Aggregations) is called a View.
+
+
+// The following two types are copied from
+// google/protobuf/{duration,timestamp}.proto. Ideally, we would be able to
+// import them, but this causes compilation issues on C-based systems
+// (e.g. https://koti.kapsi.fi/jpa/nanopb/), which cannot process the C++
+// headers generated from the standard protobuf distribution. See the relevant
+// proto files for full documentation of these types.
+
+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;
+}
+
+message Timestamp {
+  // Represents seconds of UTC time since Unix epoch
+  // 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
+  // 9999-12-31T23:59:59Z inclusive.
+  int64 seconds = 1;
+
+  // Non-negative fractions of a second at nanosecond resolution. Negative
+  // second values with fractions must still have non-negative nanos values
+  // that count forward in time. Must be from 0 to 999,999,999
+  // inclusive.
+  int32 nanos = 2;
+}
+
+// MeasurementDescriptor describes a data point (measurement) type.
+message MeasurementDescriptor {
+  // A descriptive name, e.g. rpc_latency, cpu. Must be unique.
+  string name = 1;
+
+  // More detailed description of the resource, used in documentation.
+  string description = 2;
+
+  // Fundamental units of measurement supported by Census
+  // TODO(aveitch): expand this to include other S.I. units?
+  enum BasicUnit {
+    UNKNOWN = 0;    // Implementations should not use this
+    SCALAR = 1;     // Dimensionless
+    BITS = 2;       // A single bit
+    BYTES = 3;      // An 8-bit byte
+    SECONDS = 4;    // S.I. unit
+    CORES = 5;      // CPU core usage
+    MAX_UNITS = 6;  // Last defined value; implementations should only use
+                    // this for validation.
+  }
+
+  // MeasurementUnit lets you build compound units of the form
+  //   10^n * (A * B * ...) / (X * Y * ...),
+  // where the elements in the numerator and denominator are all BasicUnits.  A
+  // MeasurementUnit must have at least one BasicUnit in its numerator.
+  //
+  // To specify multiplication in the numerator or denominator, simply specify
+  // multiple numerator or denominator fields.  For example:
+  //
+  // - byte-seconds (i.e. bytes * seconds):
+  //     numerator: BYTES
+  //     numerator: SECS
+  //
+  // - events/sec^2 (i.e. rate of change of events/sec):
+  //     numerator: SCALAR
+  //     denominator: SECS
+  //     denominator: SECS
+  //
+  // To specify multiples (in power of 10) of units, specify a non-zero
+  // 'power10' value, for example:
+  //
+  // - MB/s (i.e. megabytes / s):
+  //     power10: 6
+  //     numerator: BYTES
+  //     denominator: SECS
+  //
+  // - nanoseconds
+  //     power10: -9
+  //     numerator: SECS
+  message MeasurementUnit {
+    int32 power10 = 1;
+    repeated BasicUnit numerators = 2;
+    repeated BasicUnit denominators = 3;
+  }
+
+  // The units used by this type of measurement.
+  MeasurementUnit unit = 3;
+}
+
+// An aggregation summarizes a series of individual measurements. There are
+// two types of aggregation (IntervalAggregation and DistributionAggregation),
+// unique types of each can be set using descriptors for each.
+
+// DistributionAggregation contains summary statistics for a population of
+// values and, optionally, a histogram representing the distribution of those
+// values across a specified set of histogram buckets, as defined in
+// DistributionAggregationDescriptor.bucket_bounds.
+//
+// The summary statistics are the count, mean, minimum, and the maximum of the
+// set of population of values.
+//
+// Although it is not forbidden, it is generally a bad idea to include
+// non-finite values (infinities or NaNs) in the population of values, as this
+// will render the `mean` field meaningless.
+message DistributionAggregation {
+  // The number of values in the population. Must be non-negative.
+  int64 count = 1;
+
+  // The arithmetic mean of the values in the population. If `count` is zero
+  // then this field must be zero.
+  double mean = 2;
+
+  // The sum of the values in the population.  If `count` is zero then this
+  // field must be zero.
+  double sum = 3;
+
+  // Describes a range of population values.
+  message Range {
+    // The minimum of the population values.
+    double min = 1;
+    // The maximum of the population values.
+    double max = 2;
+  }
+
+  // The range of the population values. If `count` is zero, this field will not
+  // be defined.
+  Range range = 4;
+
+  // A Distribution may optionally contain a histogram of the values in the
+  // population. The histogram is given in `bucket_count` as counts of values
+  // that fall into one of a sequence of non-overlapping buckets, as described
+  // by `DistributionAggregationDescriptor.bucket_boundaries`. The sum of the
+  // values in `bucket_counts` must equal the value in `count`.
+  //
+  // Bucket counts are given in order under the numbering scheme described
+  // above (the underflow bucket has number 0; the finite buckets, if any,
+  // have numbers 1 through N-2; the overflow bucket has number N-1).
+  //
+  // The size of `bucket_count` must be no greater than N as defined in
+  // `bucket_boundaries`.
+  //
+  // Any suffix of trailing zero bucket_count fields may be omitted.
+  repeated int64 bucket_counts = 5;
+
+  // Tags associated with this DistributionAggregation. These will be filled
+  // in based on the View specification.
+  repeated Tag tags = 6;
+}
+
+message DistributionAggregationDescriptor {
+  // A Distribution may optionally contain a histogram of the values in the
+  // population. The bucket boundaries for that histogram are described by
+  // `bucket_bounds`. This defines `size(bucket_bounds) + 1` (= N)
+  // buckets. The boundaries for bucket index i are:
+  //
+  // [-infinity, bucket_bounds[i]) for i == 0
+  // [bucket_bounds[i-1], bucket_bounds[i]) for 0 < i < N-2
+  // [bucket_bounds[i-1], +infinity) for i == N-1
+  //
+  // i.e. an underflow bucket (number 0), zero or more finite buckets (1
+  // through N - 2, and an overflow bucket (N - 1), with inclusive lower
+  // bounds and exclusive upper bounds.
+  //
+  // If `bucket_bounds` has no elements (zero size), then there is no
+  // histogram associated with the Distribution. If `bucket_bounds` has only
+  // one element, there are no finite buckets, and that single element is the
+  // common boundary of the overflow and underflow buckets. The values must
+  // be monotonically increasing.
+  repeated double bucket_bounds = 1;
+}
+
+// An IntervalAggreation records summary stats over various time
+// windows. These stats are approximate, with the degree of accuracy
+// controlled by setting the n_sub_intervals parameter in the
+// IntervalAggregationDescriptor.
+message IntervalAggregation {
+  // Summary statistic over a single time interval.
+  message Interval {
+    // The interval duration. Must be positive.
+    Duration interval_size = 1;
+    // Approximate number of measurements recorded in this interval.
+    double count = 2;
+    // The cumulative sum of measurements in this interval.
+    double sum = 3;
+  }
+
+  // Full set of intervals for this aggregation.
+  repeated Interval intervals = 1;
+
+  // Tags associated with this IntervalAggregation. These will be filled in
+  // based on the View specification.
+  repeated Tag tags = 2;
+}
+
+// An IntervalAggreationDescriptor specifies time intervals for an
+// IntervalAggregation.
+message IntervalAggregationDescriptor {
+  // Number of internal sub-intervals to use when collecting stats for each
+  // interval. The max error in interval measurements will be approximately
+  // 1/n_sub_intervals (although in practice, this will only be approached in
+  // the presence of very large and bursty workload changes), and underlying
+  // memory usage will be roughly proportional to the value of this
+  // field. Must be in the range [2, 20]. A value of 5 will be used if this is
+  // unspecified.
+  int32 n_sub_intervals = 1;
+
+  // The size of each interval, as a time duration. Must have at least one
+  // element.
+  repeated Duration interval_sizes = 2;
+}
+
+// A Tag: key-value pair.
+message Tag {
+  string key = 1;
+  string value = 2;
+}
+
+// A ViewDescriptor specifies an AggregationDescriptor and a set of tag
+// keys. Views instantiated from this descriptor will contain Aggregations
+// broken down by the unique set of matching tag values for each measurement.
+message ViewDescriptor {
+  // Name of view. Must be unique.
+  string name = 1;
+
+  // More detailed description, for documentation purposes.
+  string description = 2;
+
+  // Name of a MeasurementDescriptor to be used for this view.
+  string measurement_descriptor_name = 3;
+
+  // Aggregation type to associate with View.
+  oneof aggregation {
+    IntervalAggregationDescriptor interval_aggregation = 4;
+    DistributionAggregationDescriptor distribution_aggregation = 5;
+  }
+
+  // Tag keys to match with a given measurement. If no keys are specified,
+  // then all stats are recorded. Keys must be unique.
+  repeated string tag_keys = 6;
+}
+
+// DistributionView contains all aggregations for a view specified using a
+// DistributionAggregationDescriptor.
+message DistributionView {
+  // Aggregations - each will have a unique set of tag values for the tag_keys
+  // associated with the corresponding View.
+  repeated DistributionAggregation aggregations = 1;
+
+  // Start and end timestamps over which aggregations was accumulated.
+  Timestamp start = 2;
+  Timestamp end = 3;
+}
+
+// IntervalView contains all aggregations for a view specified using a
+// IntervalAggregationDescriptor.
+message IntervalView {
+  // Aggregations - each will have a unique set of tag values for the tag_keys
+  // associated with the corresponding View.
+  repeated IntervalAggregation aggregations = 1;
+}
+
+// A View contains the aggregations based on a ViewDescriptor.
+message View {
+  // ViewDescriptor name associated with this set of View.
+  string view_name = 1;
+
+  oneof view {
+    DistributionView distribution_view = 2;
+    IntervalView interval_view = 3;
+  }
+}
diff --git a/tools/grpcz/grpcz_client.cc b/tools/grpcz/grpcz_client.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a5e66f7b542e33e05bdb767ef15b1438f01b1b0c
--- /dev/null
+++ b/tools/grpcz/grpcz_client.cc
@@ -0,0 +1,185 @@
+/*
+ *
+ * Copyright 2017, 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 <string>
+
+#include <google/protobuf/util/json_util.h>
+#include <grpc++/grpc++.h>
+#include <grpc/support/log.h>
+
+#include "gflags/gflags.h"
+/* #include "mongoose.h" */
+
+// TODO (makdharma): remove local copies of these protos
+#include "tools/grpcz/census.grpc.pb.h"
+#include "tools/grpcz/monitoring.grpc.pb.h"
+
+DEFINE_string(
+    grpcz_server, "127.0.0.1:8080",
+    "Unix domain socket path (e.g. unix://tmp/grpcz.sock) or IP address"
+    "(host:port) where grpcz server is running.");
+DEFINE_string(http_port, "8000",
+              "Port id for accessing the HTTP server that renders /grpcz page");
+DEFINE_bool(print_to_console, false,
+            "print the JSON retreived from grpcz server and quit");
+
+using grpc::Channel;
+using grpc::ClientContext;
+using grpc::Status;
+
+using ::grpc::instrumentation::v1alpha::CanonicalRpcStats;
+using ::grpc::instrumentation::v1alpha::Monitoring;
+
+static const std::string static_html_header =
+    "<!DOCTYPE html> <html> <head> <style> \
+table { border-collapse: collapse; width: 100%; } \
+table, td, th { border: 1px solid black; } \
+</style> </head> <body>\
+<div id='stats' data-stats='";
+
+static const std::string static_html_footer =
+    "' class='hidden'></div>\
+<h1>GRPCZ Statistics</h1> <div id='table'> </div> \
+<script> \
+  var canonical_stats = JSON.parse(\
+            document.getElementById('stats').getAttribute('data-stats')); \
+  var table = document.createElement('table'); \
+  if (canonical_stats['Error Message'] != undefined) { \
+     document.getElementById('table').innerHTML = canonical_stats['Error Message']; } \
+  else {\
+  for (var key in canonical_stats) { \
+    name = canonical_stats[key]['view']['viewName']; \
+    distribution = canonical_stats[key]['view']['distributionView']; \
+    interval = canonical_stats[key]['view']['intervalView']; \
+    value = (interval == undefined) ? \
+      JSON.stringify(distribution, null, ' ') : \
+      JSON.stringify(interval, null, ' '); \
+    var row = table.insertRow(-1); \
+    var col1 = row.insertCell(0); \
+    var col2 = row.insertCell(1); \
+    col1.innerHTML = name; \
+    col2.innerHTML = '<pre>' + value + '</pre>'; \
+  } \
+  document.getElementById('table').appendChild(table); \
+  }\
+</script> </body> </html>";
+
+class GrpczClient {
+ public:
+  GrpczClient(std::shared_ptr<Channel> channel)
+      : stub_(Monitoring::NewStub(channel)) {}
+
+  std::string GetStatsAsJson() {
+    const ::google::protobuf::Empty request;
+    CanonicalRpcStats reply;
+    ClientContext context;
+    Status status = stub_->GetCanonicalRpcStats(&context, request, &reply);
+
+    if (status.ok()) {
+      std::string json_str;
+      ::google::protobuf::util::MessageToJsonString(reply, &json_str);
+      return json_str;
+    } else {
+      static const std::string error_message_json =
+          "{\"Error Message\":\"" + status.error_message() + "\"}";
+      gpr_log(GPR_DEBUG, "%d: %s", status.error_code(),
+              status.error_message().c_str());
+      return error_message_json;
+    }
+  }
+
+ private:
+  std::unique_ptr<Monitoring::Stub> stub_;
+};
+
+std::unique_ptr<GrpczClient> g_grpcz_client;
+/*
+static struct mg_serve_http_opts s_http_server_opts;
+
+static void ev_handler(struct mg_connection *nc, int ev, void *p) {
+  if (ev == MG_EV_HTTP_REQUEST) {
+    mg_serve_http(nc, (struct http_message *)p, s_http_server_opts);
+  }
+}
+
+static void grpcz_handler(struct mg_connection *nc, int ev, void *ev_data) {
+  (void)ev;
+  (void)ev_data;
+  gpr_log(GPR_INFO, "fetching grpcz stats from %s", FLAGS_grpcz_server.c_str());
+  std::string json_str = g_grpcz_client->GetStatsAsJson();
+  std::string rendered_html =
+      static_html_header + json_str + static_html_footer;
+  mg_printf(nc, "HTTP/1.0 200 OK\r\n\r\n%s", rendered_html.c_str());
+  nc->flags |= MG_F_SEND_AND_CLOSE;
+}
+*/
+
+int main(int argc, char **argv) {
+  gflags::ParseCommandLineFlags(&argc, &argv, true);
+
+  // Create a client
+  g_grpcz_client.reset(new GrpczClient(grpc::CreateChannel(
+      FLAGS_grpcz_server, grpc::InsecureChannelCredentials())));
+  if (FLAGS_print_to_console) {
+    // using GPR_ERROR since this is the default verbosity. _DEBUG or _INFO
+    // won't print unless GRPC_VERBOSITY env var is set appropriately, which
+    // might confuse users of this utility.
+    gpr_log(GPR_ERROR, "%s\n", g_grpcz_client->GetStatsAsJson().c_str());
+    return 0;
+  }
+
+  /*
+  // Set up a mongoose webserver handler
+  struct mg_mgr mgr;
+  mg_mgr_init(&mgr, NULL);
+  gpr_log(GPR_INFO, "Starting grpcz web server on port %s\n",
+          FLAGS_http_port.c_str());
+
+  struct mg_connection *nc = mg_bind(&mgr, FLAGS_http_port.c_str(), ev_handler);
+  if (nc == NULL) {
+    gpr_log(GPR_ERROR, "Failed to create listener on port %s\n",
+            FLAGS_http_port.c_str());
+    return -1;
+  }
+  mg_register_http_endpoint(nc, "/grpcz", grpcz_handler);
+  mg_set_protocol_http_websocket(nc);
+
+  // Poll in a loop and serve /grpcz pages
+  for (;;) {
+    static const int k_sleep_millis = 100;
+    mg_mgr_poll(&mgr, k_sleep_millis);
+  }
+  mg_mgr_free(&mgr);
+  */
+  return 0;
+}
diff --git a/tools/grpcz/monitoring.proto b/tools/grpcz/monitoring.proto
new file mode 100644
index 0000000000000000000000000000000000000000..fefcd7d22f17138b4aafb50a31a9592c70c9ed4e
--- /dev/null
+++ b/tools/grpcz/monitoring.proto
@@ -0,0 +1,156 @@
+// Copyright 2017, 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 file defines an interface for exporting monitoring information
+// out of gRPC servers.
+syntax = "proto3";
+
+// TODO(ericgribkoff) Figure out how to manage the external Census proto
+// dependency.
+import "tools/grpcz/census.proto";
+import "google/protobuf/any.proto";
+import "google/protobuf/empty.proto";
+
+package grpc.instrumentation.v1alpha;
+
+option java_multiple_files = true;
+option java_package = "io.grpc.instrumentation.v1alpha";
+option java_outer_classname = "MonitoringProto";
+
+service Monitoring {
+  // Return canonical RPC stats
+  rpc GetCanonicalRpcStats(google.protobuf.Empty) returns (CanonicalRpcStats) {
+  }
+
+  // Query the server for specific stats
+  rpc GetStats(StatsRequest) returns (StatsResponse) {
+  }
+
+  // Request the server to stream back snapshots of the requested stats
+  rpc WatchStats(StatsRequest) returns (stream StatsResponse) {
+  }
+
+
+  // Return request traces.
+  rpc GetRequestTraces(TraceRequest) returns(TraceResponse) {
+  // TODO(aveitch): Please define the messages here
+  }
+
+  // Return application-defined groups of monitoring data.
+  // This is a low level facility to allow extension of the monitoring API to
+  // application-specific monitoring data. Frameworks may use this to define
+  // additional groups of monitoring data made available by servers.
+  rpc GetCustomMonitoringData(MonitoringDataGroup)
+    returns (CustomMonitoringData) {
+  }
+
+}
+
+// Canonical RPC stats exported by gRPC.
+message CanonicalRpcStats {
+  StatsResponse rpc_client_errors = 1;
+  StatsResponse rpc_client_completed_rpcs = 2;
+  StatsResponse rpc_client_started_rpcs = 3;
+  StatsResponse rpc_client_elapsed_time = 4;
+  StatsResponse rpc_client_server_elapsed_time = 5;
+  StatsResponse rpc_client_request_bytes = 6;
+  StatsResponse rpc_client_response_bytes = 7;
+  StatsResponse rpc_client_request_count = 8;
+  StatsResponse rpc_client_response_count = 9;
+  StatsResponse rpc_server_errors = 10;
+  StatsResponse rpc_server_completed_rpcs = 11;
+  StatsResponse rpc_server_server_elapsed_time = 12;
+  StatsResponse rpc_server_request_bytes = 13;
+  StatsResponse rpc_server_response_bytes = 14;
+  StatsResponse rpc_server_request_count = 15;
+  StatsResponse rpc_server_response_count = 16;
+  StatsResponse rpc_server_elapsed_time = 17;
+  //TODO(ericgribkoff) Add minute-hour interval stats.
+}
+
+// This message is sent when requesting a set of stats (Census Views) from
+// a client system, as part of the MonitoringService API's.
+message StatsRequest {
+  // An optional set of ViewDescriptor names. Only Views using these
+  // descriptors will be sent back in the response. If no names are provided,
+  // then all Views present in the client system will be included in every
+  // response. If measurement_names is also provided, then Views matching the
+  // intersection of the two are returned.
+  // TODO(aveitch): Consider making this a list of regexes or prefix matches in
+  // the future.
+  repeated string view_names = 1;
+
+  // An optional set of MeasurementDescriptor names. Only Views using these
+  // descriptors will be sent back in the response. If no names are provided,
+  // then all Views present in the client system will be included in every
+  // response. If view_names is also provided, then Views matching the
+  // intersection of the two are returned.
+  // TODO(aveitch): Consider making this a list of regexes or prefix matches in
+  // the future.
+  repeated string measurement_names = 2;
+
+  // By default, the MeasurementDescriptors and ViewDescriptors corresponding to
+  // the Views that are returned in a StatsResponse will be included in the
+  // first such response. Set this to true to have them not sent.
+  bool dont_include_descriptors_in_first_response = 3;
+}
+
+// This message contains all information relevant to a single View. It is the
+// return type for GetStats and WatchStats, and used in CanonicalRpcStats.
+message StatsResponse {
+  // A StatsResponse can optionally contain the MeasurementDescriptor and
+  // ViewDescriptor for the View. These will be sent in the first WatchStats
+  // response, or all GetStats and GetCanonicalRpcStats responses. These will
+  // not be set for {Get,Watch}Stats if
+  // dont_include_descriptors_in_first_response is set to true in the
+  // StatsRequest.
+  google.instrumentation.MeasurementDescriptor measurement_descriptor = 1;
+  google.instrumentation.ViewDescriptor view_descriptor = 2;
+
+  // The View data.
+  google.instrumentation.View view = 3;
+}
+
+message TraceRequest {
+  // TODO(aveitch): Complete definition of this type
+}
+
+message TraceResponse {
+  // TODO(aveitch): Complete definition of this type
+}
+
+message MonitoringDataGroup {
+  string name = 1;  // name of a group of monitoring data
+}
+
+// The wrapper for custom monitoring data.
+message CustomMonitoringData {
+  // can be any application specific monitoring data
+  google.protobuf.Any contents = 1;
+}
diff --git a/tools/http2_interop/http2interop_test.go b/tools/http2_interop/http2interop_test.go
index 305125f0c1127138c17d32226add4170b834c296..fb314da1964a099a4d9c855339439148d3e3db69 100644
--- a/tools/http2_interop/http2interop_test.go
+++ b/tools/http2_interop/http2interop_test.go
@@ -49,7 +49,7 @@ func InteropCtx(t *testing.T) *HTTP2InteropCtx {
 
 	if ctx.UseTestCa {
 		// It would be odd if useTestCa was true, but not useTls.  meh
-		certData, err := ioutil.ReadFile("src/core/lib/tsi/test_creds/ca.pem")
+		certData, err := ioutil.ReadFile("src/core/tsi/test_creds/ca.pem")
 		if err != nil {
 			t.Fatal(err)
 		}
diff --git a/tools/internal_ci/README.md b/tools/internal_ci/README.md
index 8bed6ca782b453c0e008603479ecb4a43a8fad49..e80e342dcd31fd051a25e63638a320e7c7efc9bf 100644
--- a/tools/internal_ci/README.md
+++ b/tools/internal_ci/README.md
@@ -1,4 +1,4 @@
-#Internal continuous integration
+# Internal continuous integration
 
 gRPC's externally facing testing is managed by Jenkins CI (see `tools/jenkins`
 directory). Nevertheless, some of the tests are better suited for being run
diff --git a/tools/internal_ci/linux/grpc_fuzzer_client.cfg b/tools/internal_ci/linux/grpc_fuzzer_client.cfg
deleted file mode 100644
index 1e8f6885763a130103e247b74c830a8e64fdc049..0000000000000000000000000000000000000000
--- a/tools/internal_ci/linux/grpc_fuzzer_client.cfg
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2017, 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.
-
-# Config file for the internal CI (in protobuf text format)
-
-# Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/linux/grpc_fuzzer_client.sh"
-timeout_mins: 1440  # 24 hours is the maximum allowed value
-action {
-  define_artifacts {
-    regex: "git/grpc/fuzzer_output/**"
-  }
-}
diff --git a/tools/internal_ci/linux/grpc_fuzzer_hpack_parser.cfg b/tools/internal_ci/linux/grpc_fuzzer_hpack_parser.cfg
deleted file mode 100644
index 72482b62e359b111f07c44f1dead39ce0fb95fa4..0000000000000000000000000000000000000000
--- a/tools/internal_ci/linux/grpc_fuzzer_hpack_parser.cfg
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2017, 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.
-
-# Config file for the internal CI (in protobuf text format)
-
-# Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/linux/grpc_fuzzer_hpack_parser.sh"
-timeout_mins: 1440  # 24 hours is the maximum allowed value
-action {
-  define_artifacts {
-    regex: "git/grpc/fuzzer_output/**"
-  }
-}
diff --git a/tools/internal_ci/linux/grpc_fuzzer_http_request.cfg b/tools/internal_ci/linux/grpc_fuzzer_http_request.cfg
deleted file mode 100644
index a4a0e8922e7dd6fcf139e72fd0cab65909c5ae39..0000000000000000000000000000000000000000
--- a/tools/internal_ci/linux/grpc_fuzzer_http_request.cfg
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2017, 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.
-
-# Config file for the internal CI (in protobuf text format)
-
-# Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/linux/grpc_fuzzer_http_request.sh"
-timeout_mins: 1440  # 24 hours is the maximum allowed value
-action {
-  define_artifacts {
-    regex: "git/grpc/fuzzer_output/**"
-  }
-}
diff --git a/tools/internal_ci/linux/grpc_fuzzer_nanopb_response.cfg b/tools/internal_ci/linux/grpc_fuzzer_nanopb_response.cfg
deleted file mode 100644
index cbf44ba29e7aaf7c4aea65fb1c08407c48302b32..0000000000000000000000000000000000000000
--- a/tools/internal_ci/linux/grpc_fuzzer_nanopb_response.cfg
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2017, 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.
-
-# Config file for the internal CI (in protobuf text format)
-
-# Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/linux/grpc_fuzzer_nanopb_response.sh"
-timeout_mins: 1440  # 24 hours is the maximum allowed value
-action {
-  define_artifacts {
-    regex: "git/grpc/fuzzer_output/**"
-  }
-}
diff --git a/tools/internal_ci/linux/grpc_fuzzer_server.sh b/tools/internal_ci/linux/grpc_fuzzer_server.sh
deleted file mode 100755
index 82b24b0f20d733c028443d4544f1a6815e225394..0000000000000000000000000000000000000000
--- a/tools/internal_ci/linux/grpc_fuzzer_server.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/bash
-# Copyright 2017, 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
-
-# change to grpc repo root
-cd $(dirname $0)/../../..
-
-git submodule update --init
-
-# download fuzzer docker image from dockerhub
-export DOCKERHUB_ORGANIZATION=grpctesting
-# runtime 23 * 60 mins
-config=asan-trace-cmp runtime=82800 tools/jenkins/run_fuzzer.sh server_fuzzer
diff --git a/tools/internal_ci/linux/grpc_interop_badserver_java.sh b/tools/internal_ci/linux/grpc_interop_badserver_java.sh
index 0985e657c63e92f363d6ae1ec62b176700265c9a..c309c623e0b7968c329334c23c9019a27d7f30b4 100755
--- a/tools/internal_ci/linux/grpc_interop_badserver_java.sh
+++ b/tools/internal_ci/linux/grpc_interop_badserver_java.sh
@@ -37,5 +37,5 @@ cd $(dirname $0)/../../..
 
 git submodule update --init
 
-tools/run_tests/run_interop_tests.py -l java --use_docker --http2_badserver_interop $@
+tools/run_tests/run_interop_tests.py -l java --use_docker --http2_server_interop $@
 
diff --git a/tools/internal_ci/linux/grpc_interop_badserver_python.sh b/tools/internal_ci/linux/grpc_interop_badserver_python.sh
index 3fff537d2b73e27e469de3f014c6982e3f3097f7..c3bb92f33da34a3a5c8aadb6ba50bbf4faeabdb7 100755
--- a/tools/internal_ci/linux/grpc_interop_badserver_python.sh
+++ b/tools/internal_ci/linux/grpc_interop_badserver_python.sh
@@ -37,5 +37,5 @@ cd $(dirname $0)/../../..
 
 git submodule update --init
 
-tools/run_tests/run_interop_tests.py -l python --use_docker --http2_badserver_interop $@
+tools/run_tests/run_interop_tests.py -l python --use_docker --http2_server_interop $@
 
diff --git a/tools/internal_ci/linux/grpc_master.cfg b/tools/internal_ci/linux/grpc_master.cfg
index 7536a91a679e69159aa6423416c1f99a8015faf4..6c94c3b4d8fb1aa23ec29f0e74c684e698838e88 100644
--- a/tools/internal_ci/linux/grpc_master.cfg
+++ b/tools/internal_ci/linux/grpc_master.cfg
@@ -34,6 +34,6 @@ build_file: "grpc/tools/internal_ci/linux/grpc_master.sh"
 timeout_mins: 240
 action {
   define_artifacts {
-    regex: "**/sponge_log.xml"
+    regex: "**/*sponge_log.xml"
   }
 }
diff --git a/tools/internal_ci/linux/grpc_master.sh b/tools/internal_ci/linux/grpc_master.sh
index d01d6375e9a7fff8d8c571dcf252b5935cef2526..bd22dd069c21857f971a1117b9df4d4202277b11 100755
--- a/tools/internal_ci/linux/grpc_master.sh
+++ b/tools/internal_ci/linux/grpc_master.sh
@@ -41,16 +41,10 @@ clang --version || true
 docker --version || true
 
 # Need to increase open files limit for c tests
-ulimit -n 2000
+ulimit -n 32768
 
 git submodule update --init
 
-tools/run_tests/run_tests.py -l c -t -x sponge_log.xml || FAILED="true"
-
-# kill port_server.py to prevent the build from hanging
-ps aux | grep port_server\\.py | awk '{print $2}' | xargs kill -9
-
-if [ "$FAILED" != "" ]
-then
-  exit 1
-fi
+# download docker images from dockerhub
+export DOCKERHUB_ORGANIZATION=grpctesting
+tools/run_tests/run_tests_matrix.py -f basictests linux --inner_jobs 16 -j 1 --internal_ci
diff --git a/tools/internal_ci/linux/grpc_fuzzer_uri.cfg b/tools/internal_ci/linux/grpc_portability.cfg
similarity index 91%
rename from tools/internal_ci/linux/grpc_fuzzer_uri.cfg
rename to tools/internal_ci/linux/grpc_portability.cfg
index 134b3d06d613540cd2b03221b8171dc1c2aa39d2..92efda80ff6a6e028dd22183289bee567a8e8e4c 100644
--- a/tools/internal_ci/linux/grpc_fuzzer_uri.cfg
+++ b/tools/internal_ci/linux/grpc_portability.cfg
@@ -30,10 +30,10 @@
 # Config file for the internal CI (in protobuf text format)
 
 # Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/linux/grpc_fuzzer_uri.sh"
-timeout_mins: 1440  # 24 hours is the maximum allowed value
+build_file: "grpc/tools/internal_ci/linux/grpc_portability.sh"
+timeout_mins: 1440
 action {
   define_artifacts {
-    regex: "git/grpc/fuzzer_output/**"
+    regex: "**/*sponge_log.xml"
   }
 }
diff --git a/tools/internal_ci/linux/grpc_fuzzer_json.sh b/tools/internal_ci/linux/grpc_portability.sh
similarity index 92%
rename from tools/internal_ci/linux/grpc_fuzzer_json.sh
rename to tools/internal_ci/linux/grpc_portability.sh
index 1e64a026b689b211b55ab5a958fbd4f37d4f04f0..6c55ed71cbbee3cb1b7983c998fe2afb54b6aa14 100755
--- a/tools/internal_ci/linux/grpc_fuzzer_json.sh
+++ b/tools/internal_ci/linux/grpc_portability.sh
@@ -35,7 +35,6 @@ cd $(dirname $0)/../../..
 
 git submodule update --init
 
-# download fuzzer docker image from dockerhub
+# download docker images from dockerhub
 export DOCKERHUB_ORGANIZATION=grpctesting
-config=asan-trace-cmp tools/jenkins/run_fuzzer.sh json_fuzzer_test
-
+tools/run_tests/run_tests_matrix.py -f portability linux --inner_jobs 16 -j 1 --internal_ci
diff --git a/tools/internal_ci/linux/grpc_portability_build_only.cfg b/tools/internal_ci/linux/grpc_portability_build_only.cfg
index ce5be5abe97d6dd06c2473bc482384121505b521..4d3dda4082234f9540e7fee0112e4a0567bcf71d 100644
--- a/tools/internal_ci/linux/grpc_portability_build_only.cfg
+++ b/tools/internal_ci/linux/grpc_portability_build_only.cfg
@@ -34,6 +34,6 @@ build_file: "grpc/tools/internal_ci/linux/grpc_portability_build_only.sh"
 timeout_mins: 180
 action {
   define_artifacts {
-    regex: "**report**.xml"
+    regex: "**/*sponge_log.xml"
   }
 }
diff --git a/tools/internal_ci/linux/grpc_portability_build_only.sh b/tools/internal_ci/linux/grpc_portability_build_only.sh
old mode 100644
new mode 100755
index ebdc0e82d767f5bbc71b3e496b0e63c39413665c..787f0302c088726ce0374256f5a34031e4bb9a75
--- a/tools/internal_ci/linux/grpc_portability_build_only.sh
+++ b/tools/internal_ci/linux/grpc_portability_build_only.sh
@@ -37,5 +37,4 @@ git submodule update --init
 
 # download docker images from dockerhub
 export DOCKERHUB_ORGANIZATION=grpctesting
-
-tools/jenkins/run_jenkins_matrix.sh -f portability linux --build_only
+tools/run_tests/run_tests_matrix.py -f portability linux --internal_ci --build_only
diff --git a/tools/internal_ci/linux/grpc_pull_request_sanity.cfg b/tools/internal_ci/linux/grpc_pull_request_sanity.cfg
index 511f2d6b35b3106048772c88e914a43c7bc100af..1abf6ac600b337385900b8591c62703779670bf3 100644
--- a/tools/internal_ci/linux/grpc_pull_request_sanity.cfg
+++ b/tools/internal_ci/linux/grpc_pull_request_sanity.cfg
@@ -34,6 +34,6 @@ build_file: "grpc/tools/internal_ci/linux/grpc_sanity.sh"
 timeout_mins: 30
 action {
   define_artifacts {
-    regex: "**/sponge_log.xml"
+    regex: "**/*sponge_log.xml"
   }
 }
diff --git a/tools/internal_ci/linux/grpc_fuzzer_api.cfg b/tools/internal_ci/linux/sanitizer/grpc_c_asan.cfg
similarity index 91%
rename from tools/internal_ci/linux/grpc_fuzzer_api.cfg
rename to tools/internal_ci/linux/sanitizer/grpc_c_asan.cfg
index 5c2592e933df5000493fa7d9592f6b44e944b37f..8f2be8b59c678e8e757af5e0ec290ab89799ea45 100644
--- a/tools/internal_ci/linux/grpc_fuzzer_api.cfg
+++ b/tools/internal_ci/linux/sanitizer/grpc_c_asan.cfg
@@ -30,10 +30,10 @@
 # Config file for the internal CI (in protobuf text format)
 
 # Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/linux/grpc_fuzzer_api.sh"
-timeout_mins: 1440  # 24 hours is the maximum allowed value
+build_file: "grpc/tools/internal_ci/linux/sanitizer/grpc_c_asan.sh"
+timeout_mins: 1440
 action {
   define_artifacts {
-    regex: "git/grpc/fuzzer_output/**"
+    regex: "**/*sponge_log.xml"
   }
 }
diff --git a/tools/internal_ci/linux/grpc_fuzzer_http_request.sh b/tools/internal_ci/linux/sanitizer/grpc_c_asan.sh
similarity index 91%
rename from tools/internal_ci/linux/grpc_fuzzer_http_request.sh
rename to tools/internal_ci/linux/sanitizer/grpc_c_asan.sh
index ef975d327a00e7ab66b84b5fa9ccf288036dc0d2..2927ad7de485c39e37bbec7f587b06b62a3bc224 100755
--- a/tools/internal_ci/linux/grpc_fuzzer_http_request.sh
+++ b/tools/internal_ci/linux/sanitizer/grpc_c_asan.sh
@@ -31,11 +31,10 @@
 set -ex
 
 # change to grpc repo root
-cd $(dirname $0)/../../..
+cd $(dirname $0)/../../../..
 
 git submodule update --init
 
-# download fuzzer docker image from dockerhub
+# download docker images from dockerhub
 export DOCKERHUB_ORGANIZATION=grpctesting
-config=asan-trace-cmp tools/jenkins/run_fuzzer.sh http_request_fuzzer_test
-
+tools/run_tests/run_tests_matrix.py -f c asan --inner_jobs 16 -j 1 --internal_ci
diff --git a/tools/internal_ci/linux/grpc_fuzzer_json.cfg b/tools/internal_ci/linux/sanitizer/grpc_c_msan.cfg
similarity index 91%
rename from tools/internal_ci/linux/grpc_fuzzer_json.cfg
rename to tools/internal_ci/linux/sanitizer/grpc_c_msan.cfg
index d22da2d7051c7fdbae8b2537ec08e1aaa6774c98..2fd19974843a742071590212ab6d796149e2e896 100644
--- a/tools/internal_ci/linux/grpc_fuzzer_json.cfg
+++ b/tools/internal_ci/linux/sanitizer/grpc_c_msan.cfg
@@ -30,10 +30,10 @@
 # Config file for the internal CI (in protobuf text format)
 
 # Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/linux/grpc_fuzzer_json.sh"
-timeout_mins: 1440  # 24 hours is the maximum allowed value
+build_file: "grpc/tools/internal_ci/linux/sanitizer/grpc_c_msan.sh"
+timeout_mins: 1440
 action {
   define_artifacts {
-    regex: "git/grpc/fuzzer_output/**"
+    regex: "**/*sponge_log.xml"
   }
 }
diff --git a/tools/internal_ci/linux/grpc_fuzzer_nanopb_response.sh b/tools/internal_ci/linux/sanitizer/grpc_c_msan.sh
similarity index 91%
rename from tools/internal_ci/linux/grpc_fuzzer_nanopb_response.sh
rename to tools/internal_ci/linux/sanitizer/grpc_c_msan.sh
index 6e7f4b7f291bb2ff4ba7db293d968f0af6e67a4e..3a3c850a9f2502ead0cab85c2ff1c405814cb4cb 100755
--- a/tools/internal_ci/linux/grpc_fuzzer_nanopb_response.sh
+++ b/tools/internal_ci/linux/sanitizer/grpc_c_msan.sh
@@ -31,10 +31,10 @@
 set -ex
 
 # change to grpc repo root
-cd $(dirname $0)/../../..
+cd $(dirname $0)/../../../..
 
 git submodule update --init
 
-# download fuzzer docker image from dockerhub
+# download docker images from dockerhub
 export DOCKERHUB_ORGANIZATION=grpctesting
-config=asan-trace-cmp tools/jenkins/run_fuzzer.sh nanopb_fuzzer_response_test
+tools/run_tests/run_tests_matrix.py -f c msan --inner_jobs 16 -j 1 --internal_ci
diff --git a/tools/internal_ci/linux/grpc_fuzzer_server.cfg b/tools/internal_ci/linux/sanitizer/grpc_c_tsan.cfg
similarity index 91%
rename from tools/internal_ci/linux/grpc_fuzzer_server.cfg
rename to tools/internal_ci/linux/sanitizer/grpc_c_tsan.cfg
index 7877d5179265f57a10c7301e1b98f4119ae3092a..1ba01211b9f3432774312a3544cb378913b3c24c 100644
--- a/tools/internal_ci/linux/grpc_fuzzer_server.cfg
+++ b/tools/internal_ci/linux/sanitizer/grpc_c_tsan.cfg
@@ -30,10 +30,10 @@
 # Config file for the internal CI (in protobuf text format)
 
 # Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/linux/grpc_fuzzer_server.sh"
-timeout_mins: 1440  # 24 hours is the maximum allowed value
+build_file: "grpc/tools/internal_ci/linux/sanitizer/grpc_c_tsan.sh"
+timeout_mins: 1440
 action {
   define_artifacts {
-    regex: "git/grpc/fuzzer_output/**"
+    regex: "**/*sponge_log.xml"
   }
 }
diff --git a/tools/internal_ci/linux/grpc_fuzzer_hpack_parser.sh b/tools/internal_ci/linux/sanitizer/grpc_c_tsan.sh
similarity index 91%
rename from tools/internal_ci/linux/grpc_fuzzer_hpack_parser.sh
rename to tools/internal_ci/linux/sanitizer/grpc_c_tsan.sh
index 43933e6d82e1ba461ab920fb2fed051ed33ea1e9..daebf34521e98f6e8d221df27ee2bef3a665276f 100755
--- a/tools/internal_ci/linux/grpc_fuzzer_hpack_parser.sh
+++ b/tools/internal_ci/linux/sanitizer/grpc_c_tsan.sh
@@ -31,11 +31,10 @@
 set -ex
 
 # change to grpc repo root
-cd $(dirname $0)/../../..
+cd $(dirname $0)/../../../..
 
 git submodule update --init
 
-# download fuzzer docker image from dockerhub
+# download docker images from dockerhub
 export DOCKERHUB_ORGANIZATION=grpctesting
-config=asan-trace-cmp tools/jenkins/run_fuzzer.sh hpack_parser_fuzzer_test
-
+tools/run_tests/run_tests_matrix.py -f c tsan --inner_jobs 16 -j 1 --internal_ci
diff --git a/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.cfg b/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..49b7f123195266700641bb20153d2a7f06182eca
--- /dev/null
+++ b/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.cfg
@@ -0,0 +1,39 @@
+# Copyright 2017, 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.
+
+# Config file for the internal CI (in protobuf text format)
+
+# Location of the continuous shell script in repository.
+build_file: "grpc/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.sh"
+timeout_mins: 1440
+action {
+  define_artifacts {
+    regex: "**/*sponge_log.xml"
+  }
+}
diff --git a/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.sh b/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.sh
new file mode 100755
index 0000000000000000000000000000000000000000..29f7fda74b1b489de705c0ba2ca26c23800f3e6d
--- /dev/null
+++ b/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# Copyright 2017, 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
+
+# change to grpc repo root
+cd $(dirname $0)/../../../..
+
+git submodule update --init
+
+# download docker images from dockerhub
+export DOCKERHUB_ORGANIZATION=grpctesting
+tools/run_tests/run_tests_matrix.py -f c++ asan --inner_jobs 16 -j 1 --internal_ci
diff --git a/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.cfg b/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..97c818b557165927063c2b685783f662b85759ae
--- /dev/null
+++ b/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.cfg
@@ -0,0 +1,39 @@
+# Copyright 2017, 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.
+
+# Config file for the internal CI (in protobuf text format)
+
+# Location of the continuous shell script in repository.
+build_file: "grpc/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.sh"
+timeout_mins: 1440
+action {
+  define_artifacts {
+    regex: "**/*sponge_log.xml"
+  }
+}
diff --git a/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.sh b/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4b9291a4a00ac8cf5bc14bdbe1fe11122f503a7c
--- /dev/null
+++ b/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# Copyright 2017, 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
+
+# change to grpc repo root
+cd $(dirname $0)/../../../..
+
+git submodule update --init
+
+# download docker images from dockerhub
+export DOCKERHUB_ORGANIZATION=grpctesting
+tools/run_tests/run_tests_matrix.py -f c++ tsan --inner_jobs 16 -j 1 --internal_ci
diff --git a/tools/internal_ci/macos/grpc_master.cfg b/tools/internal_ci/macos/grpc_master.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..039c99ec42ab1990b388aab641f33398640f5021
--- /dev/null
+++ b/tools/internal_ci/macos/grpc_master.cfg
@@ -0,0 +1,39 @@
+# Copyright 2017, 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.
+
+# Config file for the internal CI (in protobuf text format)
+
+# Location of the continuous shell script in repository.
+build_file: "grpc/tools/internal_ci/macos/grpc_master.sh"
+timeout_mins: 240
+action {
+  define_artifacts {
+    regex: "**/*sponge_log.xml"
+  }
+}
diff --git a/tools/internal_ci/linux/grpc_fuzzer_api.sh b/tools/internal_ci/macos/grpc_master.sh
similarity index 86%
rename from tools/internal_ci/linux/grpc_fuzzer_api.sh
rename to tools/internal_ci/macos/grpc_master.sh
index edf884338fc0ca7a1256f8ca4392e0bead623996..4ce1af73a54d5a64f081b55c2dd4df92f5970076 100755
--- a/tools/internal_ci/linux/grpc_fuzzer_api.sh
+++ b/tools/internal_ci/macos/grpc_master.sh
@@ -35,7 +35,12 @@ cd $(dirname $0)/../../..
 
 git submodule update --init
 
-# download fuzzer docker image from dockerhub
-export DOCKERHUB_ORGANIZATION=grpctesting
-# runtime 23 * 60 mins
-config=asan-trace-cmp runtime=82800 tools/jenkins/run_fuzzer.sh api_fuzzer
+tools/run_tests/run_tests_matrix.py -f basictests macos --internal_ci || FAILED="true"
+
+# kill port_server.py to prevent the build from hanging
+ps aux | grep port_server\\.py | awk '{print $2}' | xargs kill -9
+
+if [ "$FAILED" != "" ]
+then
+  exit 1
+fi
diff --git a/tools/internal_ci/windows/grpc_master.bat b/tools/internal_ci/windows/grpc_master.bat
index 8943390a8de0cbebd8e360698d4eed7f876d54aa..b6f3c8790f549cc3e35d0c7cf61a7140c518379a 100644
--- a/tools/internal_ci/windows/grpc_master.bat
+++ b/tools/internal_ci/windows/grpc_master.bat
@@ -36,7 +36,7 @@ cd /d %~dp0\..\..\..
 
 git submodule update --init
 
-python tools/run_tests/run_tests_matrix.py -f basictests windows -j 1 --inner_jobs 8 || goto :error
+python tools/run_tests/run_tests_matrix.py -f basictests windows -j 1 --inner_jobs 8 --internal_ci || goto :error
 goto :EOF
 
 :error
diff --git a/tools/internal_ci/windows/grpc_master.cfg b/tools/internal_ci/windows/grpc_master.cfg
index f90af113085b6ee72505bbc7181d442b8beb5401..21a9d6a985de3bb27ea539217981d1d3c9a8caff 100644
--- a/tools/internal_ci/windows/grpc_master.cfg
+++ b/tools/internal_ci/windows/grpc_master.cfg
@@ -34,6 +34,6 @@ build_file: "grpc/tools/internal_ci/windows/grpc_master.bat"
 timeout_mins: 360
 action {
   define_artifacts {
-    regex: "**sponge_log.xml"
+    regex: "**/*sponge_log.xml"
   }
 }
diff --git a/tools/internal_ci/windows/grpc_portability_master.bat b/tools/internal_ci/windows/grpc_portability_master.bat
new file mode 100644
index 0000000000000000000000000000000000000000..789808664bbd76d4ec744fc2969ab3e1959f2b99
--- /dev/null
+++ b/tools/internal_ci/windows/grpc_portability_master.bat
@@ -0,0 +1,43 @@
+@rem Copyright 2017, 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 make sure msys binaries are preferred over cygwin binaries
+@rem set path to python 2.7
+set PATH=C:\tools\msys64\usr\bin;C:\Python27;%PATH%
+
+@rem enter repo root
+cd /d %~dp0\..\..\..
+
+git submodule update --init
+
+python tools/run_tests/run_tests_matrix.py -f portability windows -j 1 --inner_jobs 8 --internal_ci || goto :error
+goto :EOF
+
+:error
+exit /b %errorlevel%
diff --git a/tools/internal_ci/windows/grpc_portability_master.cfg b/tools/internal_ci/windows/grpc_portability_master.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..10d8e9859108dbe83eec54371a90b07176324c36
--- /dev/null
+++ b/tools/internal_ci/windows/grpc_portability_master.cfg
@@ -0,0 +1,39 @@
+# Copyright 2017, 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.
+
+# Config file for the internal CI (in protobuf text format)
+
+# Location of the continuous shell script in repository.
+build_file: "grpc/tools/internal_ci/windows/grpc_portability_master.bat"
+timeout_mins: 360
+action {
+  define_artifacts {
+    regex: "**/*sponge_log.xml"
+  }
+}
diff --git a/tools/jenkins/run_bazel_basic_in_docker.sh b/tools/jenkins/run_bazel_basic_in_docker.sh
index b1d498a07d35ffa3623be7d15a95a50ff388bb20..5013f80b1df95f752eae759eb6c3be2ce48a648d 100755
--- a/tools/jenkins/run_bazel_basic_in_docker.sh
+++ b/tools/jenkins/run_bazel_basic_in_docker.sh
@@ -39,4 +39,4 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc
 && git submodule update --init --reference /var/local/jenkins/grpc/${name} \
 ${name}')
 cd /var/local/git/grpc
-bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... examples/cpp/...
+bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... examples/...
diff --git a/tools/jenkins/run_c_cpp_test.sh b/tools/jenkins/run_c_cpp_test.sh
new file mode 100755
index 0000000000000000000000000000000000000000..afa2e780f75836a069b6f0aef7d88e61a58307a3
--- /dev/null
+++ b/tools/jenkins/run_c_cpp_test.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+# Copyright 2017, 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 script is invoked by a Jenkins pull request job and executes all
+# args passed to this script if the pull request affect C/C++ code
+set -ex
+
+# Enter the gRPC repo root
+cd $(dirname $0)/../..
+
+AFFECTS_C_CPP=`python -c 'import os; \
+               import sys; \
+               sys.path.insert(0, "tools/run_tests/python_utils"); \
+               import filter_pull_request_tests as filter; \
+               github_target_branch = os.environ.get("ghprbTargetBranch"); \
+               print(filter.affects_c_cpp("origin/%s" % github_target_branch))'`
+
+if [ $AFFECTS_C_CPP == "False" ] ; then
+  echo "This pull request does not affect C/C++. Tests do not need to be run."
+else
+  $@
+fi
diff --git a/tools/jenkins/run_full_performance_released.sh b/tools/jenkins/run_full_performance_released.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ae2289e32c9a9aa7fb6b402581f5ea0b1affc2cc
--- /dev/null
+++ b/tools/jenkins/run_full_performance_released.sh
@@ -0,0 +1,73 @@
+#!/usr/bin/env bash
+# Copyright 2017, 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.
+#
+# A frozen version of run_full_performance.sh that runs full performance test
+# suite for the latest released stable version of gRPC.
+set -ex
+
+# Enter the gRPC repo root
+cd $(dirname $0)/../..
+
+# run 8core client vs 8core server
+tools/run_tests/run_performance_tests.py \
+    -l c++ csharp node ruby java python go node_express \
+    --netperf \
+    --category scalable \
+    --bq_result_table performance_released.performance_experiment \
+    --remote_worker_host grpc-performance-server-8core grpc-performance-client-8core grpc-performance-client2-8core \
+    --xml_report report_8core.xml \
+    || EXIT_CODE=1
+
+# prevent pushing leftover build files to remote hosts in the next step.
+git clean -fdxq --exclude='report*.xml'
+
+# scalability with 32cores (and upload to a different BQ table)
+tools/run_tests/run_performance_tests.py \
+    -l c++ java csharp go \
+    --netperf \
+    --category scalable \
+    --bq_result_table performance_released.performance_experiment_32core \
+    --remote_worker_host grpc-performance-server-32core grpc-performance-client-32core grpc-performance-client2-32core \
+    --xml_report report_32core.xml \
+    || EXIT_CODE=1
+
+# prevent pushing leftover build files to remote hosts in the next step.
+git clean -fdxq --exclude='report*.xml'
+
+# selected scenarios on Windows
+tools/run_tests/run_performance_tests.py \
+    -l csharp \
+    --category scalable \
+    --bq_result_table performance_released.performance_experiment_windows \
+    --remote_worker_host grpc-performance-windows1 grpc-performance-windows2 \
+    --xml_report report_windows.xml \
+    || EXIT_CODE=1
+
+exit $EXIT_CODE
diff --git a/tools/jenkins/run_interop.sh b/tools/jenkins/run_interop.sh
index 2a9fc662a9efc6e4d568387bac5ac0f3d85f761a..13c208e97c95dfb06cc49b40ad21b5516da2333c 100755
--- a/tools/jenkins/run_interop.sh
+++ b/tools/jenkins/run_interop.sh
@@ -36,4 +36,4 @@ export LANG=en_US.UTF-8
 # Enter the gRPC repo root
 cd $(dirname $0)/../..
 
-tools/run_tests/run_interop_tests.py -l all -s all --cloud_to_prod --cloud_to_prod_auth --use_docker --http2_interop --http2_badserver_interop -t -j 12 $@ || true
+tools/run_tests/run_interop_tests.py -l all -s all --cloud_to_prod --cloud_to_prod_auth --use_docker --http2_interop --http2_server_interop -t -j 12 $@ || true
diff --git a/tools/jenkins/run_interop_objc.sh b/tools/jenkins/run_interop_objc.sh
new file mode 100755
index 0000000000000000000000000000000000000000..29f9ac989c76c64285d0f531c8c3d28c04e84e04
--- /dev/null
+++ b/tools/jenkins/run_interop_objc.sh
@@ -0,0 +1,39 @@
+#!/usr/bin/env bash
+# Copyright 2017, 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 script is invoked by Jenkins and runs interop test suite.
+set -ex
+
+export LANG=en_US.UTF-8
+
+# Enter the gRPC repo root
+cd $(dirname $0)/../..
+
+tools/run_tests/run_interop_tests.py -l objc -s all --use_docker -t -j 1 $@ || true
diff --git a/tools/jenkins/run_line_count.sh b/tools/jenkins/run_line_count.sh
new file mode 100755
index 0000000000000000000000000000000000000000..a2bde534130b88ad5687c44ec7165310649735b0
--- /dev/null
+++ b/tools/jenkins/run_line_count.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+# Copyright 2017, 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 script is invoked by Jenkins and counts the number of lines in the
+# project.
+set -ex
+
+cd $(dirname $0)/../..
+tools/line_count/collect-now.sh
diff --git a/tools/jenkins/run_performance.sh b/tools/jenkins/run_performance.sh
index 99b920f6a095ba772a20eb2ac430170d25a26131..f530fb46b86256a7935ce20cc3b62ca38059a351 100755
--- a/tools/jenkins/run_performance.sh
+++ b/tools/jenkins/run_performance.sh
@@ -31,7 +31,11 @@
 # This script is invoked by Jenkins and runs performance smoke test.
 set -ex
 
+# List of benchmarks that provide good signal for analyzing performance changes in pull requests
+BENCHMARKS_TO_RUN="bm_fullstack_unary_ping_pong bm_fullstack_streaming_ping_pong bm_fullstack_streaming_pump bm_closure bm_cq bm_call_create bm_error bm_chttp2_hpack bm_chttp2_transport bm_pollset bm_metadata"
+
 # Enter the gRPC repo root
 cd $(dirname $0)/../..
 
-tools/run_tests/run_performance_tests.py -l c++ node ruby csharp python --netperf --category smoketest
+tools/run_tests/start_port_server.py
+tools/profiling/microbenchmarks/bm_diff.py -d origin/$ghprbTargetBranch -b $BENCHMARKS_TO_RUN
diff --git a/tools/profiling/latency_profile/run_latency_profile.sh b/tools/jenkins/run_performance_profile_daily.sh
similarity index 93%
rename from tools/profiling/latency_profile/run_latency_profile.sh
rename to tools/jenkins/run_performance_profile_daily.sh
index e9baee09574aebdfb3392f5f66e6fe487a283b94..f239fad18866fa284ddd2ee1c664eeb381c92e42 100755
--- a/tools/profiling/latency_profile/run_latency_profile.sh
+++ b/tools/jenkins/run_performance_profile_daily.sh
@@ -30,9 +30,7 @@
 
 set -ex
 
-cd $(dirname $0)/../../..
-
-CPUS=`python -c 'import multiprocessing; print multiprocessing.cpu_count()'`
+cd $(dirname $0)/../..
 
 # try to use pypy for generating reports
 # each trace dumps 7-8gig of text to disk, and processing this into a report is
@@ -44,4 +42,4 @@ else
   PYTHON=python2.7
 fi
 
-$PYTHON tools/run_tests/run_microbenchmark.py --collect summary perf latency --bigquery_upload
+$PYTHON tools/run_tests/run_microbenchmark.py --collect summary perf latency
diff --git a/tools/jenkins/run_performance_profile_hourly.sh b/tools/jenkins/run_performance_profile_hourly.sh
new file mode 100755
index 0000000000000000000000000000000000000000..c352a9f4acf4cf209d6062d3b217657b81ccb33e
--- /dev/null
+++ b/tools/jenkins/run_performance_profile_hourly.sh
@@ -0,0 +1,43 @@
+#!/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 $(dirname $0)/../..
+
+./tools/run_tests/start_port_server.py || true
+
+CPUS=`python -c 'import multiprocessing; print multiprocessing.cpu_count()'`
+
+make CONFIG=opt memory_profile_test memory_profile_client memory_profile_server -j $CPUS
+bins/opt/memory_profile_test
+bq load microbenchmarks.memory memory_usage.csv
+
+tools/run_tests/run_microbenchmark.py --collect summary --bigquery_upload
diff --git a/tools/line_count/collect-history.py b/tools/line_count/collect-history.py
new file mode 100755
index 0000000000000000000000000000000000000000..4c1bf73b1e15843e12176d31eb5a6f0925332d6d
--- /dev/null
+++ b/tools/line_count/collect-history.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+# Copyright 2017, 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 subprocess
+import datetime
+
+# this script is only of historical interest: it's the script that was used to
+# bootstrap the dataset
+
+def daterange(start, end):
+  for n in range(int((end - start).days)):
+    yield start + datetime.timedelta(n)
+
+start_date = datetime.date(2017, 3, 26)
+end_date = datetime.date(2017, 3, 29)
+
+for dt in daterange(start_date, end_date):
+  dmy = dt.strftime('%Y-%m-%d')
+  sha1 = subprocess.check_output(['git', 'rev-list', '-n', '1',
+                                  '--before=%s' % dmy,
+                                  'master']).strip()
+  subprocess.check_call(['git', 'checkout', sha1])
+  subprocess.check_call(['git', 'submodule', 'update'])
+  subprocess.check_call(['git', 'clean', '-f', '-x', '-d'])
+  subprocess.check_call(['cloc', '--vcs=git', '--by-file', '--yaml', '--out=../count/%s.yaml' % dmy, '.'])
+
diff --git a/tools/run_tests/helper_scripts/build_csharp_coreclr.sh b/tools/line_count/collect-now.sh
similarity index 88%
rename from tools/run_tests/helper_scripts/build_csharp_coreclr.sh
rename to tools/line_count/collect-now.sh
index dd5fd31c759cd3317b16385b3e6190cf78f3e5e4..44f4b4ed3107160ed4abf57b68f593dabd0494c9 100755
--- a/tools/run_tests/helper_scripts/build_csharp_coreclr.sh
+++ b/tools/line_count/collect-now.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2015, Google Inc.
+# Copyright 2017, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -30,9 +30,7 @@
 
 set -ex
 
-cd $(dirname $0)/../../../src/csharp
+cloc --vcs=git --by-file --yaml --out=cloc.yaml .
+tools/line_count/yaml2csv.py -i cloc.yaml -d `date +%Y-%m-%d` -o cloc.csv
+bq load line_counts.grpc cloc.csv
 
-# TODO(jtattermusch): introduce caching
-dotnet restore .
-
-dotnet build --configuration $MSBUILD_CONFIG '**/project.json'
diff --git a/tools/line_count/summarize-history.py b/tools/line_count/summarize-history.py
new file mode 100755
index 0000000000000000000000000000000000000000..cb6d570f66543f8d3e960493ec8decaf2f0c327d
--- /dev/null
+++ b/tools/line_count/summarize-history.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+# Copyright 2017, 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 subprocess
+import datetime
+
+# this script is only of historical interest: it's the script that was used to
+# bootstrap the dataset
+
+def daterange(start, end):
+  for n in range(int((end - start).days)):
+    yield start + datetime.timedelta(n)
+
+start_date = datetime.date(2017, 3, 26)
+end_date = datetime.date(2017, 3, 29)
+
+for dt in daterange(start_date, end_date):
+  dmy = dt.strftime('%Y-%m-%d')
+  print dmy
+  subprocess.check_call(['tools/line_count/yaml2csv.py', '-i', '../count/%s.yaml' % dmy, '-d', dmy, '-o', '../count/%s.csv' % dmy])
+
diff --git a/tools/line_count/yaml2csv.py b/tools/line_count/yaml2csv.py
new file mode 100755
index 0000000000000000000000000000000000000000..9bda09fd087c5087a0810416a851ff90b9f574c9
--- /dev/null
+++ b/tools/line_count/yaml2csv.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+# Copyright 2017, 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 yaml
+import argparse
+import datetime
+import csv
+
+argp = argparse.ArgumentParser(description='Convert cloc yaml to bigquery csv')
+argp.add_argument('-i', '--input', type=str)
+argp.add_argument('-d', '--date', type=str, default=datetime.date.today().strftime('%Y-%m-%d'))
+argp.add_argument('-o', '--output', type=str, default='out.csv')
+args = argp.parse_args()
+
+data = yaml.load(open(args.input).read())
+with open(args.output, 'w') as outf:
+  writer = csv.DictWriter(outf, ['date', 'name', 'language', 'code', 'comment', 'blank'])
+  for key, value in data.iteritems():
+    if key == 'header': continue
+    if key == 'SUM': continue
+    if key.startswith('third_party/'): continue
+    row = {'name': key, 'date': args.date}
+    row.update(value)
+    writer.writerow(row)
+
diff --git a/tools/profiling/microbenchmarks/bm2bq.py b/tools/profiling/microbenchmarks/bm2bq.py
index 76ed0fef0db1c9852234ad67a188f41274d655db..99cf4a558cfd8d064b555a7a0cf3fb98a4f256a3 100755
--- a/tools/profiling/microbenchmarks/bm2bq.py
+++ b/tools/profiling/microbenchmarks/bm2bq.py
@@ -36,7 +36,7 @@
 import sys
 import json
 import csv
-import os
+import bm_json
 
 columns = [
   ('jenkins_build', 'integer'),
@@ -71,8 +71,17 @@ columns = [
   ('end_of_stream', 'boolean'),
   ('header_bytes_per_iteration', 'float'),
   ('framing_bytes_per_iteration', 'float'),
+  ('nows_per_iteration', 'float'),
 ]
 
+SANITIZE = {
+  'integer': int,
+  'float': float,
+  'boolean': bool,
+  'string': str,
+  'timestamp': str,
+}
+
 if sys.argv[1] == '--schema':
   print ',\n'.join('%s:%s' % (k, t.upper()) for k, t in columns)
   sys.exit(0)
@@ -88,143 +97,10 @@ else:
 
 writer = csv.DictWriter(sys.stdout, [c for c,t in columns])
 
-bm_specs = {
-  'BM_UnaryPingPong': {
-    'tpl': ['fixture', 'client_mutator', 'server_mutator'],
-    'dyn': ['request_size', 'response_size'],
-  },
-  'BM_PumpStreamClientToServer': {
-    'tpl': ['fixture'],
-    'dyn': ['request_size'],
-  },
-  'BM_PumpStreamServerToClient': {
-    'tpl': ['fixture'],
-    'dyn': ['request_size'],
-  },
-  'BM_StreamingPingPong': {
-    'tpl': ['fixture', 'client_mutator', 'server_mutator'],
-    'dyn': ['request_size', 'request_count'],
-  },
-  'BM_StreamingPingPongMsgs': {
-    'tpl': ['fixture', 'client_mutator', 'server_mutator'],
-    'dyn': ['request_size'],
-  },
-  'BM_PumpStreamServerToClient_Trickle': {
-    'tpl': [],
-    'dyn': ['request_size', 'bandwidth_kilobits'],
-  },
-  'BM_ErrorStringOnNewError': {
-    'tpl': ['fixture'],
-    'dyn': [],
-  },
-  'BM_ErrorStringRepeatedly': {
-    'tpl': ['fixture'],
-    'dyn': [],
-  },
-  'BM_ErrorGetStatus': {
-    'tpl': ['fixture'],
-    'dyn': [],
-  },
-  'BM_ErrorGetStatusCode': {
-    'tpl': ['fixture'],
-    'dyn': [],
-  },
-  'BM_ErrorHttpError': {
-    'tpl': ['fixture'],
-    'dyn': [],
-  },
-  'BM_HasClearGrpcStatus': {
-    'tpl': ['fixture'],
-    'dyn': [],
-  },
-  'BM_IsolatedFilter' : {
-    'tpl': ['fixture', 'client_mutator'],
-    'dyn': [],
-  },
-  'BM_HpackEncoderEncodeHeader' : {
-    'tpl': ['fixture'],
-    'dyn': ['end_of_stream', 'request_size'],
-  },
-  'BM_HpackParserParseHeader' : {
-    'tpl': ['fixture'],
-    'dyn': [],
-  },
-}
-
-def numericalize(s):
-  if not s: return ''
-  if s[-1] == 'k':
-    return int(s[:-1]) * 1024
-  if s[-1] == 'M':
-    return int(s[:-1]) * 1024 * 1024
-  if 0 <= (ord(s[-1]) - ord('0')) <= 9:
-    return int(s)
-  assert 'not a number: %s' % s
-
-def parse_name(name):
-  if '<' not in name and '/' not in name and name not in bm_specs:
-    return {'name': name}
-  rest = name
-  out = {}
-  tpl_args = []
-  dyn_args = []
-  if '<' in rest:
-    tpl_bit = rest[rest.find('<') + 1 : rest.rfind('>')]
-    arg = ''
-    nesting = 0
-    for c in tpl_bit:
-      if c == '<':
-        nesting += 1
-        arg += c
-      elif c == '>':
-        nesting -= 1
-        arg += c
-      elif c == ',':
-        if nesting == 0:
-          tpl_args.append(arg.strip())
-          arg = ''
-        else:
-          arg += c
-      else:
-        arg += c
-    tpl_args.append(arg.strip())
-    rest = rest[:rest.find('<')] + rest[rest.rfind('>') + 1:]
-  if '/' in rest:
-    s = rest.split('/')
-    rest = s[0]
-    dyn_args = s[1:]
-  name = rest
-  assert name in bm_specs, 'bm_specs needs to be expanded for %s' % name
-  assert len(dyn_args) == len(bm_specs[name]['dyn'])
-  assert len(tpl_args) == len(bm_specs[name]['tpl'])
-  out['name'] = name
-  out.update(dict((k, numericalize(v)) for k, v in zip(bm_specs[name]['dyn'], dyn_args)))
-  out.update(dict(zip(bm_specs[name]['tpl'], tpl_args)))
-  return out
-
-for bm in js['benchmarks']:
-  context = js['context']
-  if 'label' in bm:
-    labels_list = [s.split(':') for s in bm['label'].strip().split(' ') if len(s) and s[0] != '#']
-    for el in labels_list:
-      el[0] = el[0].replace('/iter', '_per_iteration')
-    labels = dict(labels_list)
-  else:
-    labels = {}
-  row = {
-    'jenkins_build': os.environ.get('BUILD_NUMBER', ''),
-    'jenkins_job': os.environ.get('JOB_NAME', ''),
-  }
-  row.update(context)
-  row.update(bm)
-  row.update(parse_name(row['name']))
-  row.update(labels)
-  if 'label' in row:
-    del row['label']
-  if js2:
-    for bm2 in js2['benchmarks']:
-      if bm['name'] == bm2['name']:
-        row['cpu_time'] = bm2['cpu_time']
-        row['real_time'] = bm2['real_time']
-        row['iterations'] = bm2['iterations']
-  writer.writerow(row)
+for row in bm_json.expand_json(js, js2):
+  sane_row = {}
+  for name, sql_type in columns:
+    if name in row:
+      if row[name] == '': continue
+      sane_row[name] = SANITIZE[sql_type](row[name])
+  writer.writerow(sane_row)
diff --git a/tools/profiling/microbenchmarks/bm_diff.py b/tools/profiling/microbenchmarks/bm_diff.py
new file mode 100755
index 0000000000000000000000000000000000000000..b2d6f460475f44634b1f2b47893dc3cff0d8710c
--- /dev/null
+++ b/tools/profiling/microbenchmarks/bm_diff.py
@@ -0,0 +1,255 @@
+#!/usr/bin/env python2.7
+# Copyright 2017, 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 json
+import bm_json
+import tabulate
+import argparse
+from scipy import stats
+import subprocess
+import multiprocessing
+import collections
+import pipes
+import os
+sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), '..', '..', 'run_tests', 'python_utils'))
+import comment_on_pr
+import jobset
+import itertools
+import speedup
+import random
+import shutil
+import errno
+
+_INTERESTING = (
+  'cpu_time',
+  'real_time',
+  'locks_per_iteration',
+  'allocs_per_iteration',
+  'writes_per_iteration',
+  'atm_cas_per_iteration',
+  'atm_add_per_iteration',
+  'nows_per_iteration',
+)
+
+def changed_ratio(n, o):
+  if float(o) <= .0001: o = 0
+  if float(n) <= .0001: n = 0
+  if o == 0 and n == 0: return 0
+  if o == 0: return 100
+  return (float(n)-float(o))/float(o)
+
+def median(ary):
+  ary = sorted(ary)
+  n = len(ary)
+  if n%2 == 0:
+    return (ary[n/2] + ary[n/2+1]) / 2.0
+  else:
+    return ary[n/2]
+
+def min_change(pct):
+  return lambda n, o: abs(changed_ratio(n,o)) > pct/100.0
+
+_AVAILABLE_BENCHMARK_TESTS = ['bm_fullstack_unary_ping_pong',
+                              'bm_fullstack_streaming_ping_pong',
+                              'bm_fullstack_streaming_pump',
+                              'bm_closure',
+                              'bm_cq',
+                              'bm_call_create',
+                              'bm_error',
+                              'bm_chttp2_hpack',
+                              'bm_chttp2_transport',
+                              'bm_pollset',
+                              'bm_metadata',
+                              'bm_fullstack_trickle']
+
+argp = argparse.ArgumentParser(description='Perform diff on microbenchmarks')
+argp.add_argument('-t', '--track',
+                  choices=sorted(_INTERESTING),
+                  nargs='+',
+                  default=sorted(_INTERESTING),
+                  help='Which metrics to track')
+argp.add_argument('-b', '--benchmarks', nargs='+', choices=_AVAILABLE_BENCHMARK_TESTS, default=['bm_cq'])
+argp.add_argument('-d', '--diff_base', type=str)
+argp.add_argument('-r', '--repetitions', type=int, default=1)
+argp.add_argument('-l', '--loops', type=int, default=20)
+argp.add_argument('-j', '--jobs', type=int, default=multiprocessing.cpu_count())
+args = argp.parse_args()
+
+assert args.diff_base
+
+def avg(lst):
+  sum = 0.0
+  n = 0.0
+  for el in lst:
+    sum += el
+    n += 1
+  return sum / n
+
+def make_cmd(cfg):
+  return ['make'] + args.benchmarks + [
+      'CONFIG=%s' % cfg, '-j', '%d' % args.jobs]
+
+def build(dest):
+  shutil.rmtree('bm_diff_%s' % dest, ignore_errors=True)
+  subprocess.check_call(['git', 'submodule', 'update'])
+  try:
+    subprocess.check_call(make_cmd('opt'))
+    subprocess.check_call(make_cmd('counters'))
+  except subprocess.CalledProcessError, e:
+    subprocess.check_call(['make', 'clean'])
+    subprocess.check_call(make_cmd('opt'))
+    subprocess.check_call(make_cmd('counters'))
+  os.rename('bins', 'bm_diff_%s' % dest)
+
+def collect1(bm, cfg, ver, idx):
+  cmd = ['bm_diff_%s/%s/%s' % (ver, cfg, bm),
+         '--benchmark_out=%s.%s.%s.%d.json' % (bm, cfg, ver, idx),
+         '--benchmark_out_format=json',
+         '--benchmark_repetitions=%d' % (args.repetitions)
+         ]
+  return jobset.JobSpec(cmd, shortname='%s %s %s %d/%d' % (bm, cfg, ver, idx+1, args.loops),
+                             verbose_success=True, timeout_seconds=None)
+
+build('new')
+
+where_am_i = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip()
+subprocess.check_call(['git', 'checkout', args.diff_base])
+try:
+  build('old')
+finally:
+  subprocess.check_call(['git', 'checkout', where_am_i])
+  subprocess.check_call(['git', 'submodule', 'update'])
+
+jobs = []
+for loop in range(0, args.loops):
+  jobs.extend(x for x in itertools.chain(
+    (collect1(bm, 'opt', 'new', loop) for bm in args.benchmarks),
+    (collect1(bm, 'counters', 'new', loop) for bm in args.benchmarks),
+    (collect1(bm, 'opt', 'old', loop) for bm in args.benchmarks),
+    (collect1(bm, 'counters', 'old', loop) for bm in args.benchmarks),
+  ))
+random.shuffle(jobs, random.SystemRandom().random)
+
+jobset.run(jobs, maxjobs=args.jobs)
+
+class Benchmark:
+
+  def __init__(self):
+    self.samples = {
+      True: collections.defaultdict(list),
+      False: collections.defaultdict(list)
+    }
+    self.final = {}
+
+  def add_sample(self, data, new):
+    for f in args.track:
+      if f in data:
+        self.samples[new][f].append(float(data[f]))
+
+  def process(self):
+    for f in sorted(args.track):
+      new = self.samples[True][f]
+      old = self.samples[False][f]
+      if not new or not old: continue
+      mdn_diff = abs(median(new) - median(old))
+      print '%s: new=%r old=%r mdn_diff=%r' % (f, new, old, mdn_diff)
+      s = speedup.speedup(new, old)
+      if abs(s) > 3 and mdn_diff > 0.5:
+        self.final[f] = '%+d%%' % s
+    return self.final.keys()
+
+  def skip(self):
+    return not self.final
+
+  def row(self, flds):
+    return [self.final[f] if f in self.final else '' for f in flds]
+
+
+def eintr_be_gone(fn):
+  """Run fn until it doesn't stop because of EINTR"""
+  while True:
+    try:
+      return fn()
+    except IOError, e:
+      if e.errno != errno.EINTR:
+        raise
+
+
+def read_json(filename):
+  try:
+    with open(filename) as f: return json.loads(f.read())
+  except ValueError, e:
+    return None
+
+
+def finalize():
+  benchmarks = collections.defaultdict(Benchmark)
+
+  for bm in args.benchmarks:
+    for loop in range(0, args.loops):
+      js_new_ctr = read_json('%s.counters.new.%d.json' % (bm, loop))
+      js_new_opt = read_json('%s.opt.new.%d.json' % (bm, loop))
+      js_old_ctr = read_json('%s.counters.old.%d.json' % (bm, loop))
+      js_old_opt = read_json('%s.opt.old.%d.json' % (bm, loop))
+
+      if js_new_ctr:
+        for row in bm_json.expand_json(js_new_ctr, js_new_opt):
+          print row
+          name = row['cpp_name']
+          if name.endswith('_mean') or name.endswith('_stddev'): continue
+          benchmarks[name].add_sample(row, True)
+      if js_old_ctr:
+        for row in bm_json.expand_json(js_old_ctr, js_old_opt):
+          print row
+          name = row['cpp_name']
+          if name.endswith('_mean') or name.endswith('_stddev'): continue
+          benchmarks[name].add_sample(row, False)
+
+  really_interesting = set()
+  for name, bm in benchmarks.items():
+    print name
+    really_interesting.update(bm.process())
+  fields = [f for f in args.track if f in really_interesting]
+
+  headers = ['Benchmark'] + fields
+  rows = []
+  for name in sorted(benchmarks.keys()):
+    if benchmarks[name].skip(): continue
+    rows.append([name] + benchmarks[name].row(fields))
+  if rows:
+    text = 'Performance differences noted:\n' + tabulate.tabulate(rows, headers=headers, floatfmt='+.2f')
+  else:
+    text = 'No significant performance differences'
+  print text
+  comment_on_pr.comment_on_pr('```\n%s\n```' % text)
+
+
+eintr_be_gone(finalize)
diff --git a/tools/profiling/microbenchmarks/bm_json.py b/tools/profiling/microbenchmarks/bm_json.py
new file mode 100644
index 0000000000000000000000000000000000000000..917269823d077269a568783b3fc878f000169500
--- /dev/null
+++ b/tools/profiling/microbenchmarks/bm_json.py
@@ -0,0 +1,207 @@
+# Copyright 2017, 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 os
+
+_BM_SPECS = {
+  'BM_UnaryPingPong': {
+    'tpl': ['fixture', 'client_mutator', 'server_mutator'],
+    'dyn': ['request_size', 'response_size'],
+  },
+  'BM_PumpStreamClientToServer': {
+    'tpl': ['fixture'],
+    'dyn': ['request_size'],
+  },
+  'BM_PumpStreamServerToClient': {
+    'tpl': ['fixture'],
+    'dyn': ['request_size'],
+  },
+  'BM_StreamingPingPong': {
+    'tpl': ['fixture', 'client_mutator', 'server_mutator'],
+    'dyn': ['request_size', 'request_count'],
+  },
+  'BM_StreamingPingPongMsgs': {
+    'tpl': ['fixture', 'client_mutator', 'server_mutator'],
+    'dyn': ['request_size'],
+  },
+  'BM_PumpStreamServerToClient_Trickle': {
+    'tpl': [],
+    'dyn': ['request_size', 'bandwidth_kilobits'],
+  },
+  'BM_ErrorStringOnNewError': {
+    'tpl': ['fixture'],
+    'dyn': [],
+  },
+  'BM_ErrorStringRepeatedly': {
+    'tpl': ['fixture'],
+    'dyn': [],
+  },
+  'BM_ErrorGetStatus': {
+    'tpl': ['fixture'],
+    'dyn': [],
+  },
+  'BM_ErrorGetStatusCode': {
+    'tpl': ['fixture'],
+    'dyn': [],
+  },
+  'BM_ErrorHttpError': {
+    'tpl': ['fixture'],
+    'dyn': [],
+  },
+  'BM_HasClearGrpcStatus': {
+    'tpl': ['fixture'],
+    'dyn': [],
+  },
+  'BM_IsolatedFilter': {
+    'tpl': ['fixture', 'client_mutator'],
+    'dyn': [],
+  },
+  'BM_HpackEncoderEncodeHeader': {
+    'tpl': ['fixture'],
+    'dyn': ['end_of_stream', 'request_size'],
+  },
+  'BM_HpackParserParseHeader': {
+    'tpl': ['fixture'],
+    'dyn': [],
+  },
+  'BM_CallCreateDestroy': {
+    'tpl': ['fixture'],
+    'dyn': [],
+  },
+  'BM_Zalloc': {
+    'tpl': [],
+    'dyn': ['request_size'],
+  },
+  'BM_PollEmptyPollset_SpeedOfLight': {
+    'tpl': [],
+    'dyn': ['request_size', 'request_count'],
+  },
+  'BM_StreamCreateSendInitialMetadataDestroy': {
+    'tpl': ['fixture'],
+    'dyn': [],
+  },
+  'BM_TransportStreamSend': {
+    'tpl': [],
+    'dyn': ['request_size'],
+  },
+  'BM_TransportStreamRecv': {
+    'tpl': [],
+    'dyn': ['request_size'],
+  },
+  'BM_StreamingPingPongWithCoalescingApi': {
+    'tpl': ['fixture', 'client_mutator', 'server_mutator'],
+    'dyn': ['request_size', 'request_count', 'end_of_stream'],
+  },
+  'BM_Base16SomeStuff': {
+    'tpl': [],
+    'dyn': ['request_size'],
+  }
+}
+
+def numericalize(s):
+  if not s: return ''
+  if s[-1] == 'k':
+    return float(s[:-1]) * 1024
+  if s[-1] == 'M':
+    return float(s[:-1]) * 1024 * 1024
+  if 0 <= (ord(s[-1]) - ord('0')) <= 9:
+    return float(s)
+  assert 'not a number: %s' % s
+
+def parse_name(name):
+  cpp_name = name
+  if '<' not in name and '/' not in name and name not in _BM_SPECS:
+    return {'name': name, 'cpp_name': name}
+  rest = name
+  out = {}
+  tpl_args = []
+  dyn_args = []
+  if '<' in rest:
+    tpl_bit = rest[rest.find('<') + 1 : rest.rfind('>')]
+    arg = ''
+    nesting = 0
+    for c in tpl_bit:
+      if c == '<':
+        nesting += 1
+        arg += c
+      elif c == '>':
+        nesting -= 1
+        arg += c
+      elif c == ',':
+        if nesting == 0:
+          tpl_args.append(arg.strip())
+          arg = ''
+        else:
+          arg += c
+      else:
+        arg += c
+    tpl_args.append(arg.strip())
+    rest = rest[:rest.find('<')] + rest[rest.rfind('>') + 1:]
+  if '/' in rest:
+    s = rest.split('/')
+    rest = s[0]
+    dyn_args = s[1:]
+  name = rest
+  assert name in _BM_SPECS, '_BM_SPECS needs to be expanded for %s' % name
+  assert len(dyn_args) == len(_BM_SPECS[name]['dyn'])
+  assert len(tpl_args) == len(_BM_SPECS[name]['tpl'])
+  out['name'] = name
+  out['cpp_name'] = cpp_name
+  out.update(dict((k, numericalize(v)) for k, v in zip(_BM_SPECS[name]['dyn'], dyn_args)))
+  out.update(dict(zip(_BM_SPECS[name]['tpl'], tpl_args)))
+  return out
+
+def expand_json(js, js2 = None):
+  for bm in js['benchmarks']:
+    if bm['name'].endswith('_stddev') or bm['name'].endswith('_mean'): continue
+    context = js['context']
+    if 'label' in bm:
+      labels_list = [s.split(':') for s in bm['label'].strip().split(' ') if len(s) and s[0] != '#']
+      for el in labels_list:
+        el[0] = el[0].replace('/iter', '_per_iteration')
+      labels = dict(labels_list)
+    else:
+      labels = {}
+    row = {
+      'jenkins_build': os.environ.get('BUILD_NUMBER', ''),
+      'jenkins_job': os.environ.get('JOB_NAME', ''),
+    }
+    row.update(context)
+    row.update(bm)
+    row.update(parse_name(row['name']))
+    row.update(labels)
+    if js2:
+      for bm2 in js2['benchmarks']:
+        if bm['name'] == bm2['name'] and 'already_used' not in bm2:
+          row['cpu_time'] = bm2['cpu_time']
+          row['real_time'] = bm2['real_time']
+          row['iterations'] = bm2['iterations']
+          bm2['already_used'] = True
+          break
+    yield row
diff --git a/tools/profiling/microbenchmarks/speedup.py b/tools/profiling/microbenchmarks/speedup.py
new file mode 100644
index 0000000000000000000000000000000000000000..8af0066c9df56b9dfc441a1e4b4117631b55bd62
--- /dev/null
+++ b/tools/profiling/microbenchmarks/speedup.py
@@ -0,0 +1,67 @@
+# Copyright 2017, 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 scipy import stats
+import math
+
+_THRESHOLD = 1e-10
+
+def scale(a, mul):
+  return [x*mul for x in a]
+
+def cmp(a, b):
+  return stats.ttest_ind(a, b)
+
+def speedup(new, old):
+  s0, p0 = cmp(new, old)
+  if math.isnan(p0): return 0
+  if s0 == 0: return 0
+  if p0 > _THRESHOLD: return 0
+  if s0 < 0:
+    pct = 1
+    while pct < 101:
+      sp, pp = cmp(new, scale(old, 1 - pct/100.0))
+      if sp > 0: break
+      if pp > _THRESHOLD: break
+      pct += 1
+    return -(pct - 1)
+  else:
+    pct = 1
+    while pct < 100000:
+      sp, pp = cmp(new, scale(old, 1 + pct/100.0))
+      if sp < 0: break
+      if pp > _THRESHOLD: break
+      pct += 1
+    return pct - 1
+
+if __name__ == "__main__":
+  new=[66034560.0, 126765693.0, 99074674.0, 98588433.0, 96731372.0, 110179725.0, 103802110.0, 101139800.0, 102357205.0, 99016353.0, 98840824.0, 99585632.0, 98791720.0, 96171521.0, 95327098.0, 95629704.0, 98209772.0, 99779411.0, 100182488.0, 98354192.0, 99644781.0, 98546709.0, 99019176.0, 99543014.0, 99077269.0, 98046601.0, 99319039.0, 98542572.0, 98886614.0, 72560968.0]
+  old=[60423464.0, 71249570.0, 73213089.0, 73200055.0, 72911768.0, 72347798.0, 72494672.0, 72756976.0, 72116565.0, 71541342.0, 73442538.0, 74817383.0, 73007780.0, 72499062.0, 72404945.0, 71843504.0, 73245405.0, 72778304.0, 74004519.0, 73694464.0, 72919931.0, 72955481.0, 71583857.0, 71350467.0, 71836817.0, 70064115.0, 70355345.0, 72516202.0, 71716777.0, 71532266.0]
+  print speedup(new, old)
+  print speedup(old, new)
diff --git a/tools/run_tests/README.md b/tools/run_tests/README.md
index d5bd9e7bb9d0c3c05f82720d44bbf8102017ed14..60f20747cd0ead5c3c9e811b888080b0e4119654 100644
--- a/tools/run_tests/README.md
+++ b/tools/run_tests/README.md
@@ -1,44 +1,44 @@
-#Overview
+# Overview
 
 This directory contains scripts that facilitate building and running tests. We are using python scripts as entrypoint for our
 tests because that gives us the opportunity to run tests using the same commandline regardless of the platform you are using.
 
-#Unit tests (run_tests.py)
+# Unit tests (run_tests.py)
 
 Builds gRPC in given language and runs unit tests. Use `tools/run_tests/run_tests.py --help` for more help.
 
-######Example
+###### Example
 `tools/run_tests/run_tests.py -l csharp -c dbg`
 
-######Useful options (among many others)
+###### Useful options (among many others)
 - `--use_docker` Builds a docker container containing all the prerequisites for given language and runs the tests under that container.
 - `--build_only` Only build, do not run the tests.
 
-#Interop tests (run_interop_tests.py)
+# Interop tests (run_interop_tests.py)
 
 Runs tests for cross-platform/cross-language interoperability. For more details, see [Interop tests descriptions](/doc/interop-test-descriptions.md)
 The script is also capable of running interop tests for grpc-java and grpc-go, using sources checked out alongside the ones of the grpc repository.
 
-######Example
+###### Example
 `tools/run_tests/run_interop_tests.py -l csharp -s c++ --use_docker` (run interop tests with C# client and C++ server)
 
 Note: if you see an error like `no space left on device` when running the
 interop tests using Docker, make sure that Docker is building the image files in
 a location with sufficient disk space.
 
-#Performance benchmarks (run_performance_tests.py)
+# Performance benchmarks (run_performance_tests.py)
 
 Runs predefined benchmark scenarios for given languages. Besides the simple configuration of running all the scenarios locally,
 the script also supports orchestrating test runs with client and server running on different machines and uploading the results
 to BigQuery.
 
-######Example
+###### Example
 `tools/run_tests/run_performance_tests.py -l c++ node`
 
-######Useful options
+###### Useful options
 - `--regex` use regex to select particular scenarios to run.
 
-#Stress tests (run_stress_tests.py)
+# Stress tests (run_stress_tests.py)
 
 Runs modified interop tests clients and servers under heavy load for an extended period of time to discover potential stability issues.
 The tests are internally using Kubernetes to run the client and server on GKE and upload statistics to BigQuery.
@@ -47,10 +47,10 @@ The tests are internally using Kubernetes to run the client and server on GKE an
 
 The directory `tools/run_tests/stress_test/configs/` contains the config files for several scenarios
 
-#Artifacts & Packages (task_runner.py)
+# Artifacts & Packages (task_runner.py)
 
 A generalized framework for running predefined tasks based on their labels. We use this to building binary artifacts & distrib packages and testing them)
 
-######Example
+###### Example
 `tools/run_tests/task_runner.py -f python artifact linux x64` (build tasks with labels `python`, `artifact`, `linux`, and `x64`)
 
diff --git a/tools/run_tests/artifacts/artifact_targets.py b/tools/run_tests/artifacts/artifact_targets.py
index e0658f4678d37018ab72bbd67c5b90191e41de4d..04702baccaeba3afe99b21d18c2146e8acf24388 100644
--- a/tools/run_tests/artifacts/artifact_targets.py
+++ b/tools/run_tests/artifacts/artifact_targets.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #
diff --git a/tools/run_tests/artifacts/build_artifact_node.bat b/tools/run_tests/artifacts/build_artifact_node.bat
index 0a2bc4b9d7dbcd399163cd02f74fc8d196ce02d0..bfd4461f7217f99a8221df9890d6f43d579f1b77 100644
--- a/tools/run_tests/artifacts/build_artifact_node.bat
+++ b/tools/run_tests/artifacts/build_artifact_node.bat
@@ -27,9 +27,9 @@
 @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 node_versions=1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0 7.0.0
+set node_versions=4.0.0 5.0.0 6.0.0 7.0.0
 
-set electron_versions=1.0.0 1.1.0 1.2.0 1.3.0 1.4.0
+set electron_versions=1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0
 
 set PATH=%PATH%;C:\Program Files\nodejs\;%APPDATA%\npm
 
diff --git a/tools/run_tests/artifacts/build_artifact_node.sh b/tools/run_tests/artifacts/build_artifact_node.sh
index 47b1f339fb8a9db026ff5d2a49cd6435ef744813..7a747551e88072bc789f12cbc6151c0cba67bfa0 100755
--- a/tools/run_tests/artifacts/build_artifact_node.sh
+++ b/tools/run_tests/artifacts/build_artifact_node.sh
@@ -42,13 +42,13 @@ mkdir -p artifacts
 
 npm update
 
-node_versions=( 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0 7.0.0 )
+node_versions=( 4.0.0 5.0.0 6.0.0 7.0.0 )
 
-electron_versions=( 1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 )
+electron_versions=( 1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0 )
 
 for version in ${node_versions[@]}
 do
-  ./node_modules/.bin/node-pre-gyp configure rebuild package testpackage --target=$version --target_arch=$NODE_TARGET_ARCH
+  ./node_modules/.bin/node-pre-gyp configure rebuild package testpackage --target=$version --target_arch=$NODE_TARGET_ARCH --grpc_alpine=true
   cp -r build/stage/* artifacts/
 done
 
diff --git a/tools/run_tests/artifacts/distribtest_targets.py b/tools/run_tests/artifacts/distribtest_targets.py
index a7535b385216bb0f4c98540826dedd38e2ebd4e0..097fd2d8b5ef82a78a9987f340981676dc0e5fee 100644
--- a/tools/run_tests/artifacts/distribtest_targets.py
+++ b/tools/run_tests/artifacts/distribtest_targets.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #
@@ -38,11 +38,14 @@ import python_utils.jobset as jobset
 
 
 def create_docker_jobspec(name, dockerfile_dir, shell_command, environ={},
-                   flake_retries=0, timeout_retries=0):
+                   flake_retries=0, timeout_retries=0,
+                   copy_rel_path=None):
   """Creates jobspec for a task running under docker."""
   environ = environ.copy()
   environ['RUN_COMMAND'] = shell_command
-  environ['RELATIVE_COPY_PATH'] = 'test/distrib'
+  # the entire repo will be cloned if copy_rel_path is not set.
+  if copy_rel_path:
+    environ['RELATIVE_COPY_PATH'] = copy_rel_path
 
   docker_args=[]
   for k,v in environ.items():
@@ -102,7 +105,8 @@ class CSharpDistribTest(object):
           'tools/dockerfile/distribtest/csharp_%s_%s' % (
               self.docker_suffix,
               self.arch),
-          'test/distrib/csharp/run_distrib_test%s.sh' % self.script_suffix)
+          'test/distrib/csharp/run_distrib_test%s.sh' % self.script_suffix,
+          copy_rel_path='test/distrib')
     elif self.platform == 'macos':
       return create_jobspec(self.name,
           ['test/distrib/csharp/run_distrib_test%s.sh' % self.script_suffix],
@@ -151,7 +155,8 @@ class NodeDistribTest(object):
                                        self.arch),
                                    '%s test/distrib/node/run_distrib_test.sh %s' % (
                                        linux32,
-                                       self.node_version))
+                                       self.node_version),
+                                   copy_rel_path='test/distrib')
     elif self.platform == 'macos':
       return create_jobspec(self.name,
                             ['test/distrib/node/run_distrib_test.sh',
@@ -185,7 +190,8 @@ class PythonDistribTest(object):
           'tools/dockerfile/distribtest/python_%s_%s' % (
               self.docker_suffix,
               self.arch),
-          'test/distrib/python/run_distrib_test.sh')
+          'test/distrib/python/run_distrib_test.sh',
+          copy_rel_path='test/distrib')
 
   def __str__(self):
     return self.name
@@ -212,7 +218,8 @@ class RubyDistribTest(object):
           'tools/dockerfile/distribtest/ruby_%s_%s' % (
               self.docker_suffix,
               self.arch),
-          'test/distrib/ruby/run_distrib_test.sh')
+          'test/distrib/ruby/run_distrib_test.sh',
+          copy_rel_path='test/distrib')
 
   def __str__(self):
     return self.name
@@ -237,7 +244,8 @@ class PHPDistribTest(object):
                                    'tools/dockerfile/distribtest/php_%s_%s' % (
                                        self.docker_suffix,
                                        self.arch),
-                                   'test/distrib/php/run_distrib_test.sh')
+                                   'test/distrib/php/run_distrib_test.sh',
+                                   copy_rel_path='test/distrib')
     elif self.platform == 'macos':
       return create_jobspec(self.name,
           ['test/distrib/php/run_distrib_test.sh'],
diff --git a/tools/run_tests/artifacts/package_targets.py b/tools/run_tests/artifacts/package_targets.py
index d490f571c37f684574dbbb30b13d903b160c0116..2547f2073cfa244f4e177c0534044e070e711510 100644
--- a/tools/run_tests/artifacts/package_targets.py
+++ b/tools/run_tests/artifacts/package_targets.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #
diff --git a/tools/run_tests/dockerize/build_interop_image.sh b/tools/run_tests/dockerize/build_interop_image.sh
index 48a216a124b194f40b180a8f6ee3c6552fae5f29..3385738f9c3a4353072560776666b8f28952191a 100755
--- a/tools/run_tests/dockerize/build_interop_image.sh
+++ b/tools/run_tests/dockerize/build_interop_image.sh
@@ -71,7 +71,13 @@ then
 fi
 
 # Use image name based on Dockerfile checksum
-BASE_IMAGE=${BASE_NAME}_base:`sha1sum tools/dockerfile/interoptest/$BASE_NAME/Dockerfile | cut -f1 -d\ `
+# on OSX use md5 instead of sha1sum
+if which sha1sum > /dev/null;
+then
+  BASE_IMAGE=${BASE_NAME}_base:`sha1sum tools/dockerfile/interoptest/$BASE_NAME/Dockerfile | cut -f1 -d\ `
+else
+  BASE_IMAGE=${BASE_NAME}_base:`md5 -r tools/dockerfile/interoptest/$BASE_NAME/Dockerfile | cut -f1 -d\ `
+fi
 
 # Make sure base docker image has been built. Should be instantaneous if so.
 docker build -t $BASE_IMAGE --force-rm=true tools/dockerfile/interoptest/$BASE_NAME || exit $?
diff --git a/tools/run_tests/generated/configs.json b/tools/run_tests/generated/configs.json
index 9173bd7c19c8e25348e7bbab911b89a909c2e465..abbe76d60c20e79ef819a3c5edcd09b971b97ff5 100644
--- a/tools/run_tests/generated/configs.json
+++ b/tools/run_tests/generated/configs.json
@@ -2,6 +2,26 @@
   {
     "config": "opt"
   }, 
+  {
+    "config": "asan-trace-cmp", 
+    "environ": {
+      "ASAN_OPTIONS": "detect_leaks=1:color=always", 
+      "LSAN_OPTIONS": "suppressions=tools/lsan_suppressions.txt:report_objects=1"
+    }
+  }, 
+  {
+    "config": "dbg"
+  }, 
+  {
+    "config": "asan", 
+    "environ": {
+      "ASAN_OPTIONS": "detect_leaks=1:color=always", 
+      "LSAN_OPTIONS": "suppressions=tools/lsan_suppressions.txt:report_objects=1"
+    }
+  }, 
+  {
+    "config": "msan"
+  }, 
   {
     "config": "basicprof"
   }, 
@@ -19,14 +39,19 @@
     }
   }, 
   {
-    "config": "asan-trace-cmp", 
+    "config": "c++-compat"
+  }, 
+  {
+    "config": "ubsan", 
     "environ": {
-      "ASAN_OPTIONS": "detect_leaks=1:color=always", 
-      "LSAN_OPTIONS": "suppressions=tools/lsan_suppressions.txt:report_objects=1"
+      "UBSAN_OPTIONS": "halt_on_error=1:print_stacktrace=1:suppressions=tools/ubsan_suppressions.txt"
     }
   }, 
   {
-    "config": "dbg"
+    "config": "tsan", 
+    "environ": {
+      "TSAN_OPTIONS": "suppressions=tools/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1"
+    }
   }, 
   {
     "config": "stapprof"
@@ -43,26 +68,7 @@
     ]
   }, 
   {
-    "config": "asan", 
-    "environ": {
-      "ASAN_OPTIONS": "detect_leaks=1:color=always", 
-      "LSAN_OPTIONS": "suppressions=tools/lsan_suppressions.txt:report_objects=1"
-    }
-  }, 
-  {
-    "config": "tsan", 
-    "environ": {
-      "TSAN_OPTIONS": "suppressions=tools/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1"
-    }
-  }, 
-  {
-    "config": "ubsan", 
-    "environ": {
-      "UBSAN_OPTIONS": "halt_on_error=1:print_stacktrace=1"
-    }
-  }, 
-  {
-    "config": "msan"
+    "config": "lto"
   }, 
   {
     "config": "mutrace"
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index ba48994c8e4495e84f645ef2a4380eed489bba4e..c9628234379134ca1bd3cf1401d4b8882247c16e 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -84,6 +84,21 @@
     "third_party": false, 
     "type": "target"
   }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c", 
+    "name": "arena_test", 
+    "src": [
+      "test/core/support/arena_test.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
   {
     "deps": [
       "gpr", 
@@ -421,6 +436,23 @@
     "third_party": false, 
     "type": "target"
   }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c", 
+    "name": "error_test", 
+    "src": [
+      "test/core/iomgr/error_test.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
   {
     "deps": [
       "gpr", 
@@ -438,6 +470,23 @@
     "third_party": false, 
     "type": "target"
   }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c", 
+    "name": "fake_resolver_test", 
+    "src": [
+      "test/core/client_channel/resolvers/fake_resolver_test.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
   {
     "deps": [
       "gpr", 
@@ -880,7 +929,7 @@
     "language": "c", 
     "name": "grpc_b64_test", 
     "src": [
-      "test/core/security/b64_test.c"
+      "test/core/slice/b64_test.c"
     ], 
     "third_party": false, 
     "type": "target"
@@ -1557,6 +1606,23 @@
     "third_party": false, 
     "type": "target"
   }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c", 
+    "name": "minimal_stack_is_minimal_test", 
+    "src": [
+      "test/core/channel/minimal_stack_is_minimal_test.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
   {
     "deps": [
       "gpr", 
@@ -1657,6 +1723,23 @@
     "third_party": false, 
     "type": "target"
   }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c", 
+    "name": "parse_address_test", 
+    "src": [
+      "test/core/client_channel/parse_address_test.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
   {
     "deps": [
       "gpr", 
@@ -1883,15 +1966,14 @@
       "gpr", 
       "gpr_test_util", 
       "grpc", 
-      "grpc_test_util", 
-      "test_tcp_server"
+      "grpc_test_util"
     ], 
     "headers": [], 
     "is_filegroup": false, 
     "language": "c", 
-    "name": "set_initial_connect_string_test", 
+    "name": "slice_buffer_test", 
     "src": [
-      "test/core/client_channel/set_initial_connect_string_test.c"
+      "test/core/slice/slice_buffer_test.c"
     ], 
     "third_party": false, 
     "type": "target"
@@ -1906,9 +1988,9 @@
     "headers": [], 
     "is_filegroup": false, 
     "language": "c", 
-    "name": "slice_buffer_test", 
+    "name": "slice_hash_table_test", 
     "src": [
-      "test/core/slice/slice_buffer_test.c"
+      "test/core/slice/slice_hash_table_test.c"
     ], 
     "third_party": false, 
     "type": "target"
@@ -2032,6 +2114,23 @@
     "third_party": false, 
     "type": "target"
   }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c", 
+    "name": "stream_owned_slice_test", 
+    "src": [
+      "test/core/transport/stream_owned_slice_test.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
   {
     "deps": [
       "gpr", 
@@ -2386,6 +2485,28 @@
       "grpc", 
       "grpc++", 
       "grpc++_test_util", 
+      "grpc_benchmark", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "bm_arena", 
+    "src": [
+      "test/cpp/microbenchmarks/bm_arena.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "benchmark", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_util", 
+      "grpc_benchmark", 
       "grpc_test_util"
     ], 
     "headers": [], 
@@ -2406,6 +2527,7 @@
       "grpc", 
       "grpc++", 
       "grpc++_test_util", 
+      "grpc_benchmark", 
       "grpc_test_util"
     ], 
     "headers": [], 
@@ -2426,6 +2548,28 @@
       "grpc", 
       "grpc++", 
       "grpc++_test_util", 
+      "grpc_benchmark", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "bm_chttp2_transport", 
+    "src": [
+      "test/cpp/microbenchmarks/bm_chttp2_transport.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "benchmark", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_util", 
+      "grpc_benchmark", 
       "grpc_test_util"
     ], 
     "headers": [], 
@@ -2446,6 +2590,7 @@
       "grpc", 
       "grpc++", 
       "grpc++_test_util", 
+      "grpc_benchmark", 
       "grpc_test_util"
     ], 
     "headers": [], 
@@ -2466,6 +2611,28 @@
       "grpc", 
       "grpc++", 
       "grpc++_test_util", 
+      "grpc_benchmark", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "bm_cq_multiple_threads", 
+    "src": [
+      "test/cpp/microbenchmarks/bm_cq_multiple_threads.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "benchmark", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_util", 
+      "grpc_benchmark", 
       "grpc_test_util"
     ], 
     "headers": [], 
@@ -2486,14 +2653,15 @@
       "grpc", 
       "grpc++", 
       "grpc++_test_util", 
+      "grpc_benchmark", 
       "grpc_test_util"
     ], 
     "headers": [], 
     "is_filegroup": false, 
     "language": "c++", 
-    "name": "bm_fullstack", 
+    "name": "bm_fullstack_streaming_ping_pong", 
     "src": [
-      "test/cpp/microbenchmarks/bm_fullstack.cc"
+      "test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -2504,6 +2672,72 @@
       "gpr", 
       "gpr_test_util", 
       "grpc", 
+      "grpc++", 
+      "grpc++_test_util", 
+      "grpc_benchmark", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "bm_fullstack_streaming_pump", 
+    "src": [
+      "test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "benchmark", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_util", 
+      "grpc_benchmark", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "bm_fullstack_trickle", 
+    "src": [
+      "test/cpp/microbenchmarks/bm_fullstack_trickle.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "benchmark", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_util", 
+      "grpc_benchmark", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "bm_fullstack_unary_ping_pong", 
+    "src": [
+      "test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "benchmark", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_util", 
+      "grpc_benchmark", 
       "grpc_test_util"
     ], 
     "headers": [], 
@@ -2516,6 +2750,27 @@
     "third_party": false, 
     "type": "target"
   }, 
+  {
+    "deps": [
+      "benchmark", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_util", 
+      "grpc_benchmark", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "bm_pollset", 
+    "src": [
+      "test/cpp/microbenchmarks/bm_pollset.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
   {
     "deps": [
       "gpr", 
@@ -2616,14 +2871,19 @@
     "headers": [
       "src/proto/grpc/testing/control.grpc.pb.h", 
       "src/proto/grpc/testing/control.pb.h", 
+      "src/proto/grpc/testing/control_mock.grpc.pb.h", 
       "src/proto/grpc/testing/messages.grpc.pb.h", 
       "src/proto/grpc/testing/messages.pb.h", 
+      "src/proto/grpc/testing/messages_mock.grpc.pb.h", 
       "src/proto/grpc/testing/payloads.grpc.pb.h", 
       "src/proto/grpc/testing/payloads.pb.h", 
+      "src/proto/grpc/testing/payloads_mock.grpc.pb.h", 
       "src/proto/grpc/testing/services.grpc.pb.h", 
       "src/proto/grpc/testing/services.pb.h", 
+      "src/proto/grpc/testing/services_mock.grpc.pb.h", 
       "src/proto/grpc/testing/stats.grpc.pb.h", 
-      "src/proto/grpc/testing/stats.pb.h"
+      "src/proto/grpc/testing/stats.pb.h", 
+      "src/proto/grpc/testing/stats_mock.grpc.pb.h"
     ], 
     "is_filegroup": false, 
     "language": "c++", 
@@ -2636,20 +2896,27 @@
   }, 
   {
     "deps": [
+      "gpr", 
+      "grpc", 
       "grpc++_codegen_base", 
       "grpc++_codegen_base_src"
     ], 
     "headers": [
       "src/proto/grpc/testing/control.grpc.pb.h", 
       "src/proto/grpc/testing/control.pb.h", 
+      "src/proto/grpc/testing/control_mock.grpc.pb.h", 
       "src/proto/grpc/testing/messages.grpc.pb.h", 
       "src/proto/grpc/testing/messages.pb.h", 
+      "src/proto/grpc/testing/messages_mock.grpc.pb.h", 
       "src/proto/grpc/testing/payloads.grpc.pb.h", 
       "src/proto/grpc/testing/payloads.pb.h", 
+      "src/proto/grpc/testing/payloads_mock.grpc.pb.h", 
       "src/proto/grpc/testing/services.grpc.pb.h", 
       "src/proto/grpc/testing/services.pb.h", 
+      "src/proto/grpc/testing/services_mock.grpc.pb.h", 
       "src/proto/grpc/testing/stats.grpc.pb.h", 
-      "src/proto/grpc/testing/stats.pb.h"
+      "src/proto/grpc/testing/stats.pb.h", 
+      "src/proto/grpc/testing/stats_mock.grpc.pb.h"
     ], 
     "is_filegroup": false, 
     "language": "c++", 
@@ -2763,6 +3030,25 @@
     "third_party": false, 
     "type": "target"
   }, 
+  {
+    "deps": [
+      "grpc++", 
+      "grpc++_error_details"
+    ], 
+    "headers": [
+      "src/proto/grpc/testing/echo_messages.grpc.pb.h", 
+      "src/proto/grpc/testing/echo_messages.pb.h", 
+      "src/proto/grpc/testing/echo_messages_mock.grpc.pb.h"
+    ], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "error_details_test", 
+    "src": [
+      "test/cpp/util/error_details_test.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
   {
     "deps": [
       "gpr", 
@@ -2809,7 +3095,8 @@
     ], 
     "headers": [
       "src/proto/grpc/testing/compiler_test.grpc.pb.h", 
-      "src/proto/grpc/testing/compiler_test.pb.h"
+      "src/proto/grpc/testing/compiler_test.pb.h", 
+      "src/proto/grpc/testing/compiler_test_mock.grpc.pb.h"
     ], 
     "is_filegroup": false, 
     "language": "c++", 
@@ -2954,7 +3241,9 @@
       "src/proto/grpc/testing/echo.grpc.pb.h", 
       "src/proto/grpc/testing/echo.pb.h", 
       "src/proto/grpc/testing/echo_messages.grpc.pb.h", 
-      "src/proto/grpc/testing/echo_messages.pb.h"
+      "src/proto/grpc/testing/echo_messages.pb.h", 
+      "src/proto/grpc/testing/echo_messages_mock.grpc.pb.h", 
+      "src/proto/grpc/testing/echo_mock.grpc.pb.h"
     ], 
     "is_filegroup": false, 
     "language": "c++", 
@@ -2974,7 +3263,8 @@
     ], 
     "headers": [
       "src/proto/grpc/lb/v1/load_balancer.grpc.pb.h", 
-      "src/proto/grpc/lb/v1/load_balancer.pb.h"
+      "src/proto/grpc/lb/v1/load_balancer.pb.h", 
+      "src/proto/grpc/lb/v1/load_balancer_mock.grpc.pb.h"
     ], 
     "is_filegroup": false, 
     "language": "c++", 
@@ -2996,7 +3286,31 @@
     ], 
     "headers": [
       "src/proto/grpc/lb/v1/load_balancer.grpc.pb.h", 
-      "src/proto/grpc/lb/v1/load_balancer.pb.h"
+      "src/proto/grpc/lb/v1/load_balancer.pb.h", 
+      "src/proto/grpc/lb/v1/load_balancer_mock.grpc.pb.h"
+    ], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "grpclb_end2end_test", 
+    "src": [
+      "test/cpp/end2end/grpclb_end2end_test.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_util", 
+      "grpc_test_util"
+    ], 
+    "headers": [
+      "src/proto/grpc/lb/v1/load_balancer.grpc.pb.h", 
+      "src/proto/grpc/lb/v1/load_balancer.pb.h", 
+      "src/proto/grpc/lb/v1/load_balancer_mock.grpc.pb.h"
     ], 
     "is_filegroup": false, 
     "language": "c++", 
@@ -3141,6 +3455,25 @@
     "third_party": false, 
     "type": "target"
   }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
+      "grpc++_test", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "memory_test", 
+    "src": [
+      "test/core/support/memory_test.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
   {
     "deps": [
       "gpr", 
@@ -3151,6 +3484,7 @@
     "headers": [
       "src/proto/grpc/testing/metrics.grpc.pb.h", 
       "src/proto/grpc/testing/metrics.pb.h", 
+      "src/proto/grpc/testing/metrics_mock.grpc.pb.h", 
       "test/cpp/util/metrics_server.h"
     ], 
     "is_filegroup": false, 
@@ -3172,11 +3506,14 @@
       "grpc++_test_util", 
       "grpc_test_util"
     ], 
-    "headers": [], 
+    "headers": [
+      "include/grpc++/test/mock_stream.h"
+    ], 
     "is_filegroup": false, 
     "language": "c++", 
     "name": "mock_test", 
     "src": [
+      "include/grpc++/test/mock_stream.h", 
       "test/cpp/end2end/mock_test.cc"
     ], 
     "third_party": false, 
@@ -3335,10 +3672,13 @@
     "headers": [
       "src/proto/grpc/testing/empty.grpc.pb.h", 
       "src/proto/grpc/testing/empty.pb.h", 
+      "src/proto/grpc/testing/empty_mock.grpc.pb.h", 
       "src/proto/grpc/testing/messages.grpc.pb.h", 
       "src/proto/grpc/testing/messages.pb.h", 
+      "src/proto/grpc/testing/messages_mock.grpc.pb.h", 
       "src/proto/grpc/testing/test.grpc.pb.h", 
-      "src/proto/grpc/testing/test.pb.h"
+      "src/proto/grpc/testing/test.pb.h", 
+      "src/proto/grpc/testing/test_mock.grpc.pb.h"
     ], 
     "is_filegroup": false, 
     "language": "c++", 
@@ -3364,10 +3704,13 @@
     "headers": [
       "src/proto/grpc/testing/empty.grpc.pb.h", 
       "src/proto/grpc/testing/empty.pb.h", 
+      "src/proto/grpc/testing/empty_mock.grpc.pb.h", 
       "src/proto/grpc/testing/messages.grpc.pb.h", 
       "src/proto/grpc/testing/messages.pb.h", 
+      "src/proto/grpc/testing/messages_mock.grpc.pb.h", 
       "src/proto/grpc/testing/test.grpc.pb.h", 
-      "src/proto/grpc/testing/test.pb.h"
+      "src/proto/grpc/testing/test.pb.h", 
+      "src/proto/grpc/testing/test_mock.grpc.pb.h"
     ], 
     "is_filegroup": false, 
     "language": "c++", 
@@ -3455,6 +3798,32 @@
     "third_party": false, 
     "type": "target"
   }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_util", 
+      "grpc_test_util"
+    ], 
+    "headers": [
+      "src/proto/grpc/testing/echo.grpc.pb.h", 
+      "src/proto/grpc/testing/echo.pb.h", 
+      "src/proto/grpc/testing/echo_messages.grpc.pb.h", 
+      "src/proto/grpc/testing/echo_messages.pb.h", 
+      "src/proto/grpc/testing/echo_messages_mock.grpc.pb.h", 
+      "src/proto/grpc/testing/echo_mock.grpc.pb.h"
+    ], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "server_builder_test", 
+    "src": [
+      "test/cpp/server/server_builder_test.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
   {
     "deps": [
       "gpr", 
@@ -3581,12 +3950,16 @@
     "headers": [
       "src/proto/grpc/testing/empty.grpc.pb.h", 
       "src/proto/grpc/testing/empty.pb.h", 
+      "src/proto/grpc/testing/empty_mock.grpc.pb.h", 
       "src/proto/grpc/testing/messages.grpc.pb.h", 
       "src/proto/grpc/testing/messages.pb.h", 
+      "src/proto/grpc/testing/messages_mock.grpc.pb.h", 
       "src/proto/grpc/testing/metrics.grpc.pb.h", 
       "src/proto/grpc/testing/metrics.pb.h", 
+      "src/proto/grpc/testing/metrics_mock.grpc.pb.h", 
       "src/proto/grpc/testing/test.grpc.pb.h", 
       "src/proto/grpc/testing/test.pb.h", 
+      "src/proto/grpc/testing/test_mock.grpc.pb.h", 
       "test/cpp/interop/client_helper.h", 
       "test/cpp/interop/interop_client.h", 
       "test/cpp/interop/stress_interop_client.h", 
@@ -3603,7 +3976,6 @@
       "test/cpp/interop/stress_interop_client.cc", 
       "test/cpp/interop/stress_interop_client.h", 
       "test/cpp/interop/stress_test.cc", 
-      "test/cpp/util/create_test_channel.cc", 
       "test/cpp/util/create_test_channel.h", 
       "test/cpp/util/metrics_server.cc", 
       "test/cpp/util/metrics_server.h"
@@ -5366,10 +5738,14 @@
       "census", 
       "gpr", 
       "grpc_base", 
+      "grpc_deadline_filter", 
       "grpc_lb_policy_grpclb_secure", 
       "grpc_lb_policy_pick_first", 
       "grpc_lb_policy_round_robin", 
       "grpc_load_reporting", 
+      "grpc_max_age_filter", 
+      "grpc_message_size_filter", 
+      "grpc_resolver_dns_ares", 
       "grpc_resolver_dns_native", 
       "grpc_resolver_sockaddr", 
       "grpc_secure", 
@@ -5467,10 +5843,14 @@
       "census", 
       "gpr", 
       "grpc_base", 
+      "grpc_deadline_filter", 
       "grpc_lb_policy_grpclb", 
       "grpc_lb_policy_pick_first", 
       "grpc_lb_policy_round_robin", 
       "grpc_load_reporting", 
+      "grpc_max_age_filter", 
+      "grpc_message_size_filter", 
+      "grpc_resolver_dns_ares", 
       "grpc_resolver_dns_native", 
       "grpc_resolver_sockaddr", 
       "grpc_transport_chttp2_client_insecure", 
@@ -5530,6 +5910,7 @@
   }, 
   {
     "deps": [
+      "gpr", 
       "grpc", 
       "grpc++_base", 
       "grpc++_codegen_base", 
@@ -5586,6 +5967,26 @@
     "third_party": false, 
     "type": "lib"
   }, 
+  {
+    "deps": [
+      "grpc++"
+    ], 
+    "headers": [
+      "include/grpc++/support/error_details.h", 
+      "src/proto/grpc/status/status.grpc.pb.h", 
+      "src/proto/grpc/status/status.pb.h", 
+      "src/proto/grpc/status/status_mock.grpc.pb.h"
+    ], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "grpc++_error_details", 
+    "src": [
+      "include/grpc++/support/error_details.h", 
+      "src/cpp/util/error_details.cc"
+    ], 
+    "third_party": false, 
+    "type": "lib"
+  }, 
   {
     "deps": [
       "grpc++", 
@@ -5648,18 +6049,21 @@
       "grpc++_codegen_base_src", 
       "grpc++_codegen_proto", 
       "grpc++_config_proto", 
-      "grpc_test_util", 
-      "thrift_util"
+      "grpc_test_util"
     ], 
     "headers": [
       "src/proto/grpc/health/v1/health.grpc.pb.h", 
       "src/proto/grpc/health/v1/health.pb.h", 
+      "src/proto/grpc/health/v1/health_mock.grpc.pb.h", 
       "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h", 
       "src/proto/grpc/testing/duplicate/echo_duplicate.pb.h", 
+      "src/proto/grpc/testing/duplicate/echo_duplicate_mock.grpc.pb.h", 
       "src/proto/grpc/testing/echo.grpc.pb.h", 
       "src/proto/grpc/testing/echo.pb.h", 
       "src/proto/grpc/testing/echo_messages.grpc.pb.h", 
       "src/proto/grpc/testing/echo_messages.pb.h", 
+      "src/proto/grpc/testing/echo_messages_mock.grpc.pb.h", 
+      "src/proto/grpc/testing/echo_mock.grpc.pb.h", 
       "test/cpp/end2end/test_service_impl.h", 
       "test/cpp/util/byte_buffer_proto_helper.h", 
       "test/cpp/util/create_test_channel.h", 
@@ -5707,6 +6111,30 @@
     "third_party": false, 
     "type": "lib"
   }, 
+  {
+    "deps": [
+      "benchmark", 
+      "grpc", 
+      "grpc++", 
+      "grpc_test_util"
+    ], 
+    "headers": [
+      "test/cpp/microbenchmarks/fullstack_context_mutators.h", 
+      "test/cpp/microbenchmarks/fullstack_fixtures.h", 
+      "test/cpp/microbenchmarks/helpers.h"
+    ], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "grpc_benchmark", 
+    "src": [
+      "test/cpp/microbenchmarks/fullstack_context_mutators.h", 
+      "test/cpp/microbenchmarks/fullstack_fixtures.h", 
+      "test/cpp/microbenchmarks/helpers.cc", 
+      "test/cpp/microbenchmarks/helpers.h"
+    ], 
+    "third_party": false, 
+    "type": "lib"
+  }, 
   {
     "deps": [
       "grpc++", 
@@ -5758,11 +6186,15 @@
       "src/compiler/objective_c_generator_helpers.h", 
       "src/compiler/php_generator.h", 
       "src/compiler/php_generator_helpers.h", 
+      "src/compiler/protobuf_plugin.h", 
       "src/compiler/python_generator.h", 
+      "src/compiler/python_generator_helpers.h", 
+      "src/compiler/python_private_generator.h", 
       "src/compiler/ruby_generator.h", 
       "src/compiler/ruby_generator_helpers-inl.h", 
       "src/compiler/ruby_generator_map-inl.h", 
-      "src/compiler/ruby_generator_string-inl.h"
+      "src/compiler/ruby_generator_string-inl.h", 
+      "src/compiler/schema_interface.h"
     ], 
     "is_filegroup": false, 
     "language": "c++", 
@@ -5785,13 +6217,17 @@
       "src/compiler/php_generator.cc", 
       "src/compiler/php_generator.h", 
       "src/compiler/php_generator_helpers.h", 
+      "src/compiler/protobuf_plugin.h", 
       "src/compiler/python_generator.cc", 
       "src/compiler/python_generator.h", 
+      "src/compiler/python_generator_helpers.h", 
+      "src/compiler/python_private_generator.h", 
       "src/compiler/ruby_generator.cc", 
       "src/compiler/ruby_generator.h", 
       "src/compiler/ruby_generator_helpers-inl.h", 
       "src/compiler/ruby_generator_map-inl.h", 
-      "src/compiler/ruby_generator_string-inl.h"
+      "src/compiler/ruby_generator_string-inl.h", 
+      "src/compiler/schema_interface.h"
     ], 
     "third_party": false, 
     "type": "lib"
@@ -5807,10 +6243,13 @@
     "headers": [
       "src/proto/grpc/testing/empty.grpc.pb.h", 
       "src/proto/grpc/testing/empty.pb.h", 
+      "src/proto/grpc/testing/empty_mock.grpc.pb.h", 
       "src/proto/grpc/testing/messages.grpc.pb.h", 
       "src/proto/grpc/testing/messages.pb.h", 
+      "src/proto/grpc/testing/messages_mock.grpc.pb.h", 
       "src/proto/grpc/testing/test.grpc.pb.h", 
       "src/proto/grpc/testing/test.pb.h", 
+      "src/proto/grpc/testing/test_mock.grpc.pb.h", 
       "test/cpp/interop/http2_client.h"
     ], 
     "is_filegroup": false, 
@@ -5834,6 +6273,7 @@
     "headers": [
       "src/proto/grpc/testing/messages.grpc.pb.h", 
       "src/proto/grpc/testing/messages.pb.h", 
+      "src/proto/grpc/testing/messages_mock.grpc.pb.h", 
       "test/cpp/interop/client_helper.h"
     ], 
     "is_filegroup": false, 
@@ -5860,10 +6300,13 @@
     "headers": [
       "src/proto/grpc/testing/empty.grpc.pb.h", 
       "src/proto/grpc/testing/empty.pb.h", 
+      "src/proto/grpc/testing/empty_mock.grpc.pb.h", 
       "src/proto/grpc/testing/messages.grpc.pb.h", 
       "src/proto/grpc/testing/messages.pb.h", 
+      "src/proto/grpc/testing/messages_mock.grpc.pb.h", 
       "src/proto/grpc/testing/test.grpc.pb.h", 
       "src/proto/grpc/testing/test.pb.h", 
+      "src/proto/grpc/testing/test_mock.grpc.pb.h", 
       "test/cpp/interop/interop_client.h"
     ], 
     "is_filegroup": false, 
@@ -5912,10 +6355,13 @@
     "headers": [
       "src/proto/grpc/testing/empty.grpc.pb.h", 
       "src/proto/grpc/testing/empty.pb.h", 
+      "src/proto/grpc/testing/empty_mock.grpc.pb.h", 
       "src/proto/grpc/testing/messages.grpc.pb.h", 
       "src/proto/grpc/testing/messages.pb.h", 
+      "src/proto/grpc/testing/messages_mock.grpc.pb.h", 
       "src/proto/grpc/testing/test.grpc.pb.h", 
-      "src/proto/grpc/testing/test.pb.h"
+      "src/proto/grpc/testing/test.pb.h", 
+      "src/proto/grpc/testing/test_mock.grpc.pb.h"
     ], 
     "is_filegroup": false, 
     "language": "c++", 
@@ -5949,14 +6395,20 @@
     "headers": [
       "src/proto/grpc/testing/control.grpc.pb.h", 
       "src/proto/grpc/testing/control.pb.h", 
+      "src/proto/grpc/testing/control_mock.grpc.pb.h", 
       "src/proto/grpc/testing/messages.grpc.pb.h", 
       "src/proto/grpc/testing/messages.pb.h", 
+      "src/proto/grpc/testing/messages_mock.grpc.pb.h", 
       "src/proto/grpc/testing/payloads.grpc.pb.h", 
       "src/proto/grpc/testing/payloads.pb.h", 
+      "src/proto/grpc/testing/payloads_mock.grpc.pb.h", 
       "src/proto/grpc/testing/services.grpc.pb.h", 
       "src/proto/grpc/testing/services.pb.h", 
+      "src/proto/grpc/testing/services_mock.grpc.pb.h", 
       "src/proto/grpc/testing/stats.grpc.pb.h", 
       "src/proto/grpc/testing/stats.pb.h", 
+      "src/proto/grpc/testing/stats_mock.grpc.pb.h", 
+      "test/cpp/qps/benchmark_config.h", 
       "test/cpp/qps/client.h", 
       "test/cpp/qps/driver.h", 
       "test/cpp/qps/histogram.h", 
@@ -5966,13 +6418,14 @@
       "test/cpp/qps/report.h", 
       "test/cpp/qps/server.h", 
       "test/cpp/qps/stats.h", 
-      "test/cpp/qps/usage_timer.h", 
-      "test/cpp/util/benchmark_config.h"
+      "test/cpp/qps/usage_timer.h"
     ], 
     "is_filegroup": false, 
     "language": "c++", 
     "name": "qps", 
     "src": [
+      "test/cpp/qps/benchmark_config.cc", 
+      "test/cpp/qps/benchmark_config.h", 
       "test/cpp/qps/client.h", 
       "test/cpp/qps/client_async.cc", 
       "test/cpp/qps/client_sync.cc", 
@@ -5991,9 +6444,7 @@
       "test/cpp/qps/server_sync.cc", 
       "test/cpp/qps/stats.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"
+      "test/cpp/qps/usage_timer.h"
     ], 
     "third_party": false, 
     "type": "lib"
@@ -6791,6 +7242,41 @@
     "third_party": true, 
     "type": "lib"
   }, 
+  {
+    "deps": [], 
+    "headers": [
+      "third_party/cares/ares_build.h", 
+      "third_party/cares/cares/ares.h", 
+      "third_party/cares/cares/ares_data.h", 
+      "third_party/cares/cares/ares_dns.h", 
+      "third_party/cares/cares/ares_getenv.h", 
+      "third_party/cares/cares/ares_getopt.h", 
+      "third_party/cares/cares/ares_inet_net_pton.h", 
+      "third_party/cares/cares/ares_iphlpapi.h", 
+      "third_party/cares/cares/ares_ipv6.h", 
+      "third_party/cares/cares/ares_library_init.h", 
+      "third_party/cares/cares/ares_llist.h", 
+      "third_party/cares/cares/ares_nowarn.h", 
+      "third_party/cares/cares/ares_platform.h", 
+      "third_party/cares/cares/ares_private.h", 
+      "third_party/cares/cares/ares_rules.h", 
+      "third_party/cares/cares/ares_setup.h", 
+      "third_party/cares/cares/ares_strcasecmp.h", 
+      "third_party/cares/cares/ares_strdup.h", 
+      "third_party/cares/cares/ares_version.h", 
+      "third_party/cares/cares/bitncmp.h", 
+      "third_party/cares/cares/config-win32.h", 
+      "third_party/cares/cares/setup_once.h", 
+      "third_party/cares/config_darwin/ares_config.h", 
+      "third_party/cares/config_linux/ares_config.h"
+    ], 
+    "is_filegroup": false, 
+    "language": "c", 
+    "name": "ares", 
+    "src": [], 
+    "third_party": false, 
+    "type": "lib"
+  }, 
   {
     "deps": [
       "gpr", 
@@ -6851,6 +7337,7 @@
       "test/core/end2end/end2end_tests.h", 
       "test/core/end2end/tests/authority_not_supported.c", 
       "test/core/end2end/tests/bad_hostname.c", 
+      "test/core/end2end/tests/bad_ping.c", 
       "test/core/end2end/tests/binary_metadata.c", 
       "test/core/end2end/tests/call_creds.c", 
       "test/core/end2end/tests/cancel_after_accept.c", 
@@ -6877,6 +7364,8 @@
       "test/core/end2end/tests/large_metadata.c", 
       "test/core/end2end/tests/load_reporting_hook.c", 
       "test/core/end2end/tests/max_concurrent_streams.c", 
+      "test/core/end2end/tests/max_connection_age.c", 
+      "test/core/end2end/tests/max_connection_idle.c", 
       "test/core/end2end/tests/max_message_length.c", 
       "test/core/end2end/tests/negative_deadline.c", 
       "test/core/end2end/tests/network_status_change.c", 
@@ -6924,6 +7413,7 @@
       "test/core/end2end/end2end_tests.h", 
       "test/core/end2end/tests/authority_not_supported.c", 
       "test/core/end2end/tests/bad_hostname.c", 
+      "test/core/end2end/tests/bad_ping.c", 
       "test/core/end2end/tests/binary_metadata.c", 
       "test/core/end2end/tests/cancel_after_accept.c", 
       "test/core/end2end/tests/cancel_after_client_done.c", 
@@ -6949,6 +7439,8 @@
       "test/core/end2end/tests/large_metadata.c", 
       "test/core/end2end/tests/load_reporting_hook.c", 
       "test/core/end2end/tests/max_concurrent_streams.c", 
+      "test/core/end2end/tests/max_connection_age.c", 
+      "test/core/end2end/tests/max_connection_idle.c", 
       "test/core/end2end/tests/max_message_length.c", 
       "test/core/end2end/tests/negative_deadline.c", 
       "test/core/end2end/tests/network_status_change.c", 
@@ -7072,9 +7564,14 @@
       "include/grpc/support/tls_pthread.h", 
       "include/grpc/support/useful.h", 
       "src/core/lib/profiling/timers.h", 
+      "src/core/lib/support/arena.h", 
+      "src/core/lib/support/atomic.h", 
+      "src/core/lib/support/atomic_with_atm.h", 
+      "src/core/lib/support/atomic_with_std.h", 
       "src/core/lib/support/backoff.h", 
       "src/core/lib/support/block_annotate.h", 
       "src/core/lib/support/env.h", 
+      "src/core/lib/support/memory.h", 
       "src/core/lib/support/mpscq.h", 
       "src/core/lib/support/murmur_hash.h", 
       "src/core/lib/support/spinlock.h", 
@@ -7119,6 +7616,12 @@
       "src/core/lib/profiling/stap_timers.c", 
       "src/core/lib/profiling/timers.h", 
       "src/core/lib/support/alloc.c", 
+      "src/core/lib/support/arena.c", 
+      "src/core/lib/support/arena.h", 
+      "src/core/lib/support/atm.c", 
+      "src/core/lib/support/atomic.h", 
+      "src/core/lib/support/atomic_with_atm.h", 
+      "src/core/lib/support/atomic_with_std.h", 
       "src/core/lib/support/avl.c", 
       "src/core/lib/support/backoff.c", 
       "src/core/lib/support/backoff.h", 
@@ -7139,6 +7642,7 @@
       "src/core/lib/support/log_linux.c", 
       "src/core/lib/support/log_posix.c", 
       "src/core/lib/support/log_windows.c", 
+      "src/core/lib/support/memory.h", 
       "src/core/lib/support/mpscq.c", 
       "src/core/lib/support/mpscq.h", 
       "src/core/lib/support/murmur_hash.c", 
@@ -7186,7 +7690,6 @@
       "include/grpc/impl/codegen/gpr_slice.h", 
       "include/grpc/impl/codegen/gpr_types.h", 
       "include/grpc/impl/codegen/port_platform.h", 
-      "include/grpc/impl/codegen/slice.h", 
       "include/grpc/impl/codegen/sync.h", 
       "include/grpc/impl/codegen/sync_generic.h", 
       "include/grpc/impl/codegen/sync_posix.h", 
@@ -7203,7 +7706,6 @@
       "include/grpc/impl/codegen/gpr_slice.h", 
       "include/grpc/impl/codegen/gpr_types.h", 
       "include/grpc/impl/codegen/port_platform.h", 
-      "include/grpc/impl/codegen/slice.h", 
       "include/grpc/impl/codegen/sync.h", 
       "include/grpc/impl/codegen/sync_generic.h", 
       "include/grpc/impl/codegen/sync_posix.h", 
@@ -7231,16 +7733,11 @@
       "src/core/lib/channel/channel_args.h", 
       "src/core/lib/channel/channel_stack.h", 
       "src/core/lib/channel/channel_stack_builder.h", 
-      "src/core/lib/channel/compress_filter.h", 
       "src/core/lib/channel/connected_channel.h", 
       "src/core/lib/channel/context.h", 
-      "src/core/lib/channel/deadline_filter.h", 
       "src/core/lib/channel/handshaker.h", 
       "src/core/lib/channel/handshaker_factory.h", 
       "src/core/lib/channel/handshaker_registry.h", 
-      "src/core/lib/channel/http_client_filter.h", 
-      "src/core/lib/channel/http_server_filter.h", 
-      "src/core/lib/channel/message_size_filter.h", 
       "src/core/lib/compression/algorithm_metadata.h", 
       "src/core/lib/compression/message_compress.h", 
       "src/core/lib/debug/trace.h", 
@@ -7263,6 +7760,7 @@
       "src/core/lib/iomgr/iomgr_internal.h", 
       "src/core/lib/iomgr/iomgr_posix.h", 
       "src/core/lib/iomgr/load_file.h", 
+      "src/core/lib/iomgr/lockfree_event.h", 
       "src/core/lib/iomgr/network_status_tracker.h", 
       "src/core/lib/iomgr/polling_entity.h", 
       "src/core/lib/iomgr/pollset.h", 
@@ -7277,6 +7775,7 @@
       "src/core/lib/iomgr/sockaddr_posix.h", 
       "src/core/lib/iomgr/sockaddr_utils.h", 
       "src/core/lib/iomgr/sockaddr_windows.h", 
+      "src/core/lib/iomgr/socket_factory_posix.h", 
       "src/core/lib/iomgr/socket_mutator.h", 
       "src/core/lib/iomgr/socket_utils.h", 
       "src/core/lib/iomgr/socket_utils_posix.h", 
@@ -7285,6 +7784,7 @@
       "src/core/lib/iomgr/tcp_client_posix.h", 
       "src/core/lib/iomgr/tcp_posix.h", 
       "src/core/lib/iomgr/tcp_server.h", 
+      "src/core/lib/iomgr/tcp_server_utils_posix.h", 
       "src/core/lib/iomgr/tcp_uv.h", 
       "src/core/lib/iomgr/tcp_windows.h", 
       "src/core/lib/iomgr/time_averaged_stats.h", 
@@ -7304,6 +7804,7 @@
       "src/core/lib/json/json_common.h", 
       "src/core/lib/json/json_reader.h", 
       "src/core/lib/json/json_writer.h", 
+      "src/core/lib/slice/b64.h", 
       "src/core/lib/slice/percent_encoding.h", 
       "src/core/lib/slice/slice_hash_table.h", 
       "src/core/lib/slice/slice_internal.h", 
@@ -7315,6 +7816,7 @@
       "src/core/lib/surface/channel_init.h", 
       "src/core/lib/surface/channel_stack_type.h", 
       "src/core/lib/surface/completion_queue.h", 
+      "src/core/lib/surface/completion_queue_factory.h", 
       "src/core/lib/surface/event_string.h", 
       "src/core/lib/surface/init.h", 
       "src/core/lib/surface/lame_client.h", 
@@ -7355,25 +7857,15 @@
       "src/core/lib/channel/channel_stack.h", 
       "src/core/lib/channel/channel_stack_builder.c", 
       "src/core/lib/channel/channel_stack_builder.h", 
-      "src/core/lib/channel/compress_filter.c", 
-      "src/core/lib/channel/compress_filter.h", 
       "src/core/lib/channel/connected_channel.c", 
       "src/core/lib/channel/connected_channel.h", 
       "src/core/lib/channel/context.h", 
-      "src/core/lib/channel/deadline_filter.c", 
-      "src/core/lib/channel/deadline_filter.h", 
       "src/core/lib/channel/handshaker.c", 
       "src/core/lib/channel/handshaker.h", 
       "src/core/lib/channel/handshaker_factory.c", 
       "src/core/lib/channel/handshaker_factory.h", 
       "src/core/lib/channel/handshaker_registry.c", 
       "src/core/lib/channel/handshaker_registry.h", 
-      "src/core/lib/channel/http_client_filter.c", 
-      "src/core/lib/channel/http_client_filter.h", 
-      "src/core/lib/channel/http_server_filter.c", 
-      "src/core/lib/channel/http_server_filter.h", 
-      "src/core/lib/channel/message_size_filter.c", 
-      "src/core/lib/channel/message_size_filter.h", 
       "src/core/lib/compression/algorithm_metadata.h", 
       "src/core/lib/compression/compression.c", 
       "src/core/lib/compression/message_compress.c", 
@@ -7420,6 +7912,8 @@
       "src/core/lib/iomgr/iomgr_windows.c", 
       "src/core/lib/iomgr/load_file.c", 
       "src/core/lib/iomgr/load_file.h", 
+      "src/core/lib/iomgr/lockfree_event.c", 
+      "src/core/lib/iomgr/lockfree_event.h", 
       "src/core/lib/iomgr/network_status_tracker.c", 
       "src/core/lib/iomgr/network_status_tracker.h", 
       "src/core/lib/iomgr/polling_entity.c", 
@@ -7445,6 +7939,8 @@
       "src/core/lib/iomgr/sockaddr_utils.c", 
       "src/core/lib/iomgr/sockaddr_utils.h", 
       "src/core/lib/iomgr/sockaddr_windows.h", 
+      "src/core/lib/iomgr/socket_factory_posix.c", 
+      "src/core/lib/iomgr/socket_factory_posix.h", 
       "src/core/lib/iomgr/socket_mutator.c", 
       "src/core/lib/iomgr/socket_mutator.h", 
       "src/core/lib/iomgr/socket_utils.h", 
@@ -7465,6 +7961,10 @@
       "src/core/lib/iomgr/tcp_posix.h", 
       "src/core/lib/iomgr/tcp_server.h", 
       "src/core/lib/iomgr/tcp_server_posix.c", 
+      "src/core/lib/iomgr/tcp_server_utils_posix.h", 
+      "src/core/lib/iomgr/tcp_server_utils_posix_common.c", 
+      "src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c", 
+      "src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c", 
       "src/core/lib/iomgr/tcp_server_uv.c", 
       "src/core/lib/iomgr/tcp_server_windows.c", 
       "src/core/lib/iomgr/tcp_uv.c", 
@@ -7506,6 +8006,8 @@
       "src/core/lib/json/json_string.c", 
       "src/core/lib/json/json_writer.c", 
       "src/core/lib/json/json_writer.h", 
+      "src/core/lib/slice/b64.c", 
+      "src/core/lib/slice/b64.h", 
       "src/core/lib/slice/percent_encoding.c", 
       "src/core/lib/slice/percent_encoding.h", 
       "src/core/lib/slice/slice.c", 
@@ -7535,10 +8037,12 @@
       "src/core/lib/surface/channel_stack_type.h", 
       "src/core/lib/surface/completion_queue.c", 
       "src/core/lib/surface/completion_queue.h", 
+      "src/core/lib/surface/completion_queue_factory.c", 
+      "src/core/lib/surface/completion_queue_factory.h", 
       "src/core/lib/surface/event_string.c", 
       "src/core/lib/surface/event_string.h", 
       "src/core/lib/surface/init.h", 
-      "src/core/lib/surface/lame_client.c", 
+      "src/core/lib/surface/lame_client.cc", 
       "src/core/lib/surface/lame_client.h", 
       "src/core/lib/surface/metadata_array.c", 
       "src/core/lib/surface/server.c", 
@@ -7580,71 +8084,71 @@
   {
     "deps": [
       "gpr", 
-      "grpc_base"
+      "grpc_base", 
+      "grpc_deadline_filter"
     ], 
     "headers": [
-      "src/core/ext/client_channel/client_channel.h", 
-      "src/core/ext/client_channel/client_channel_factory.h", 
-      "src/core/ext/client_channel/connector.h", 
-      "src/core/ext/client_channel/http_connect_handshaker.h", 
-      "src/core/ext/client_channel/http_proxy.h", 
-      "src/core/ext/client_channel/initial_connect_string.h", 
-      "src/core/ext/client_channel/lb_policy.h", 
-      "src/core/ext/client_channel/lb_policy_factory.h", 
-      "src/core/ext/client_channel/lb_policy_registry.h", 
-      "src/core/ext/client_channel/parse_address.h", 
-      "src/core/ext/client_channel/proxy_mapper.h", 
-      "src/core/ext/client_channel/proxy_mapper_registry.h", 
-      "src/core/ext/client_channel/resolver.h", 
-      "src/core/ext/client_channel/resolver_factory.h", 
-      "src/core/ext/client_channel/resolver_registry.h", 
-      "src/core/ext/client_channel/subchannel.h", 
-      "src/core/ext/client_channel/subchannel_index.h", 
-      "src/core/ext/client_channel/uri_parser.h"
+      "src/core/ext/filters/client_channel/client_channel.h", 
+      "src/core/ext/filters/client_channel/client_channel_factory.h", 
+      "src/core/ext/filters/client_channel/connector.h", 
+      "src/core/ext/filters/client_channel/http_connect_handshaker.h", 
+      "src/core/ext/filters/client_channel/http_proxy.h", 
+      "src/core/ext/filters/client_channel/lb_policy.h", 
+      "src/core/ext/filters/client_channel/lb_policy_factory.h", 
+      "src/core/ext/filters/client_channel/lb_policy_registry.h", 
+      "src/core/ext/filters/client_channel/parse_address.h", 
+      "src/core/ext/filters/client_channel/proxy_mapper.h", 
+      "src/core/ext/filters/client_channel/proxy_mapper_registry.h", 
+      "src/core/ext/filters/client_channel/resolver.h", 
+      "src/core/ext/filters/client_channel/resolver_factory.h", 
+      "src/core/ext/filters/client_channel/resolver_registry.h", 
+      "src/core/ext/filters/client_channel/retry_throttle.h", 
+      "src/core/ext/filters/client_channel/subchannel.h", 
+      "src/core/ext/filters/client_channel/subchannel_index.h", 
+      "src/core/ext/filters/client_channel/uri_parser.h"
     ], 
     "is_filegroup": true, 
     "language": "c", 
     "name": "grpc_client_channel", 
     "src": [
-      "src/core/ext/client_channel/channel_connectivity.c", 
-      "src/core/ext/client_channel/client_channel.c", 
-      "src/core/ext/client_channel/client_channel.h", 
-      "src/core/ext/client_channel/client_channel_factory.c", 
-      "src/core/ext/client_channel/client_channel_factory.h", 
-      "src/core/ext/client_channel/client_channel_plugin.c", 
-      "src/core/ext/client_channel/connector.c", 
-      "src/core/ext/client_channel/connector.h", 
-      "src/core/ext/client_channel/default_initial_connect_string.c", 
-      "src/core/ext/client_channel/http_connect_handshaker.c", 
-      "src/core/ext/client_channel/http_connect_handshaker.h", 
-      "src/core/ext/client_channel/http_proxy.c", 
-      "src/core/ext/client_channel/http_proxy.h", 
-      "src/core/ext/client_channel/initial_connect_string.c", 
-      "src/core/ext/client_channel/initial_connect_string.h", 
-      "src/core/ext/client_channel/lb_policy.c", 
-      "src/core/ext/client_channel/lb_policy.h", 
-      "src/core/ext/client_channel/lb_policy_factory.c", 
-      "src/core/ext/client_channel/lb_policy_factory.h", 
-      "src/core/ext/client_channel/lb_policy_registry.c", 
-      "src/core/ext/client_channel/lb_policy_registry.h", 
-      "src/core/ext/client_channel/parse_address.c", 
-      "src/core/ext/client_channel/parse_address.h", 
-      "src/core/ext/client_channel/proxy_mapper.c", 
-      "src/core/ext/client_channel/proxy_mapper.h", 
-      "src/core/ext/client_channel/proxy_mapper_registry.c", 
-      "src/core/ext/client_channel/proxy_mapper_registry.h", 
-      "src/core/ext/client_channel/resolver.c", 
-      "src/core/ext/client_channel/resolver.h", 
-      "src/core/ext/client_channel/resolver_factory.c", 
-      "src/core/ext/client_channel/resolver_factory.h", 
-      "src/core/ext/client_channel/resolver_registry.c", 
-      "src/core/ext/client_channel/resolver_registry.h", 
-      "src/core/ext/client_channel/subchannel.c", 
-      "src/core/ext/client_channel/subchannel.h", 
-      "src/core/ext/client_channel/subchannel_index.c", 
-      "src/core/ext/client_channel/subchannel_index.h", 
-      "src/core/ext/client_channel/uri_parser.c", 
-      "src/core/ext/client_channel/uri_parser.h"
+      "src/core/ext/filters/client_channel/channel_connectivity.c", 
+      "src/core/ext/filters/client_channel/client_channel.c", 
+      "src/core/ext/filters/client_channel/client_channel.h", 
+      "src/core/ext/filters/client_channel/client_channel_factory.c", 
+      "src/core/ext/filters/client_channel/client_channel_factory.h", 
+      "src/core/ext/filters/client_channel/client_channel_plugin.c", 
+      "src/core/ext/filters/client_channel/connector.c", 
+      "src/core/ext/filters/client_channel/connector.h", 
+      "src/core/ext/filters/client_channel/http_connect_handshaker.c", 
+      "src/core/ext/filters/client_channel/http_connect_handshaker.h", 
+      "src/core/ext/filters/client_channel/http_proxy.c", 
+      "src/core/ext/filters/client_channel/http_proxy.h", 
+      "src/core/ext/filters/client_channel/lb_policy.c", 
+      "src/core/ext/filters/client_channel/lb_policy.h", 
+      "src/core/ext/filters/client_channel/lb_policy_factory.c", 
+      "src/core/ext/filters/client_channel/lb_policy_factory.h", 
+      "src/core/ext/filters/client_channel/lb_policy_registry.c", 
+      "src/core/ext/filters/client_channel/lb_policy_registry.h", 
+      "src/core/ext/filters/client_channel/parse_address.c", 
+      "src/core/ext/filters/client_channel/parse_address.h", 
+      "src/core/ext/filters/client_channel/proxy_mapper.c", 
+      "src/core/ext/filters/client_channel/proxy_mapper.h", 
+      "src/core/ext/filters/client_channel/proxy_mapper_registry.c", 
+      "src/core/ext/filters/client_channel/proxy_mapper_registry.h", 
+      "src/core/ext/filters/client_channel/resolver.c", 
+      "src/core/ext/filters/client_channel/resolver.h", 
+      "src/core/ext/filters/client_channel/resolver_factory.c", 
+      "src/core/ext/filters/client_channel/resolver_factory.h", 
+      "src/core/ext/filters/client_channel/resolver_registry.c", 
+      "src/core/ext/filters/client_channel/resolver_registry.h", 
+      "src/core/ext/filters/client_channel/retry_throttle.c", 
+      "src/core/ext/filters/client_channel/retry_throttle.h", 
+      "src/core/ext/filters/client_channel/subchannel.c", 
+      "src/core/ext/filters/client_channel/subchannel.h", 
+      "src/core/ext/filters/client_channel/subchannel_index.c", 
+      "src/core/ext/filters/client_channel/subchannel_index.h", 
+      "src/core/ext/filters/client_channel/uri_parser.c", 
+      "src/core/ext/filters/client_channel/uri_parser.h"
     ], 
     "third_party": false, 
     "type": "filegroup"
@@ -7660,6 +8164,7 @@
       "include/grpc/impl/codegen/exec_ctx_fwd.h", 
       "include/grpc/impl/codegen/grpc_types.h", 
       "include/grpc/impl/codegen/propagation_bits.h", 
+      "include/grpc/impl/codegen/slice.h", 
       "include/grpc/impl/codegen/status.h"
     ], 
     "is_filegroup": true, 
@@ -7672,11 +8177,55 @@
       "include/grpc/impl/codegen/exec_ctx_fwd.h", 
       "include/grpc/impl/codegen/grpc_types.h", 
       "include/grpc/impl/codegen/propagation_bits.h", 
+      "include/grpc/impl/codegen/slice.h", 
       "include/grpc/impl/codegen/status.h"
     ], 
     "third_party": false, 
     "type": "filegroup"
   }, 
+  {
+    "deps": [
+      "gpr", 
+      "grpc_base"
+    ], 
+    "headers": [
+      "src/core/ext/filters/deadline/deadline_filter.h"
+    ], 
+    "is_filegroup": true, 
+    "language": "c", 
+    "name": "grpc_deadline_filter", 
+    "src": [
+      "src/core/ext/filters/deadline/deadline_filter.c", 
+      "src/core/ext/filters/deadline/deadline_filter.h"
+    ], 
+    "third_party": false, 
+    "type": "filegroup"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "grpc_base"
+    ], 
+    "headers": [
+      "src/core/ext/filters/http/client/http_client_filter.h", 
+      "src/core/ext/filters/http/message_compress/message_compress_filter.h", 
+      "src/core/ext/filters/http/server/http_server_filter.h"
+    ], 
+    "is_filegroup": true, 
+    "language": "c", 
+    "name": "grpc_http_filters", 
+    "src": [
+      "src/core/ext/filters/http/client/http_client_filter.c", 
+      "src/core/ext/filters/http/client/http_client_filter.h", 
+      "src/core/ext/filters/http/http_filters_plugin.c", 
+      "src/core/ext/filters/http/message_compress/message_compress_filter.c", 
+      "src/core/ext/filters/http/message_compress/message_compress_filter.h", 
+      "src/core/ext/filters/http/server/http_server_filter.c", 
+      "src/core/ext/filters/http/server/http_server_filter.h"
+    ], 
+    "third_party": false, 
+    "type": "filegroup"
+  }, 
   {
     "deps": [
       "gpr", 
@@ -7685,23 +8234,29 @@
       "nanopb"
     ], 
     "headers": [
-      "src/core/ext/lb_policy/grpclb/grpclb.h", 
-      "src/core/ext/lb_policy/grpclb/grpclb_channel.h", 
-      "src/core/ext/lb_policy/grpclb/load_balancer_api.h", 
-      "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
     ], 
     "is_filegroup": true, 
     "language": "c", 
     "name": "grpc_lb_policy_grpclb", 
     "src": [
-      "src/core/ext/lb_policy/grpclb/grpclb.c", 
-      "src/core/ext/lb_policy/grpclb/grpclb.h", 
-      "src/core/ext/lb_policy/grpclb/grpclb_channel.c", 
-      "src/core/ext/lb_policy/grpclb/grpclb_channel.h", 
-      "src/core/ext/lb_policy/grpclb/load_balancer_api.c", 
-      "src/core/ext/lb_policy/grpclb/load_balancer_api.h", 
-      "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", 
-      "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
     ], 
     "third_party": false, 
     "type": "filegroup"
@@ -7711,26 +8266,33 @@
       "gpr", 
       "grpc_base", 
       "grpc_client_channel", 
+      "grpc_secure", 
       "nanopb"
     ], 
     "headers": [
-      "src/core/ext/lb_policy/grpclb/grpclb.h", 
-      "src/core/ext/lb_policy/grpclb/grpclb_channel.h", 
-      "src/core/ext/lb_policy/grpclb/load_balancer_api.h", 
-      "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
     ], 
     "is_filegroup": true, 
     "language": "c", 
     "name": "grpc_lb_policy_grpclb_secure", 
     "src": [
-      "src/core/ext/lb_policy/grpclb/grpclb.c", 
-      "src/core/ext/lb_policy/grpclb/grpclb.h", 
-      "src/core/ext/lb_policy/grpclb/grpclb_channel.h", 
-      "src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c", 
-      "src/core/ext/lb_policy/grpclb/load_balancer_api.c", 
-      "src/core/ext/lb_policy/grpclb/load_balancer_api.h", 
-      "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", 
-      "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", 
+      "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
     ], 
     "third_party": false, 
     "type": "filegroup"
@@ -7746,7 +8308,7 @@
     "language": "c", 
     "name": "grpc_lb_policy_pick_first", 
     "src": [
-      "src/core/ext/lb_policy/pick_first/pick_first.c"
+      "src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c"
     ], 
     "third_party": false, 
     "type": "filegroup"
@@ -7762,7 +8324,7 @@
     "language": "c", 
     "name": "grpc_lb_policy_round_robin", 
     "src": [
-      "src/core/ext/lb_policy/round_robin/round_robin.c"
+      "src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c"
     ], 
     "third_party": false, 
     "type": "filegroup"
@@ -7773,17 +8335,76 @@
       "grpc_base"
     ], 
     "headers": [
-      "src/core/ext/load_reporting/load_reporting.h", 
-      "src/core/ext/load_reporting/load_reporting_filter.h"
+      "src/core/ext/filters/load_reporting/load_reporting.h", 
+      "src/core/ext/filters/load_reporting/load_reporting_filter.h"
     ], 
     "is_filegroup": true, 
     "language": "c", 
     "name": "grpc_load_reporting", 
     "src": [
-      "src/core/ext/load_reporting/load_reporting.c", 
-      "src/core/ext/load_reporting/load_reporting.h", 
-      "src/core/ext/load_reporting/load_reporting_filter.c", 
-      "src/core/ext/load_reporting/load_reporting_filter.h"
+      "src/core/ext/filters/load_reporting/load_reporting.c", 
+      "src/core/ext/filters/load_reporting/load_reporting.h", 
+      "src/core/ext/filters/load_reporting/load_reporting_filter.c", 
+      "src/core/ext/filters/load_reporting/load_reporting_filter.h"
+    ], 
+    "third_party": false, 
+    "type": "filegroup"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "grpc_base"
+    ], 
+    "headers": [
+      "src/core/ext/filters/max_age/max_age_filter.h"
+    ], 
+    "is_filegroup": true, 
+    "language": "c", 
+    "name": "grpc_max_age_filter", 
+    "src": [
+      "src/core/ext/filters/max_age/max_age_filter.c", 
+      "src/core/ext/filters/max_age/max_age_filter.h"
+    ], 
+    "third_party": false, 
+    "type": "filegroup"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "grpc_base"
+    ], 
+    "headers": [
+      "src/core/ext/filters/message_size/message_size_filter.h"
+    ], 
+    "is_filegroup": true, 
+    "language": "c", 
+    "name": "grpc_message_size_filter", 
+    "src": [
+      "src/core/ext/filters/message_size/message_size_filter.c", 
+      "src/core/ext/filters/message_size/message_size_filter.h"
+    ], 
+    "third_party": false, 
+    "type": "filegroup"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "grpc_base", 
+      "grpc_client_channel"
+    ], 
+    "headers": [
+      "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", 
+      "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
+    ], 
+    "is_filegroup": true, 
+    "language": "c", 
+    "name": "grpc_resolver_dns_ares", 
+    "src": [
+      "src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c", 
+      "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", 
+      "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c", 
+      "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c", 
+      "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
     ], 
     "third_party": false, 
     "type": "filegroup"
@@ -7799,7 +8420,7 @@
     "language": "c", 
     "name": "grpc_resolver_dns_native", 
     "src": [
-      "src/core/ext/resolver/dns/native/dns_resolver.c"
+      "src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c"
     ], 
     "third_party": false, 
     "type": "filegroup"
@@ -7815,7 +8436,7 @@
     "language": "c", 
     "name": "grpc_resolver_sockaddr", 
     "src": [
-      "src/core/ext/resolver/sockaddr/sockaddr_resolver.c"
+      "src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c"
     ], 
     "third_party": false, 
     "type": "filegroup"
@@ -7847,7 +8468,6 @@
       "src/core/lib/security/transport/security_connector.h", 
       "src/core/lib/security/transport/security_handshaker.h", 
       "src/core/lib/security/transport/tsi_error.h", 
-      "src/core/lib/security/util/b64.h", 
       "src/core/lib/security/util/json_util.h"
     ], 
     "is_filegroup": true, 
@@ -7895,8 +8515,6 @@
       "src/core/lib/security/transport/server_auth_filter.c", 
       "src/core/lib/security/transport/tsi_error.c", 
       "src/core/lib/security/transport/tsi_error.h", 
-      "src/core/lib/security/util/b64.c", 
-      "src/core/lib/security/util/b64.h", 
       "src/core/lib/security/util/json_util.c", 
       "src/core/lib/security/util/json_util.h", 
       "src/core/lib/surface/init_secure.c"
@@ -7912,7 +8530,7 @@
     "headers": [
       "test/core/end2end/cq_verifier.h", 
       "test/core/end2end/fake_resolver.h", 
-      "test/core/end2end/fixtures/http_proxy.h", 
+      "test/core/end2end/fixtures/http_proxy_fixture.h", 
       "test/core/end2end/fixtures/proxy.h", 
       "test/core/iomgr/endpoint_tests.h", 
       "test/core/util/debugger_macros.h", 
@@ -7934,8 +8552,8 @@
       "test/core/end2end/cq_verifier.h", 
       "test/core/end2end/fake_resolver.c", 
       "test/core/end2end/fake_resolver.h", 
-      "test/core/end2end/fixtures/http_proxy.c", 
-      "test/core/end2end/fixtures/http_proxy.h", 
+      "test/core/end2end/fixtures/http_proxy_fixture.c", 
+      "test/core/end2end/fixtures/http_proxy_fixture.h", 
       "test/core/end2end/fixtures/proxy.c", 
       "test/core/end2end/fixtures/proxy.h", 
       "test/core/iomgr/endpoint_tests.c", 
@@ -7968,6 +8586,7 @@
     "deps": [
       "gpr", 
       "grpc_base", 
+      "grpc_http_filters", 
       "grpc_transport_chttp2_alpn"
     ], 
     "headers": [
@@ -7984,6 +8603,7 @@
       "src/core/ext/transport/chttp2/transport/hpack_encoder.h", 
       "src/core/ext/transport/chttp2/transport/hpack_parser.h", 
       "src/core/ext/transport/chttp2/transport/hpack_table.h", 
+      "src/core/ext/transport/chttp2/transport/http2_settings.h", 
       "src/core/ext/transport/chttp2/transport/huffsyms.h", 
       "src/core/ext/transport/chttp2/transport/incoming_metadata.h", 
       "src/core/ext/transport/chttp2/transport/internal.h", 
@@ -8020,6 +8640,8 @@
       "src/core/ext/transport/chttp2/transport/hpack_parser.h", 
       "src/core/ext/transport/chttp2/transport/hpack_table.c", 
       "src/core/ext/transport/chttp2/transport/hpack_table.h", 
+      "src/core/ext/transport/chttp2/transport/http2_settings.c", 
+      "src/core/ext/transport/chttp2/transport/http2_settings.h", 
       "src/core/ext/transport/chttp2/transport/huffsyms.c", 
       "src/core/ext/transport/chttp2/transport/huffsyms.h", 
       "src/core/ext/transport/chttp2/transport/incoming_metadata.c", 
@@ -8057,6 +8679,7 @@
     "deps": [
       "gpr", 
       "grpc_base", 
+      "grpc_client_channel", 
       "grpc_transport_chttp2"
     ], 
     "headers": [
@@ -8168,6 +8791,7 @@
   {
     "deps": [
       "grpc_base", 
+      "grpc_http_filters", 
       "grpc_transport_chttp2"
     ], 
     "headers": [
@@ -8212,31 +8836,37 @@
       "gpr"
     ], 
     "headers": [
-      "src/core/lib/tsi/fake_transport_security.h", 
-      "src/core/lib/tsi/ssl_transport_security.h", 
-      "src/core/lib/tsi/ssl_types.h", 
-      "src/core/lib/tsi/transport_security.h", 
-      "src/core/lib/tsi/transport_security_interface.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_adapter.h", 
+      "src/core/tsi/transport_security_interface.h"
     ], 
     "is_filegroup": true, 
     "language": "c", 
     "name": "tsi", 
     "src": [
-      "src/core/lib/tsi/fake_transport_security.c", 
-      "src/core/lib/tsi/fake_transport_security.h", 
-      "src/core/lib/tsi/ssl_transport_security.c", 
-      "src/core/lib/tsi/ssl_transport_security.h", 
-      "src/core/lib/tsi/ssl_types.h", 
-      "src/core/lib/tsi/transport_security.c", 
-      "src/core/lib/tsi/transport_security.h", 
-      "src/core/lib/tsi/transport_security_interface.h"
+      "src/core/tsi/fake_transport_security.c", 
+      "src/core/tsi/fake_transport_security.h", 
+      "src/core/tsi/ssl_transport_security.c", 
+      "src/core/tsi/ssl_transport_security.h", 
+      "src/core/tsi/ssl_types.h", 
+      "src/core/tsi/transport_security.c", 
+      "src/core/tsi/transport_security.h", 
+      "src/core/tsi/transport_security_adapter.c", 
+      "src/core/tsi/transport_security_adapter.h", 
+      "src/core/tsi/transport_security_interface.h"
     ], 
     "third_party": false, 
     "type": "filegroup"
   }, 
   {
     "deps": [
-      "grpc++_codegen_base"
+      "gpr", 
+      "grpc++_codegen_base", 
+      "grpc_base", 
+      "nanopb"
     ], 
     "headers": [
       "include/grpc++/alarm.h", 
@@ -8251,6 +8881,7 @@
       "include/grpc++/grpc++.h", 
       "include/grpc++/health_check_service_interface.h", 
       "include/grpc++/impl/call.h", 
+      "include/grpc++/impl/channel_argument_option.h", 
       "include/grpc++/impl/client_unary_call.h", 
       "include/grpc++/impl/codegen/core_codegen.h", 
       "include/grpc++/impl/grpc_library.h", 
@@ -8307,6 +8938,7 @@
       "include/grpc++/grpc++.h", 
       "include/grpc++/health_check_service_interface.h", 
       "include/grpc++/impl/call.h", 
+      "include/grpc++/impl/channel_argument_option.h", 
       "include/grpc++/impl/client_unary_call.h", 
       "include/grpc++/impl/codegen/core_codegen.h", 
       "include/grpc++/impl/grpc_library.h", 
@@ -8356,6 +8988,7 @@
       "src/cpp/common/rpc_method.cc", 
       "src/cpp/common/version_cc.cc", 
       "src/cpp/server/async_generic_service.cc", 
+      "src/cpp/server/channel_argument_option.cc", 
       "src/cpp/server/create_default_thread_pool.cc", 
       "src/cpp/server/dynamic_thread_pool.cc", 
       "src/cpp/server/dynamic_thread_pool.h", 
@@ -8412,7 +9045,6 @@
       "include/grpc++/impl/codegen/slice.h", 
       "include/grpc++/impl/codegen/status.h", 
       "include/grpc++/impl/codegen/status_code_enum.h", 
-      "include/grpc++/impl/codegen/status_helper.h", 
       "include/grpc++/impl/codegen/string_ref.h", 
       "include/grpc++/impl/codegen/stub_options.h", 
       "include/grpc++/impl/codegen/sync_stream.h", 
@@ -8447,7 +9079,6 @@
       "include/grpc++/impl/codegen/slice.h", 
       "include/grpc++/impl/codegen/status.h", 
       "include/grpc++/impl/codegen/status_code_enum.h", 
-      "include/grpc++/impl/codegen/status_helper.h", 
       "include/grpc++/impl/codegen/string_ref.h", 
       "include/grpc++/impl/codegen/stub_options.h", 
       "include/grpc++/impl/codegen/sync_stream.h", 
@@ -8505,7 +9136,8 @@
     "deps": [], 
     "headers": [
       "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h", 
-      "src/proto/grpc/reflection/v1alpha/reflection.pb.h"
+      "src/proto/grpc/reflection/v1alpha/reflection.pb.h", 
+      "src/proto/grpc/reflection/v1alpha/reflection_mock.grpc.pb.h"
     ], 
     "is_filegroup": true, 
     "language": "c++", 
@@ -8519,33 +9151,17 @@
       "grpc++"
     ], 
     "headers": [
+      "include/grpc++/test/mock_stream.h", 
       "include/grpc++/test/server_context_test_spouse.h"
     ], 
     "is_filegroup": true, 
     "language": "c++", 
     "name": "grpc++_test", 
     "src": [
+      "include/grpc++/test/mock_stream.h", 
       "include/grpc++/test/server_context_test_spouse.h"
     ], 
     "third_party": false, 
     "type": "filegroup"
-  }, 
-  {
-    "deps": [
-      "grpc++_codegen_base"
-    ], 
-    "headers": [
-      "include/grpc++/impl/codegen/thrift_serializer.h", 
-      "include/grpc++/impl/codegen/thrift_utils.h"
-    ], 
-    "is_filegroup": true, 
-    "language": "c++", 
-    "name": "thrift_util", 
-    "src": [
-      "include/grpc++/impl/codegen/thrift_serializer.h", 
-      "include/grpc++/impl/codegen/thrift_utils.h"
-    ], 
-    "third_party": false, 
-    "type": "filegroup"
   }
 ]
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index ab7938d0ca18a4f14977c907cfe544840823e80a..e46b0d1d86bc94c4325adf0ca6e560e6b03a1ce3 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -9,7 +9,7 @@
       "posix", 
       "windows"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -89,6 +89,28 @@
       "windows"
     ]
   }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": false, 
+    "language": "c", 
+    "name": "arena_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
   {
     "args": [], 
     "ci_platforms": [
@@ -341,7 +363,7 @@
       "posix", 
       "windows"
     ], 
-    "cpu_cost": 30, 
+    "cpu_cost": 10, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -385,7 +407,7 @@
       "posix", 
       "windows"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 2.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -515,12 +537,34 @@
       "windows"
     ]
   }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 30, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": false, 
+    "language": "c", 
+    "name": "error_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
   {
     "args": [], 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 3, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -533,6 +577,28 @@
       "linux"
     ]
   }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": false, 
+    "language": "c", 
+    "name": "fake_resolver_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
   {
     "args": [], 
     "ci_platforms": [
@@ -713,7 +779,7 @@
       "posix", 
       "windows"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 30, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -845,7 +911,7 @@
       "posix", 
       "windows"
     ], 
-    "cpu_cost": 10, 
+    "cpu_cost": 3, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -1631,28 +1697,6 @@
       "windows"
     ]
   }, 
-  {
-    "args": [], 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": true, 
-    "gtest": false, 
-    "language": "c", 
-    "name": "mlog_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ]
-  }, 
   {
     "args": [], 
     "ci_platforms": [
@@ -1667,7 +1711,7 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "multiple_server_queues_test", 
+    "name": "minimal_stack_is_minimal_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -1686,32 +1730,10 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
-    "flaky": false, 
-    "gtest": false, 
-    "language": "c", 
-    "name": "murmur_hash_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ]
-  }, 
-  {
-    "args": [], 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ], 
-    "cpu_cost": 0.1, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
+    "flaky": true, 
     "gtest": false, 
     "language": "c", 
-    "name": "no_server_test", 
+    "name": "mlog_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -1733,7 +1755,7 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "percent_encoding_test", 
+    "name": "multiple_server_queues_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -1741,44 +1763,6 @@
       "windows"
     ]
   }, 
-  {
-    "args": [], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
-    "flaky": false, 
-    "gtest": false, 
-    "language": "c", 
-    "name": "pollset_set_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [], 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "gtest": false, 
-    "language": "c", 
-    "name": "resolve_address_posix_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
   {
     "args": [], 
     "ci_platforms": [
@@ -1793,7 +1777,7 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "resolve_address_test", 
+    "name": "murmur_hash_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -1809,13 +1793,13 @@
       "posix", 
       "windows"
     ], 
-    "cpu_cost": 30, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "resource_quota_test", 
+    "name": "no_server_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -1837,7 +1821,7 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "secure_channel_create_test", 
+    "name": "parse_address_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -1855,13 +1839,11 @@
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "secure_endpoint_test", 
+    "name": "percent_encoding_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -1872,10 +1854,7 @@
   {
     "args": [], 
     "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
+      "linux"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
@@ -1885,34 +1864,9 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "sequential_connectivity_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ]
-  }, 
-  {
-    "args": [], 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "gtest": false, 
-    "language": "c", 
-    "name": "server_chttp2_test", 
+    "name": "pollset_set_test", 
     "platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
+      "linux"
     ]
   }, 
   {
@@ -1920,67 +1874,21 @@
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "gtest": false, 
-    "language": "c", 
-    "name": "server_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ]
-  }, 
-  {
-    "args": [], 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ], 
-    "cpu_cost": 0.1, 
-    "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
     ], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "set_initial_connect_string_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ]
-  }, 
-  {
-    "args": [], 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "gtest": false, 
-    "language": "c", 
-    "name": "slice_buffer_test", 
+    "name": "resolve_address_posix_test", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ]
   }, 
   {
@@ -1997,7 +1905,7 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "slice_string_helpers_test", 
+    "name": "resolve_address_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2013,13 +1921,13 @@
       "posix", 
       "windows"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 30, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "slice_test", 
+    "name": "resource_quota_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2041,7 +1949,7 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "sockaddr_resolver_test", 
+    "name": "secure_channel_create_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2059,11 +1967,13 @@
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "sockaddr_utils_test", 
+    "name": "secure_endpoint_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2076,7 +1986,8 @@
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
@@ -2086,11 +1997,12 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "socket_utils_test", 
+    "name": "sequential_connectivity_test", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ]
   }, 
   {
@@ -2107,7 +2019,7 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "status_conversion_test", 
+    "name": "server_chttp2_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2120,21 +2032,21 @@
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ], 
-    "cpu_cost": 0.5, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "tcp_client_posix_test", 
+    "name": "server_test", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ]
   }, 
   {
@@ -2145,15 +2057,13 @@
       "posix", 
       "windows"
     ], 
-    "cpu_cost": 0.5, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "native"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "tcp_client_uv_test", 
+    "name": "slice_buffer_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2166,21 +2076,21 @@
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ], 
-    "cpu_cost": 0.2, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "tcp_posix_test", 
+    "name": "slice_hash_table_test", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ]
   }, 
   {
@@ -2188,21 +2098,21 @@
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "tcp_server_posix_test", 
+    "name": "slice_string_helpers_test", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ]
   }, 
   {
@@ -2215,13 +2125,11 @@
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "native"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "tcp_server_uv_test", 
+    "name": "slice_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2243,7 +2151,7 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "time_averaged_stats_test", 
+    "name": "sockaddr_resolver_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2265,7 +2173,7 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "timeout_encoding_test", 
+    "name": "sockaddr_utils_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2278,8 +2186,7 @@
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
@@ -2289,12 +2196,11 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "timer_heap_test", 
+    "name": "socket_utils_test", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ]
   }, 
   {
@@ -2307,13 +2213,11 @@
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "timer_list_test", 
+    "name": "status_conversion_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2335,7 +2239,7 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "transport_connectivity_state_test", 
+    "name": "stream_owned_slice_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2348,21 +2252,21 @@
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.5, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "transport_metadata_test", 
+    "name": "tcp_client_posix_test", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ]
   }, 
   {
@@ -2373,13 +2277,15 @@
       "posix", 
       "windows"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.5, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "native"
+    ], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "transport_pid_controller_test", 
+    "name": "tcp_client_uv_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2394,13 +2300,15 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.2, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "transport_security_test", 
+    "name": "tcp_posix_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2422,7 +2330,7 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "udp_server_test", 
+    "name": "tcp_server_posix_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2439,11 +2347,13 @@
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "native"
+    ], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "uri_parser_test", 
+    "name": "tcp_server_uv_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2456,21 +2366,21 @@
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "wakeup_fd_cv_test", 
+    "name": "time_averaged_stats_test", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ]
   }, 
   {
@@ -2485,9 +2395,9 @@
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
-    "gtest": true, 
-    "language": "c++", 
-    "name": "alarm_cpp_test", 
+    "gtest": false, 
+    "language": "c", 
+    "name": "timeout_encoding_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2505,11 +2415,13 @@
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
-    "gtest": true, 
-    "language": "c++", 
-    "name": "async_end2end_test", 
+    "gtest": false, 
+    "language": "c", 
+    "name": "timer_heap_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2527,11 +2439,13 @@
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
-    "gtest": true, 
-    "language": "c++", 
-    "name": "auth_property_iterator_test", 
+    "gtest": false, 
+    "language": "c", 
+    "name": "timer_list_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2540,75 +2454,73 @@
     ]
   }, 
   {
-    "args": [
-      "--benchmark_min_time=0"
-    ], 
+    "args": [], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
     "gtest": false, 
-    "language": "c++", 
-    "name": "bm_call_create", 
+    "language": "c", 
+    "name": "transport_connectivity_state_test", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ]
   }, 
   {
-    "args": [
-      "--benchmark_min_time=0"
-    ], 
+    "args": [], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
     "gtest": false, 
-    "language": "c++", 
-    "name": "bm_chttp2_hpack", 
+    "language": "c", 
+    "name": "transport_metadata_test", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ]
   }, 
   {
-    "args": [
-      "--benchmark_min_time=0"
-    ], 
+    "args": [], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
     "gtest": false, 
-    "language": "c++", 
-    "name": "bm_closure", 
+    "language": "c", 
+    "name": "transport_pid_controller_test", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ]
   }, 
   {
-    "args": [
-      "--benchmark_min_time=0"
-    ], 
+    "args": [], 
     "ci_platforms": [
       "linux", 
       "mac", 
@@ -2619,8 +2531,8 @@
     "exclude_iomgrs": [], 
     "flaky": false, 
     "gtest": false, 
-    "language": "c++", 
-    "name": "bm_cq", 
+    "language": "c", 
+    "name": "transport_security_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2628,9 +2540,7 @@
     ]
   }, 
   {
-    "args": [
-      "--benchmark_min_time=0"
-    ], 
+    "args": [], 
     "ci_platforms": [
       "linux", 
       "mac", 
@@ -2638,11 +2548,13 @@
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "gtest": false, 
-    "language": "c++", 
-    "name": "bm_error", 
+    "language": "c", 
+    "name": "udp_server_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2650,36 +2562,29 @@
     ]
   }, 
   {
-    "args": [
-      "--benchmark_min_time=0"
-    ], 
+    "args": [], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix"
+      "posix", 
+      "windows"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
-    "excluded_poll_engines": [
-      "poll", 
-      "poll-cv"
-    ], 
     "flaky": false, 
     "gtest": false, 
-    "language": "c++", 
-    "name": "bm_fullstack", 
+    "language": "c", 
+    "name": "uri_parser_test", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix"
-    ], 
-    "timeout_seconds": 1200
+      "posix", 
+      "windows"
+    ]
   }, 
   {
-    "args": [
-      "--benchmark_min_time=0"
-    ], 
+    "args": [], 
     "ci_platforms": [
       "linux", 
       "mac", 
@@ -2687,11 +2592,13 @@
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "gtest": false, 
-    "language": "c++", 
-    "name": "bm_metadata", 
+    "language": "c", 
+    "name": "wakeup_fd_cv_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2712,7 +2619,7 @@
     "flaky": false, 
     "gtest": true, 
     "language": "c++", 
-    "name": "channel_arguments_test", 
+    "name": "alarm_cpp_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2734,7 +2641,7 @@
     "flaky": false, 
     "gtest": true, 
     "language": "c++", 
-    "name": "channel_filter_test", 
+    "name": "async_end2end_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2756,7 +2663,7 @@
     "flaky": false, 
     "gtest": true, 
     "language": "c++", 
-    "name": "cli_call_test", 
+    "name": "auth_property_iterator_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2765,19 +2672,21 @@
     ]
   }, 
   {
-    "args": [], 
+    "args": [
+      "--benchmark_min_time=0"
+    ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 0.1, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
-    "gtest": true, 
+    "gtest": false, 
     "language": "c++", 
-    "name": "client_crash_test", 
+    "name": "bm_arena", 
     "platforms": [
       "linux", 
       "mac", 
@@ -2785,291 +2694,309 @@
     ]
   }, 
   {
-    "args": [], 
+    "args": [
+      "--benchmark_min_time=0"
+    ], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
-    "gtest": true, 
+    "gtest": false, 
     "language": "c++", 
-    "name": "codegen_test_full", 
+    "name": "bm_call_create", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ]
   }, 
   {
-    "args": [], 
+    "args": [
+      "--benchmark_min_time=0"
+    ], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
-    "gtest": true, 
+    "gtest": false, 
     "language": "c++", 
-    "name": "codegen_test_minimal", 
+    "name": "bm_chttp2_hpack", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ]
   }, 
   {
-    "args": [], 
+    "args": [
+      "--benchmark_min_time=0"
+    ], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
-    "gtest": true, 
+    "gtest": false, 
     "language": "c++", 
-    "name": "credentials_test", 
+    "name": "bm_chttp2_transport", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ]
   }, 
   {
-    "args": [], 
+    "args": [
+      "--benchmark_min_time=0"
+    ], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
-    "gtest": true, 
+    "gtest": false, 
     "language": "c++", 
-    "name": "cxx_byte_buffer_test", 
+    "name": "bm_closure", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ]
   }, 
   {
-    "args": [], 
+    "args": [
+      "--benchmark_min_time=0"
+    ], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
-    "gtest": true, 
+    "gtest": false, 
     "language": "c++", 
-    "name": "cxx_slice_test", 
+    "name": "bm_cq", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ]
   }, 
   {
-    "args": [], 
+    "args": [
+      "--benchmark_min_time=0"
+    ], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
-    "gtest": true, 
+    "gtest": false, 
     "language": "c++", 
-    "name": "cxx_string_ref_test", 
+    "name": "bm_cq_multiple_threads", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ]
   }, 
   {
-    "args": [], 
+    "args": [
+      "--benchmark_min_time=0"
+    ], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
-    "gtest": true, 
+    "gtest": false, 
     "language": "c++", 
-    "name": "cxx_time_test", 
+    "name": "bm_error", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ]
   }, 
   {
-    "args": [], 
+    "args": [
+      "--benchmark_min_time=0"
+    ], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ], 
-    "cpu_cost": 0.5, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
+    "excluded_poll_engines": [
+      "poll", 
+      "poll-cv"
+    ], 
     "flaky": false, 
-    "gtest": true, 
+    "gtest": false, 
     "language": "c++", 
-    "name": "end2end_test", 
+    "name": "bm_fullstack_streaming_ping_pong", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
-    ]
+      "posix"
+    ], 
+    "timeout_seconds": 1200
   }, 
   {
-    "args": [], 
+    "args": [
+      "--benchmark_min_time=0"
+    ], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
+    "excluded_poll_engines": [
+      "poll", 
+      "poll-cv"
+    ], 
     "flaky": false, 
-    "gtest": true, 
+    "gtest": false, 
     "language": "c++", 
-    "name": "filter_end2end_test", 
+    "name": "bm_fullstack_streaming_pump", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
-    ]
+      "posix"
+    ], 
+    "timeout_seconds": 1200
   }, 
   {
-    "args": [], 
+    "args": [
+      "--benchmark_min_time=0"
+    ], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
+    "excluded_poll_engines": [
+      "poll", 
+      "poll-cv"
+    ], 
     "flaky": false, 
-    "gtest": true, 
+    "gtest": false, 
     "language": "c++", 
-    "name": "generic_end2end_test", 
+    "name": "bm_fullstack_trickle", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
-    ]
+      "posix"
+    ], 
+    "timeout_seconds": 1200
   }, 
   {
     "args": [
-      "--generated_file_path=gens/src/proto/grpc/testing/compiler_test.grpc.pb.h"
+      "--benchmark_min_time=0"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
+    "excluded_poll_engines": [
+      "poll", 
+      "poll-cv"
+    ], 
     "flaky": false, 
-    "gtest": true, 
+    "gtest": false, 
     "language": "c++", 
-    "name": "golden_file_test", 
+    "name": "bm_fullstack_unary_ping_pong", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
-    ]
+      "posix"
+    ], 
+    "timeout_seconds": 1200
   }, 
   {
-    "args": [], 
+    "args": [
+      "--benchmark_min_time=0"
+    ], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
-    "gtest": true, 
+    "gtest": false, 
     "language": "c++", 
-    "name": "grpc_tool_test", 
+    "name": "bm_metadata", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ]
   }, 
   {
-    "args": [], 
+    "args": [
+      "--benchmark_min_time=0"
+    ], 
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
-    "gtest": true, 
+    "gtest": false, 
     "language": "c++", 
-    "name": "grpclb_api_test", 
+    "name": "bm_pollset", 
     "platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
+      "posix"
     ]
   }, 
   {
@@ -3084,9 +3011,9 @@
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
-    "gtest": false, 
+    "gtest": true, 
     "language": "c++", 
-    "name": "grpclb_test", 
+    "name": "channel_arguments_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -3108,7 +3035,7 @@
     "flaky": false, 
     "gtest": true, 
     "language": "c++", 
-    "name": "health_service_end2end_test", 
+    "name": "channel_filter_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -3127,10 +3054,10 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
-    "flaky": true, 
-    "gtest": false, 
+    "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
-    "name": "hybrid_end2end_test", 
+    "name": "cli_call_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -3149,9 +3076,9 @@
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
-    "gtest": false, 
+    "gtest": true, 
     "language": "c++", 
-    "name": "interop_test", 
+    "name": "client_crash_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -3172,7 +3099,7 @@
     "flaky": false, 
     "gtest": true, 
     "language": "c++", 
-    "name": "mock_test", 
+    "name": "codegen_test_full", 
     "platforms": [
       "linux", 
       "mac", 
@@ -3192,9 +3119,9 @@
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
-    "gtest": false, 
+    "gtest": true, 
     "language": "c++", 
-    "name": "noop-benchmark", 
+    "name": "codegen_test_minimal", 
     "platforms": [
       "linux", 
       "mac", 
@@ -3216,7 +3143,7 @@
     "flaky": false, 
     "gtest": true, 
     "language": "c++", 
-    "name": "proto_server_reflection_test", 
+    "name": "credentials_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -3238,7 +3165,7 @@
     "flaky": false, 
     "gtest": true, 
     "language": "c++", 
-    "name": "proto_utils_test", 
+    "name": "cxx_byte_buffer_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -3246,26 +3173,6 @@
       "windows"
     ]
   }, 
-  {
-    "args": [], 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 0.5, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "gtest": false, 
-    "language": "c++", 
-    "name": "qps_openloop_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
   {
     "args": [], 
     "ci_platforms": [
@@ -3280,7 +3187,467 @@
     "flaky": false, 
     "gtest": true, 
     "language": "c++", 
-    "name": "round_robin_end2end_test", 
+    "name": "cxx_slice_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "cxx_string_ref_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "cxx_time_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 0.5, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "end2end_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "error_details_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "filter_end2end_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "generic_end2end_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [
+      "--generated_file_path=gens/src/proto/grpc/testing/"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "golden_file_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "grpc_tool_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "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": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "grpclb_end2end_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": false, 
+    "language": "c++", 
+    "name": "grpclb_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "health_service_end2end_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": true, 
+    "gtest": false, 
+    "language": "c++", 
+    "name": "hybrid_end2end_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": false, 
+    "language": "c++", 
+    "name": "interop_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "memory_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "mock_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": false, 
+    "language": "c++", 
+    "name": "noop-benchmark", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "proto_server_reflection_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "proto_utils_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.5, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": false, 
+    "language": "c++", 
+    "name": "qps_openloop_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "round_robin_end2end_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -3352,6 +3719,28 @@
       "windows"
     ]
   }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "server_builder_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
   {
     "args": [], 
     "ci_platforms": [
@@ -5492,7 +5881,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -5513,6 +5902,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "call_creds"
@@ -5569,7 +5981,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -5778,7 +6190,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -5824,7 +6236,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -5847,7 +6259,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -5893,7 +6305,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -5916,7 +6328,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -5985,7 +6397,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -6054,7 +6466,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -6069,7 +6481,7 @@
   }, 
   {
     "args": [
-      "max_message_length"
+      "max_connection_age"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6077,7 +6489,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -6092,7 +6504,7 @@
   }, 
   {
     "args": [
-      "negative_deadline"
+      "max_connection_idle"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6100,9 +6512,11 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
     "name": "h2_census_test", 
@@ -6115,7 +6529,7 @@
   }, 
   {
     "args": [
-      "network_status_change"
+      "max_message_length"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6123,7 +6537,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -6138,7 +6552,7 @@
   }, 
   {
     "args": [
-      "no_logging"
+      "negative_deadline"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6161,7 +6575,7 @@
   }, 
   {
     "args": [
-      "no_op"
+      "network_status_change"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6169,7 +6583,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -6184,7 +6598,7 @@
   }, 
   {
     "args": [
-      "payload"
+      "no_logging"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6207,7 +6621,7 @@
   }, 
   {
     "args": [
-      "ping"
+      "no_op"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6230,7 +6644,7 @@
   }, 
   {
     "args": [
-      "ping_pong_streaming"
+      "payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6253,7 +6667,7 @@
   }, 
   {
     "args": [
-      "registered_call"
+      "ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6261,7 +6675,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -6276,7 +6690,7 @@
   }, 
   {
     "args": [
-      "request_with_flags"
+      "ping_pong_streaming"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6299,7 +6713,7 @@
   }, 
   {
     "args": [
-      "request_with_payload"
+      "registered_call"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6322,7 +6736,7 @@
   }, 
   {
     "args": [
-      "resource_quota_server"
+      "request_with_flags"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6330,7 +6744,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -6345,7 +6759,7 @@
   }, 
   {
     "args": [
-      "server_finishes_request"
+      "request_with_payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6353,7 +6767,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -6368,7 +6782,7 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_calls"
+      "resource_quota_server"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6391,7 +6805,7 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_tags"
+      "server_finishes_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6399,7 +6813,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -6414,7 +6828,7 @@
   }, 
   {
     "args": [
-      "simple_cacheable_request"
+      "shutdown_finishes_calls"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6422,7 +6836,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -6437,7 +6851,7 @@
   }, 
   {
     "args": [
-      "simple_delayed_request"
+      "shutdown_finishes_tags"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6445,7 +6859,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -6460,7 +6874,7 @@
   }, 
   {
     "args": [
-      "simple_metadata"
+      "simple_cacheable_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6468,7 +6882,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -6483,7 +6897,7 @@
   }, 
   {
     "args": [
-      "simple_request"
+      "simple_delayed_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6506,7 +6920,7 @@
   }, 
   {
     "args": [
-      "streaming_error_response"
+      "simple_metadata"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6529,7 +6943,7 @@
   }, 
   {
     "args": [
-      "trailing_metadata"
+      "simple_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6552,7 +6966,7 @@
   }, 
   {
     "args": [
-      "write_buffering"
+      "streaming_error_response"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6560,7 +6974,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -6575,7 +6989,7 @@
   }, 
   {
     "args": [
-      "write_buffering_at_end"
+      "trailing_metadata"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6598,7 +7012,7 @@
   }, 
   {
     "args": [
-      "authority_not_supported"
+      "write_buffering"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6606,12 +7020,12 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_compress_test", 
+    "name": "h2_census_test", 
     "platforms": [
       "windows", 
       "linux", 
@@ -6621,7 +7035,7 @@
   }, 
   {
     "args": [
-      "bad_hostname"
+      "write_buffering_at_end"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6629,12 +7043,12 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_compress_test", 
+    "name": "h2_census_test", 
     "platforms": [
       "windows", 
       "linux", 
@@ -6644,7 +7058,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "authority_not_supported"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6667,7 +7081,7 @@
   }, 
   {
     "args": [
-      "call_creds"
+      "bad_hostname"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6690,30 +7104,7 @@
   }, 
   {
     "args": [
-      "cancel_after_accept"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 0.1, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_compress_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "cancel_after_client_done"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6736,7 +7127,7 @@
   }, 
   {
     "args": [
-      "cancel_after_invoke"
+      "binary_metadata"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6759,7 +7150,7 @@
   }, 
   {
     "args": [
-      "cancel_before_invoke"
+      "call_creds"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6767,7 +7158,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 0.1, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -6782,7 +7173,7 @@
   }, 
   {
     "args": [
-      "cancel_in_a_vacuum"
+      "cancel_after_accept"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6805,7 +7196,7 @@
   }, 
   {
     "args": [
-      "cancel_with_status"
+      "cancel_after_client_done"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6828,7 +7219,7 @@
   }, 
   {
     "args": [
-      "compressed_payload"
+      "cancel_after_invoke"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6836,7 +7227,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -6851,7 +7242,7 @@
   }, 
   {
     "args": [
-      "connectivity"
+      "cancel_before_invoke"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6861,9 +7252,7 @@
     ], 
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "h2_compress_test", 
@@ -6876,7 +7265,7 @@
   }, 
   {
     "args": [
-      "default_host"
+      "cancel_in_a_vacuum"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6884,7 +7273,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -6899,7 +7288,7 @@
   }, 
   {
     "args": [
-      "disappearing_server"
+      "cancel_with_status"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6907,10 +7296,10 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
-    "flaky": true, 
+    "flaky": false, 
     "language": "c", 
     "name": "h2_compress_test", 
     "platforms": [
@@ -6922,7 +7311,7 @@
   }, 
   {
     "args": [
-      "empty_batch"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6945,7 +7334,7 @@
   }, 
   {
     "args": [
-      "filter_call_init_fails"
+      "connectivity"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6953,9 +7342,11 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
     "name": "h2_compress_test", 
@@ -6968,7 +7359,7 @@
   }, 
   {
     "args": [
-      "filter_causes_close"
+      "default_host"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6991,7 +7382,7 @@
   }, 
   {
     "args": [
-      "filter_latency"
+      "disappearing_server"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7002,7 +7393,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
-    "flaky": false, 
+    "flaky": true, 
     "language": "c", 
     "name": "h2_compress_test", 
     "platforms": [
@@ -7014,7 +7405,7 @@
   }, 
   {
     "args": [
-      "graceful_server_shutdown"
+      "empty_batch"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7037,30 +7428,7 @@
   }, 
   {
     "args": [
-      "high_initial_seqno"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_compress_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "hpack_size"
+      "filter_call_init_fails"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7083,7 +7451,7 @@
   }, 
   {
     "args": [
-      "idempotent_request"
+      "filter_causes_close"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7091,7 +7459,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7106,7 +7474,7 @@
   }, 
   {
     "args": [
-      "invoke_large_request"
+      "filter_latency"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7114,7 +7482,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7129,7 +7497,7 @@
   }, 
   {
     "args": [
-      "keepalive_timeout"
+      "graceful_server_shutdown"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7137,7 +7505,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7152,7 +7520,7 @@
   }, 
   {
     "args": [
-      "large_metadata"
+      "high_initial_seqno"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7160,7 +7528,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7175,7 +7543,7 @@
   }, 
   {
     "args": [
-      "load_reporting_hook"
+      "hpack_size"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7183,7 +7551,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7198,7 +7566,7 @@
   }, 
   {
     "args": [
-      "max_concurrent_streams"
+      "idempotent_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7221,7 +7589,7 @@
   }, 
   {
     "args": [
-      "max_message_length"
+      "invoke_large_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7244,7 +7612,7 @@
   }, 
   {
     "args": [
-      "negative_deadline"
+      "keepalive_timeout"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7252,7 +7620,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7267,7 +7635,7 @@
   }, 
   {
     "args": [
-      "network_status_change"
+      "large_metadata"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7290,7 +7658,7 @@
   }, 
   {
     "args": [
-      "no_logging"
+      "load_reporting_hook"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7313,7 +7681,7 @@
   }, 
   {
     "args": [
-      "no_op"
+      "max_concurrent_streams"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7321,7 +7689,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7336,7 +7704,7 @@
   }, 
   {
     "args": [
-      "payload"
+      "max_connection_age"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7344,7 +7712,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7359,7 +7727,7 @@
   }, 
   {
     "args": [
-      "ping"
+      "max_connection_idle"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7367,9 +7735,11 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
     "name": "h2_compress_test", 
@@ -7382,7 +7752,7 @@
   }, 
   {
     "args": [
-      "ping_pong_streaming"
+      "max_message_length"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7390,7 +7760,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7405,7 +7775,7 @@
   }, 
   {
     "args": [
-      "registered_call"
+      "negative_deadline"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7428,7 +7798,7 @@
   }, 
   {
     "args": [
-      "request_with_flags"
+      "network_status_change"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7451,7 +7821,7 @@
   }, 
   {
     "args": [
-      "request_with_payload"
+      "no_logging"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7474,7 +7844,7 @@
   }, 
   {
     "args": [
-      "resource_quota_server"
+      "no_op"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7497,7 +7867,7 @@
   }, 
   {
     "args": [
-      "server_finishes_request"
+      "payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7520,7 +7890,7 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_calls"
+      "ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7528,7 +7898,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7543,7 +7913,7 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_tags"
+      "ping_pong_streaming"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7551,7 +7921,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7566,7 +7936,7 @@
   }, 
   {
     "args": [
-      "simple_cacheable_request"
+      "registered_call"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7589,7 +7959,7 @@
   }, 
   {
     "args": [
-      "simple_delayed_request"
+      "request_with_flags"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7597,7 +7967,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7612,7 +7982,7 @@
   }, 
   {
     "args": [
-      "simple_metadata"
+      "request_with_payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7620,7 +7990,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7635,7 +8005,7 @@
   }, 
   {
     "args": [
-      "simple_request"
+      "server_finishes_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7643,7 +8013,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7658,7 +8028,7 @@
   }, 
   {
     "args": [
-      "streaming_error_response"
+      "shutdown_finishes_calls"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7666,7 +8036,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7681,7 +8051,7 @@
   }, 
   {
     "args": [
-      "trailing_metadata"
+      "shutdown_finishes_tags"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7689,7 +8059,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7704,7 +8074,7 @@
   }, 
   {
     "args": [
-      "write_buffering"
+      "simple_cacheable_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7712,7 +8082,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7727,7 +8097,7 @@
   }, 
   {
     "args": [
-      "write_buffering_at_end"
+      "simple_delayed_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7750,41 +8120,20 @@
   }, 
   {
     "args": [
-      "authority_not_supported"
+      "simple_metadata"
     ], 
     "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_fakesec_test", 
-    "platforms": [
       "windows", 
       "linux", 
       "mac", 
       "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "bad_hostname"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_fakesec_test", 
+    "name": "h2_compress_test", 
     "platforms": [
       "windows", 
       "linux", 
@@ -7794,41 +8143,20 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "simple_request"
     ], 
     "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_fakesec_test", 
-    "platforms": [
       "windows", 
       "linux", 
       "mac", 
       "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "call_creds"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_fakesec_test", 
+    "name": "h2_compress_test", 
     "platforms": [
       "windows", 
       "linux", 
@@ -7838,11 +8166,12 @@
   }, 
   {
     "args": [
-      "cancel_after_accept"
+      "streaming_error_response"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
+      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -7850,7 +8179,7 @@
     "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_fakesec_test", 
+    "name": "h2_compress_test", 
     "platforms": [
       "windows", 
       "linux", 
@@ -7860,11 +8189,12 @@
   }, 
   {
     "args": [
-      "cancel_after_client_done"
+      "trailing_metadata"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
+      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -7872,7 +8202,7 @@
     "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_fakesec_test", 
+    "name": "h2_compress_test", 
     "platforms": [
       "windows", 
       "linux", 
@@ -7882,11 +8212,12 @@
   }, 
   {
     "args": [
-      "cancel_after_invoke"
+      "write_buffering"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
+      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -7894,7 +8225,7 @@
     "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_fakesec_test", 
+    "name": "h2_compress_test", 
     "platforms": [
       "windows", 
       "linux", 
@@ -7904,11 +8235,12 @@
   }, 
   {
     "args": [
-      "cancel_before_invoke"
+      "write_buffering_at_end"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
+      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -7916,7 +8248,7 @@
     "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_fakesec_test", 
+    "name": "h2_compress_test", 
     "platforms": [
       "windows", 
       "linux", 
@@ -7926,14 +8258,14 @@
   }, 
   {
     "args": [
-      "cancel_in_a_vacuum"
+      "authority_not_supported"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 0.1, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7948,14 +8280,14 @@
   }, 
   {
     "args": [
-      "cancel_with_status"
+      "bad_hostname"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 0.1, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -7970,7 +8302,7 @@
   }, 
   {
     "args": [
-      "compressed_payload"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -7992,7 +8324,7 @@
   }, 
   {
     "args": [
-      "connectivity"
+      "binary_metadata"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8001,9 +8333,7 @@
     ], 
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "h2_fakesec_test", 
@@ -8016,7 +8346,7 @@
   }, 
   {
     "args": [
-      "default_host"
+      "call_creds"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8038,17 +8368,17 @@
   }, 
   {
     "args": [
-      "disappearing_server"
+      "cancel_after_accept"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
-    "flaky": true, 
+    "flaky": false, 
     "language": "c", 
     "name": "h2_fakesec_test", 
     "platforms": [
@@ -8060,14 +8390,14 @@
   }, 
   {
     "args": [
-      "empty_batch"
+      "cancel_after_client_done"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8082,14 +8412,14 @@
   }, 
   {
     "args": [
-      "filter_call_init_fails"
+      "cancel_after_invoke"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8104,14 +8434,14 @@
   }, 
   {
     "args": [
-      "filter_causes_close"
+      "cancel_before_invoke"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8126,14 +8456,14 @@
   }, 
   {
     "args": [
-      "filter_latency"
+      "cancel_in_a_vacuum"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8148,7 +8478,7 @@
   }, 
   {
     "args": [
-      "graceful_server_shutdown"
+      "cancel_with_status"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8170,7 +8500,7 @@
   }, 
   {
     "args": [
-      "high_initial_seqno"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8192,16 +8522,18 @@
   }, 
   {
     "args": [
-      "hpack_size"
+      "connectivity"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
     "name": "h2_fakesec_test", 
@@ -8214,7 +8546,7 @@
   }, 
   {
     "args": [
-      "idempotent_request"
+      "default_host"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8236,7 +8568,7 @@
   }, 
   {
     "args": [
-      "invoke_large_request"
+      "disappearing_server"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8246,7 +8578,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
-    "flaky": false, 
+    "flaky": true, 
     "language": "c", 
     "name": "h2_fakesec_test", 
     "platforms": [
@@ -8258,14 +8590,14 @@
   }, 
   {
     "args": [
-      "keepalive_timeout"
+      "empty_batch"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8280,7 +8612,7 @@
   }, 
   {
     "args": [
-      "large_metadata"
+      "filter_call_init_fails"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8302,14 +8634,14 @@
   }, 
   {
     "args": [
-      "load_reporting_hook"
+      "filter_causes_close"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8324,14 +8656,14 @@
   }, 
   {
     "args": [
-      "max_concurrent_streams"
+      "filter_latency"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8346,14 +8678,14 @@
   }, 
   {
     "args": [
-      "max_message_length"
+      "graceful_server_shutdown"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8368,14 +8700,14 @@
   }, 
   {
     "args": [
-      "negative_deadline"
+      "high_initial_seqno"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8390,14 +8722,14 @@
   }, 
   {
     "args": [
-      "network_status_change"
+      "hpack_size"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8412,7 +8744,7 @@
   }, 
   {
     "args": [
-      "no_logging"
+      "idempotent_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8434,7 +8766,7 @@
   }, 
   {
     "args": [
-      "no_op"
+      "invoke_large_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8456,14 +8788,14 @@
   }, 
   {
     "args": [
-      "payload"
+      "keepalive_timeout"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8478,7 +8810,7 @@
   }, 
   {
     "args": [
-      "ping"
+      "large_metadata"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8500,7 +8832,7 @@
   }, 
   {
     "args": [
-      "ping_pong_streaming"
+      "load_reporting_hook"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8522,14 +8854,14 @@
   }, 
   {
     "args": [
-      "registered_call"
+      "max_concurrent_streams"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8544,7 +8876,7 @@
   }, 
   {
     "args": [
-      "request_with_flags"
+      "max_connection_age"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8566,16 +8898,18 @@
   }, 
   {
     "args": [
-      "request_with_payload"
+      "max_connection_idle"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
     "name": "h2_fakesec_test", 
@@ -8588,14 +8922,14 @@
   }, 
   {
     "args": [
-      "resource_quota_server"
+      "max_message_length"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8610,7 +8944,7 @@
   }, 
   {
     "args": [
-      "server_finishes_request"
+      "negative_deadline"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8632,14 +8966,14 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_calls"
+      "network_status_change"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8654,7 +8988,7 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_tags"
+      "no_logging"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8676,7 +9010,7 @@
   }, 
   {
     "args": [
-      "simple_cacheable_request"
+      "no_op"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8698,7 +9032,7 @@
   }, 
   {
     "args": [
-      "simple_delayed_request"
+      "payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8720,14 +9054,14 @@
   }, 
   {
     "args": [
-      "simple_metadata"
+      "ping"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8742,14 +9076,14 @@
   }, 
   {
     "args": [
-      "simple_request"
+      "ping_pong_streaming"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8764,7 +9098,7 @@
   }, 
   {
     "args": [
-      "streaming_error_response"
+      "registered_call"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8786,14 +9120,14 @@
   }, 
   {
     "args": [
-      "trailing_metadata"
+      "request_with_flags"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8808,14 +9142,14 @@
   }, 
   {
     "args": [
-      "write_buffering"
+      "request_with_payload"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -8830,7 +9164,7 @@
   }, 
   {
     "args": [
-      "write_buffering_at_end"
+      "resource_quota_server"
     ], 
     "ci_platforms": [
       "windows", 
@@ -8852,22 +9186,21 @@
   }, 
   {
     "args": [
-      "authority_not_supported"
+      "server_finishes_request"
     ], 
     "ci_platforms": [
+      "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_fd_test", 
+    "name": "h2_fakesec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -8875,22 +9208,21 @@
   }, 
   {
     "args": [
-      "bad_hostname"
+      "shutdown_finishes_calls"
     ], 
     "ci_platforms": [
+      "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_fd_test", 
+    "name": "h2_fakesec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -8898,22 +9230,21 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "shutdown_finishes_tags"
     ], 
     "ci_platforms": [
+      "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_fd_test", 
+    "name": "h2_fakesec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -8921,22 +9252,43 @@
   }, 
   {
     "args": [
-      "call_creds"
+      "simple_cacheable_request"
     ], 
     "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fakesec_test", 
+    "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_delayed_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_fd_test", 
+    "name": "h2_fakesec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -8944,22 +9296,21 @@
   }, 
   {
     "args": [
-      "cancel_after_accept"
+      "simple_metadata"
     ], 
     "ci_platforms": [
+      "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
-    "cpu_cost": 0.1, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_fd_test", 
+    "name": "h2_fakesec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -8967,22 +9318,21 @@
   }, 
   {
     "args": [
-      "cancel_after_client_done"
+      "simple_request"
     ], 
     "ci_platforms": [
+      "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_fd_test", 
+    "name": "h2_fakesec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -8990,22 +9340,21 @@
   }, 
   {
     "args": [
-      "cancel_after_invoke"
+      "streaming_error_response"
     ], 
     "ci_platforms": [
+      "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_fd_test", 
+    "name": "h2_fakesec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -9013,22 +9362,21 @@
   }, 
   {
     "args": [
-      "cancel_before_invoke"
+      "trailing_metadata"
     ], 
     "ci_platforms": [
+      "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
-    "cpu_cost": 0.1, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_fd_test", 
+    "name": "h2_fakesec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -9036,22 +9384,21 @@
   }, 
   {
     "args": [
-      "cancel_in_a_vacuum"
+      "write_buffering"
     ], 
     "ci_platforms": [
+      "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_fd_test", 
+    "name": "h2_fakesec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -9059,22 +9406,21 @@
   }, 
   {
     "args": [
-      "cancel_with_status"
+      "write_buffering_at_end"
     ], 
     "ci_platforms": [
+      "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_fd_test", 
+    "name": "h2_fakesec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -9082,7 +9428,7 @@
   }, 
   {
     "args": [
-      "compressed_payload"
+      "authority_not_supported"
     ], 
     "ci_platforms": [
       "linux", 
@@ -9105,7 +9451,7 @@
   }, 
   {
     "args": [
-      "empty_batch"
+      "bad_hostname"
     ], 
     "ci_platforms": [
       "linux", 
@@ -9128,14 +9474,14 @@
   }, 
   {
     "args": [
-      "filter_call_init_fails"
+      "binary_metadata"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9151,7 +9497,7 @@
   }, 
   {
     "args": [
-      "filter_causes_close"
+      "call_creds"
     ], 
     "ci_platforms": [
       "linux", 
@@ -9174,14 +9520,14 @@
   }, 
   {
     "args": [
-      "filter_latency"
+      "cancel_after_accept"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9197,7 +9543,7 @@
   }, 
   {
     "args": [
-      "graceful_server_shutdown"
+      "cancel_after_client_done"
     ], 
     "ci_platforms": [
       "linux", 
@@ -9220,14 +9566,14 @@
   }, 
   {
     "args": [
-      "high_initial_seqno"
+      "cancel_after_invoke"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9243,14 +9589,14 @@
   }, 
   {
     "args": [
-      "hpack_size"
+      "cancel_before_invoke"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9266,14 +9612,14 @@
   }, 
   {
     "args": [
-      "idempotent_request"
+      "cancel_in_a_vacuum"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9289,14 +9635,14 @@
   }, 
   {
     "args": [
-      "invoke_large_request"
+      "cancel_with_status"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9312,7 +9658,7 @@
   }, 
   {
     "args": [
-      "keepalive_timeout"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "linux", 
@@ -9335,14 +9681,14 @@
   }, 
   {
     "args": [
-      "large_metadata"
+      "empty_batch"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9358,7 +9704,7 @@
   }, 
   {
     "args": [
-      "load_reporting_hook"
+      "filter_call_init_fails"
     ], 
     "ci_platforms": [
       "linux", 
@@ -9381,14 +9727,14 @@
   }, 
   {
     "args": [
-      "max_concurrent_streams"
+      "filter_causes_close"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9404,14 +9750,14 @@
   }, 
   {
     "args": [
-      "max_message_length"
+      "filter_latency"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9427,14 +9773,14 @@
   }, 
   {
     "args": [
-      "negative_deadline"
+      "graceful_server_shutdown"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9450,14 +9796,14 @@
   }, 
   {
     "args": [
-      "network_status_change"
+      "high_initial_seqno"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9473,14 +9819,14 @@
   }, 
   {
     "args": [
-      "no_logging"
+      "hpack_size"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9496,7 +9842,7 @@
   }, 
   {
     "args": [
-      "no_op"
+      "idempotent_request"
     ], 
     "ci_platforms": [
       "linux", 
@@ -9519,7 +9865,7 @@
   }, 
   {
     "args": [
-      "payload"
+      "invoke_large_request"
     ], 
     "ci_platforms": [
       "linux", 
@@ -9542,14 +9888,14 @@
   }, 
   {
     "args": [
-      "ping_pong_streaming"
+      "keepalive_timeout"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9565,7 +9911,7 @@
   }, 
   {
     "args": [
-      "registered_call"
+      "large_metadata"
     ], 
     "ci_platforms": [
       "linux", 
@@ -9588,14 +9934,14 @@
   }, 
   {
     "args": [
-      "request_with_flags"
+      "load_reporting_hook"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 0.1, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9611,14 +9957,14 @@
   }, 
   {
     "args": [
-      "request_with_payload"
+      "max_concurrent_streams"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9634,14 +9980,14 @@
   }, 
   {
     "args": [
-      "resource_quota_server"
+      "max_connection_age"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9657,14 +10003,14 @@
   }, 
   {
     "args": [
-      "server_finishes_request"
+      "max_message_length"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9680,7 +10026,7 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_calls"
+      "negative_deadline"
     ], 
     "ci_platforms": [
       "linux", 
@@ -9703,14 +10049,14 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_tags"
+      "network_status_change"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9726,7 +10072,7 @@
   }, 
   {
     "args": [
-      "simple_cacheable_request"
+      "no_logging"
     ], 
     "ci_platforms": [
       "linux", 
@@ -9749,7 +10095,7 @@
   }, 
   {
     "args": [
-      "simple_metadata"
+      "no_op"
     ], 
     "ci_platforms": [
       "linux", 
@@ -9772,7 +10118,7 @@
   }, 
   {
     "args": [
-      "simple_request"
+      "payload"
     ], 
     "ci_platforms": [
       "linux", 
@@ -9795,14 +10141,14 @@
   }, 
   {
     "args": [
-      "streaming_error_response"
+      "ping_pong_streaming"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9818,7 +10164,7 @@
   }, 
   {
     "args": [
-      "trailing_metadata"
+      "registered_call"
     ], 
     "ci_platforms": [
       "linux", 
@@ -9841,14 +10187,14 @@
   }, 
   {
     "args": [
-      "write_buffering"
+      "request_with_flags"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9864,14 +10210,14 @@
   }, 
   {
     "args": [
-      "write_buffering_at_end"
+      "request_with_payload"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -9887,22 +10233,22 @@
   }, 
   {
     "args": [
-      "authority_not_supported"
+      "resource_quota_server"
     ], 
     "ci_platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_full_test", 
+    "name": "h2_fd_test", 
     "platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -9910,22 +10256,22 @@
   }, 
   {
     "args": [
-      "bad_hostname"
+      "server_finishes_request"
     ], 
     "ci_platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_full_test", 
+    "name": "h2_fd_test", 
     "platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -9933,22 +10279,22 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "shutdown_finishes_calls"
     ], 
     "ci_platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_full_test", 
+    "name": "h2_fd_test", 
     "platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -9956,22 +10302,22 @@
   }, 
   {
     "args": [
-      "call_creds"
+      "shutdown_finishes_tags"
     ], 
     "ci_platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_full_test", 
+    "name": "h2_fd_test", 
     "platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -9979,22 +10325,22 @@
   }, 
   {
     "args": [
-      "cancel_after_accept"
+      "simple_cacheable_request"
     ], 
     "ci_platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_full_test", 
+    "name": "h2_fd_test", 
     "platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -10002,22 +10348,22 @@
   }, 
   {
     "args": [
-      "cancel_after_client_done"
+      "simple_metadata"
     ], 
     "ci_platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_full_test", 
+    "name": "h2_fd_test", 
     "platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -10025,22 +10371,22 @@
   }, 
   {
     "args": [
-      "cancel_after_invoke"
+      "simple_request"
     ], 
     "ci_platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 0.1, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_full_test", 
+    "name": "h2_fd_test", 
     "platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -10048,22 +10394,22 @@
   }, 
   {
     "args": [
-      "cancel_before_invoke"
+      "streaming_error_response"
     ], 
     "ci_platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_full_test", 
+    "name": "h2_fd_test", 
     "platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -10071,22 +10417,22 @@
   }, 
   {
     "args": [
-      "cancel_in_a_vacuum"
+      "trailing_metadata"
     ], 
     "ci_platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 0.1, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_full_test", 
+    "name": "h2_fd_test", 
     "platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -10094,45 +10440,22 @@
   }, 
   {
     "args": [
-      "cancel_with_status"
+      "write_buffering"
     ], 
     "ci_platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
+    "exclude_iomgrs": [
+      "uv"
     ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_full_test", 
+    "name": "h2_fd_test", 
     "platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -10140,10 +10463,9 @@
   }, 
   {
     "args": [
-      "connectivity"
+      "write_buffering_at_end"
     ], 
     "ci_platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -10155,9 +10477,8 @@
     ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_full_test", 
+    "name": "h2_fd_test", 
     "platforms": [
-      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -10165,7 +10486,7 @@
   }, 
   {
     "args": [
-      "default_host"
+      "authority_not_supported"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10188,7 +10509,7 @@
   }, 
   {
     "args": [
-      "disappearing_server"
+      "bad_hostname"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10199,7 +10520,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
-    "flaky": true, 
+    "flaky": false, 
     "language": "c", 
     "name": "h2_full_test", 
     "platforms": [
@@ -10211,7 +10532,7 @@
   }, 
   {
     "args": [
-      "empty_batch"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10234,7 +10555,7 @@
   }, 
   {
     "args": [
-      "filter_call_init_fails"
+      "binary_metadata"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10242,7 +10563,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -10257,7 +10578,7 @@
   }, 
   {
     "args": [
-      "filter_causes_close"
+      "call_creds"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10280,7 +10601,7 @@
   }, 
   {
     "args": [
-      "filter_latency"
+      "cancel_after_accept"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10288,7 +10609,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -10303,7 +10624,7 @@
   }, 
   {
     "args": [
-      "graceful_server_shutdown"
+      "cancel_after_client_done"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10326,7 +10647,7 @@
   }, 
   {
     "args": [
-      "high_initial_seqno"
+      "cancel_after_invoke"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10334,7 +10655,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -10349,7 +10670,7 @@
   }, 
   {
     "args": [
-      "hpack_size"
+      "cancel_before_invoke"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10357,7 +10678,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -10372,7 +10693,7 @@
   }, 
   {
     "args": [
-      "idempotent_request"
+      "cancel_in_a_vacuum"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10380,7 +10701,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -10395,7 +10716,7 @@
   }, 
   {
     "args": [
-      "invoke_large_request"
+      "cancel_with_status"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10403,7 +10724,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -10418,7 +10739,7 @@
   }, 
   {
     "args": [
-      "keepalive_timeout"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10441,7 +10762,7 @@
   }, 
   {
     "args": [
-      "large_metadata"
+      "connectivity"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10449,9 +10770,11 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
     "name": "h2_full_test", 
@@ -10464,7 +10787,7 @@
   }, 
   {
     "args": [
-      "load_reporting_hook"
+      "default_host"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10487,7 +10810,7 @@
   }, 
   {
     "args": [
-      "max_concurrent_streams"
+      "disappearing_server"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10498,7 +10821,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
-    "flaky": false, 
+    "flaky": true, 
     "language": "c", 
     "name": "h2_full_test", 
     "platforms": [
@@ -10510,7 +10833,7 @@
   }, 
   {
     "args": [
-      "max_message_length"
+      "empty_batch"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10518,7 +10841,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -10533,7 +10856,7 @@
   }, 
   {
     "args": [
-      "negative_deadline"
+      "filter_call_init_fails"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10556,7 +10879,7 @@
   }, 
   {
     "args": [
-      "network_status_change"
+      "filter_causes_close"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10564,7 +10887,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -10579,7 +10902,7 @@
   }, 
   {
     "args": [
-      "no_logging"
+      "filter_latency"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10587,7 +10910,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -10602,7 +10925,7 @@
   }, 
   {
     "args": [
-      "no_op"
+      "graceful_server_shutdown"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10610,7 +10933,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -10625,7 +10948,7 @@
   }, 
   {
     "args": [
-      "payload"
+      "high_initial_seqno"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10633,7 +10956,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -10648,7 +10971,7 @@
   }, 
   {
     "args": [
-      "ping"
+      "hpack_size"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10656,7 +10979,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -10671,7 +10994,7 @@
   }, 
   {
     "args": [
-      "ping_pong_streaming"
+      "idempotent_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10694,7 +11017,7 @@
   }, 
   {
     "args": [
-      "registered_call"
+      "invoke_large_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10717,7 +11040,7 @@
   }, 
   {
     "args": [
-      "request_with_flags"
+      "keepalive_timeout"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10740,7 +11063,7 @@
   }, 
   {
     "args": [
-      "request_with_payload"
+      "large_metadata"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10763,7 +11086,7 @@
   }, 
   {
     "args": [
-      "resource_quota_server"
+      "load_reporting_hook"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10786,7 +11109,7 @@
   }, 
   {
     "args": [
-      "server_finishes_request"
+      "max_concurrent_streams"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10794,7 +11117,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -10809,7 +11132,7 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_calls"
+      "max_connection_age"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10817,7 +11140,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -10832,7 +11155,7 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_tags"
+      "max_connection_idle"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10840,9 +11163,11 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
     "name": "h2_full_test", 
@@ -10855,7 +11180,7 @@
   }, 
   {
     "args": [
-      "simple_cacheable_request"
+      "max_message_length"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10863,7 +11188,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -10878,7 +11203,352 @@
   }, 
   {
     "args": [
-      "simple_delayed_request"
+      "negative_deadline"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "network_status_change"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "no_logging"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "no_op"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "ping_pong_streaming"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "registered_call"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_flags"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "resource_quota_server"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "server_finishes_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "shutdown_finishes_calls"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "shutdown_finishes_tags"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_delayed_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -10955,7 +11625,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -11001,7 +11671,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -11024,7 +11694,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -11077,7 +11747,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "linux"
@@ -11094,6 +11764,25 @@
       "linux"
     ]
   }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
   {
     "args": [
       "call_creds"
@@ -11139,7 +11828,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11310,7 +11999,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11348,7 +12037,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11367,7 +12056,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11405,7 +12094,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11424,7 +12113,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11481,7 +12170,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11538,7 +12227,45 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_idle"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11557,7 +12284,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11595,7 +12322,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11671,7 +12398,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11690,7 +12417,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11747,7 +12474,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11785,7 +12512,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11804,7 +12531,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11823,7 +12550,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11842,7 +12569,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11918,7 +12645,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11956,7 +12683,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -11975,7 +12702,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -12035,7 +12762,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -12056,6 +12783,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "call_creds"
@@ -12112,7 +12862,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -12321,7 +13071,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -12367,7 +13117,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -12390,7 +13140,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -12436,7 +13186,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -12505,7 +13255,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -12574,7 +13324,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -12587,6 +13337,54 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_idle"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "max_message_length"
@@ -12597,7 +13395,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -12643,7 +13441,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -12712,7 +13510,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -12735,7 +13533,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -12804,7 +13602,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -12850,7 +13648,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -12873,7 +13671,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -12896,7 +13694,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -12919,7 +13717,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -13011,7 +13809,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -13057,7 +13855,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -13080,7 +13878,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -13143,7 +13941,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -13165,6 +13963,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_http_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "call_creds"
@@ -13222,7 +14044,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -13438,7 +14260,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -13486,7 +14308,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -13510,7 +14332,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -13558,7 +14380,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -13582,7 +14404,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -13654,7 +14476,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -13726,7 +14548,55 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_http_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_http_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_idle"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -13750,7 +14620,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -13798,7 +14668,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -13894,7 +14764,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -13918,7 +14788,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -13990,7 +14860,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -14038,7 +14908,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -14062,7 +14932,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -14086,7 +14956,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -14110,7 +14980,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -14206,7 +15076,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -14254,7 +15124,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -14278,7 +15148,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -14341,7 +15211,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -14362,6 +15232,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_load_reporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "call_creds"
@@ -14418,7 +15311,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -14627,7 +15520,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -14673,7 +15566,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -14696,7 +15589,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -14742,7 +15635,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -14765,7 +15658,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -14834,7 +15727,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -14903,7 +15796,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -14916,6 +15809,54 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_load_reporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_idle"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_load_reporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "max_message_length"
@@ -14926,7 +15867,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -14972,7 +15913,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -15064,7 +16005,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -15087,7 +16028,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -15156,7 +16097,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -15202,7 +16143,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -15225,7 +16166,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -15248,7 +16189,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -15271,7 +16212,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -15363,7 +16304,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -15409,7 +16350,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -15432,7 +16373,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -15495,7 +16436,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -15517,6 +16458,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_oauth2_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "call_creds"
@@ -15574,7 +16539,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -15790,7 +16755,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -15838,7 +16803,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -15862,7 +16827,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -15910,7 +16875,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -15934,7 +16899,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16006,7 +16971,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16078,7 +17043,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16095,14 +17060,14 @@
   }, 
   {
     "args": [
-      "max_message_length"
+      "max_connection_age"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16119,14 +17084,14 @@
   }, 
   {
     "args": [
-      "negative_deadline"
+      "max_connection_idle"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16143,14 +17108,14 @@
   }, 
   {
     "args": [
-      "network_status_change"
+      "max_message_length"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16167,7 +17132,7 @@
   }, 
   {
     "args": [
-      "no_logging"
+      "negative_deadline"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16191,14 +17156,14 @@
   }, 
   {
     "args": [
-      "no_op"
+      "network_status_change"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16215,7 +17180,7 @@
   }, 
   {
     "args": [
-      "payload"
+      "no_logging"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16239,7 +17204,7 @@
   }, 
   {
     "args": [
-      "ping"
+      "no_op"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16263,7 +17228,7 @@
   }, 
   {
     "args": [
-      "ping_pong_streaming"
+      "payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16287,14 +17252,14 @@
   }, 
   {
     "args": [
-      "registered_call"
+      "ping"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16311,7 +17276,7 @@
   }, 
   {
     "args": [
-      "request_with_flags"
+      "ping_pong_streaming"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16335,7 +17300,7 @@
   }, 
   {
     "args": [
-      "request_with_payload"
+      "registered_call"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16359,14 +17324,14 @@
   }, 
   {
     "args": [
-      "resource_quota_server"
+      "request_with_flags"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16383,14 +17348,14 @@
   }, 
   {
     "args": [
-      "server_finishes_request"
+      "request_with_payload"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16407,7 +17372,7 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_calls"
+      "resource_quota_server"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16431,14 +17396,14 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_tags"
+      "server_finishes_request"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16455,14 +17420,14 @@
   }, 
   {
     "args": [
-      "simple_cacheable_request"
+      "shutdown_finishes_calls"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16479,14 +17444,14 @@
   }, 
   {
     "args": [
-      "simple_delayed_request"
+      "shutdown_finishes_tags"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16503,14 +17468,14 @@
   }, 
   {
     "args": [
-      "simple_metadata"
+      "simple_cacheable_request"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16527,7 +17492,7 @@
   }, 
   {
     "args": [
-      "simple_request"
+      "simple_delayed_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16551,7 +17516,7 @@
   }, 
   {
     "args": [
-      "streaming_error_response"
+      "simple_metadata"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16575,7 +17540,7 @@
   }, 
   {
     "args": [
-      "trailing_metadata"
+      "simple_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16599,14 +17564,14 @@
   }, 
   {
     "args": [
-      "write_buffering"
+      "streaming_error_response"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16623,7 +17588,7 @@
   }, 
   {
     "args": [
-      "write_buffering_at_end"
+      "trailing_metadata"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16647,21 +17612,21 @@
   }, 
   {
     "args": [
-      "authority_not_supported"
+      "write_buffering"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
     ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_proxy_test", 
+    "name": "h2_oauth2_test", 
     "platforms": [
       "windows", 
       "linux", 
@@ -16671,21 +17636,21 @@
   }, 
   {
     "args": [
-      "bad_hostname"
+      "write_buffering_at_end"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
     ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_proxy_test", 
+    "name": "h2_oauth2_test", 
     "platforms": [
       "windows", 
       "linux", 
@@ -16695,7 +17660,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "authority_not_supported"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16719,7 +17684,7 @@
   }, 
   {
     "args": [
-      "call_creds"
+      "bad_hostname"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16743,7 +17708,7 @@
   }, 
   {
     "args": [
-      "cancel_after_accept"
+      "binary_metadata"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16767,7 +17732,7 @@
   }, 
   {
     "args": [
-      "cancel_after_client_done"
+      "call_creds"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16791,7 +17756,7 @@
   }, 
   {
     "args": [
-      "cancel_after_invoke"
+      "cancel_after_accept"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16815,7 +17780,7 @@
   }, 
   {
     "args": [
-      "cancel_before_invoke"
+      "cancel_after_client_done"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16839,7 +17804,7 @@
   }, 
   {
     "args": [
-      "cancel_in_a_vacuum"
+      "cancel_after_invoke"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16863,7 +17828,7 @@
   }, 
   {
     "args": [
-      "cancel_with_status"
+      "cancel_before_invoke"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16887,14 +17852,14 @@
   }, 
   {
     "args": [
-      "default_host"
+      "cancel_in_a_vacuum"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16911,38 +17876,14 @@
   }, 
   {
     "args": [
-      "disappearing_server"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
-    "flaky": true, 
-    "language": "c", 
-    "name": "h2_proxy_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "empty_batch"
+      "cancel_with_status"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -16959,7 +17900,7 @@
   }, 
   {
     "args": [
-      "filter_call_init_fails"
+      "default_host"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16983,7 +17924,7 @@
   }, 
   {
     "args": [
-      "filter_causes_close"
+      "disappearing_server"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16995,6 +17936,30 @@
     "exclude_iomgrs": [
       "uv"
     ], 
+    "flaky": true, 
+    "language": "c", 
+    "name": "h2_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "empty_batch"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
     "name": "h2_proxy_test", 
@@ -17007,7 +17972,7 @@
   }, 
   {
     "args": [
-      "filter_latency"
+      "filter_call_init_fails"
     ], 
     "ci_platforms": [
       "windows", 
@@ -17029,6 +17994,54 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "filter_causes_close"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "filter_latency"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "graceful_server_shutdown"
@@ -17062,7 +18075,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17173,6 +18186,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "max_message_length"
@@ -17182,7 +18219,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17230,7 +18267,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17326,7 +18363,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17374,7 +18411,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17398,7 +18435,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17422,7 +18459,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17446,7 +18483,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17470,7 +18507,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17566,7 +18603,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17614,7 +18651,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17638,7 +18675,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17710,7 +18747,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17782,7 +18819,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17926,7 +18963,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17974,7 +19011,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17998,7 +19035,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18046,7 +19083,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18070,7 +19107,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18142,7 +19179,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18214,7 +19251,31 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18238,7 +19299,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18286,7 +19347,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18382,7 +19443,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18454,7 +19515,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18502,7 +19563,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18526,7 +19587,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18550,7 +19611,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18574,7 +19635,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18646,7 +19707,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18694,7 +19755,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18718,7 +19779,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18790,7 +19851,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18862,7 +19923,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19006,7 +20067,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19054,7 +20115,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19078,7 +20139,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19126,7 +20187,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19198,7 +20259,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19270,7 +20331,31 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19294,7 +20379,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19342,7 +20427,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19414,7 +20499,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19486,7 +20571,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19510,7 +20595,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19534,7 +20619,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19558,7 +20643,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19582,7 +20667,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19654,7 +20739,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19702,7 +20787,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19726,7 +20811,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -19802,7 +20887,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -19880,7 +20965,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20036,7 +21121,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20088,7 +21173,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20114,7 +21199,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20166,7 +21251,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20192,7 +21277,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20270,7 +21355,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20348,7 +21433,33 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "msan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_1byte_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20374,7 +21485,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20426,7 +21537,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20530,7 +21641,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20608,7 +21719,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20634,7 +21745,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20660,7 +21771,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20686,7 +21797,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20712,7 +21823,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20790,7 +21901,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20842,7 +21953,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20868,7 +21979,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -20933,7 +22044,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -20954,6 +22065,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "call_creds"
@@ -21010,7 +22144,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21219,7 +22353,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21265,7 +22399,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21288,7 +22422,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21334,7 +22468,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21357,7 +22491,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21426,7 +22560,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21495,7 +22629,30 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21508,6 +22665,31 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "max_connection_idle"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "max_message_length"
@@ -21518,7 +22700,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21564,7 +22746,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21656,7 +22838,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21679,7 +22861,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21748,7 +22930,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21794,7 +22976,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21817,7 +22999,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21840,7 +23022,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21863,7 +23045,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -21955,7 +23137,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22001,7 +23183,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22024,7 +23206,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22085,7 +23267,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -22106,6 +23288,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "call_creds"
@@ -22162,7 +23367,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22371,7 +23576,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22417,7 +23622,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22440,7 +23645,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22486,7 +23691,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22509,7 +23714,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22578,7 +23783,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22647,7 +23852,30 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22660,6 +23888,31 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "max_connection_idle"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "max_message_length"
@@ -22670,7 +23923,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22716,7 +23969,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22808,7 +24061,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22831,7 +24084,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22900,7 +24153,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22946,7 +24199,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22969,7 +24222,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -22992,7 +24245,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -23015,7 +24268,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -23107,7 +24360,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -23153,7 +24406,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -23176,7 +24429,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -23246,7 +24499,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -23318,7 +24571,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -23486,7 +24739,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -23534,7 +24787,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -23558,7 +24811,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -23606,7 +24859,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -23717,6 +24970,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "max_message_length"
@@ -23726,7 +25003,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -23774,7 +25051,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -23870,7 +25147,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -23918,7 +25195,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -23942,7 +25219,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -23966,7 +25243,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -23990,7 +25267,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -24014,7 +25291,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -24110,7 +25387,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -24158,7 +25435,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -24182,7 +25459,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -24245,7 +25522,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "linux", 
@@ -24266,6 +25543,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "call_creds"
@@ -24321,7 +25621,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -24505,7 +25805,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -24551,7 +25851,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -24574,7 +25874,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -24620,7 +25920,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -24643,7 +25943,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -24712,7 +26012,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -24781,7 +26081,53 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_idle"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -24804,7 +26150,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -24850,7 +26196,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -24942,7 +26288,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -24965,7 +26311,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -25034,7 +26380,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -25080,7 +26426,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -25103,7 +26449,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -25126,7 +26472,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -25149,7 +26495,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -25241,7 +26587,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -25287,7 +26633,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -25310,7 +26656,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -25372,7 +26718,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -25393,6 +26739,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "cancel_after_accept"
@@ -25426,7 +26795,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -25635,7 +27004,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -25681,7 +27050,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -25704,7 +27073,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -25750,7 +27119,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -25773,7 +27142,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -25842,7 +27211,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -25911,7 +27280,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -25926,7 +27295,7 @@
   }, 
   {
     "args": [
-      "max_message_length"
+      "max_connection_age"
     ], 
     "ci_platforms": [
       "windows", 
@@ -25934,7 +27303,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -25949,7 +27318,7 @@
   }, 
   {
     "args": [
-      "negative_deadline"
+      "max_connection_idle"
     ], 
     "ci_platforms": [
       "windows", 
@@ -25957,9 +27326,11 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
     "name": "h2_census_nosec_test", 
@@ -25972,7 +27343,7 @@
   }, 
   {
     "args": [
-      "network_status_change"
+      "max_message_length"
     ], 
     "ci_platforms": [
       "windows", 
@@ -25980,7 +27351,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -25995,7 +27366,7 @@
   }, 
   {
     "args": [
-      "no_logging"
+      "negative_deadline"
     ], 
     "ci_platforms": [
       "windows", 
@@ -26018,7 +27389,7 @@
   }, 
   {
     "args": [
-      "no_op"
+      "network_status_change"
     ], 
     "ci_platforms": [
       "windows", 
@@ -26026,7 +27397,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -26041,7 +27412,7 @@
   }, 
   {
     "args": [
-      "payload"
+      "no_logging"
     ], 
     "ci_platforms": [
       "windows", 
@@ -26064,7 +27435,7 @@
   }, 
   {
     "args": [
-      "ping"
+      "no_op"
     ], 
     "ci_platforms": [
       "windows", 
@@ -26087,7 +27458,7 @@
   }, 
   {
     "args": [
-      "ping_pong_streaming"
+      "payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -26110,7 +27481,7 @@
   }, 
   {
     "args": [
-      "registered_call"
+      "ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -26118,7 +27489,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -26133,7 +27504,7 @@
   }, 
   {
     "args": [
-      "request_with_flags"
+      "ping_pong_streaming"
     ], 
     "ci_platforms": [
       "windows", 
@@ -26156,7 +27527,7 @@
   }, 
   {
     "args": [
-      "request_with_payload"
+      "registered_call"
     ], 
     "ci_platforms": [
       "windows", 
@@ -26177,6 +27548,52 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "request_with_flags"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "resource_quota_server"
@@ -26210,7 +27627,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -26233,7 +27650,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -26256,7 +27673,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -26279,7 +27696,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -26371,7 +27788,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -26417,7 +27834,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -26440,7 +27857,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -26501,7 +27918,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -26522,6 +27939,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "cancel_after_accept"
@@ -26555,7 +27995,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -26764,7 +28204,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -26810,7 +28250,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -26833,7 +28273,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -26879,7 +28319,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -26902,7 +28342,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -26971,7 +28411,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -27040,7 +28480,30 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -27053,6 +28516,31 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "max_connection_idle"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "max_message_length"
@@ -27063,7 +28551,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -27109,7 +28597,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -27201,7 +28689,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -27224,7 +28712,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -27293,7 +28781,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -27308,7 +28796,7 @@
   }, 
   {
     "args": [
-      "resource_quota_server"
+      "server_finishes_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -27316,7 +28804,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -27331,7 +28819,76 @@
   }, 
   {
     "args": [
-      "server_finishes_request"
+      "shutdown_finishes_calls"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "shutdown_finishes_tags"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_delayed_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -27354,7 +28911,7 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_calls"
+      "simple_metadata"
     ], 
     "ci_platforms": [
       "windows", 
@@ -27377,7 +28934,7 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_tags"
+      "simple_request"
     ], 
     "ci_platforms": [
       "windows", 
@@ -27400,122 +28957,30 @@
   }, 
   {
     "args": [
-      "simple_cacheable_request"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_compress_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "simple_delayed_request"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_compress_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "simple_metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_compress_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "simple_request"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_compress_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "streaming_error_response"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_compress_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "trailing_metadata"
+      "streaming_error_response"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "trailing_metadata"
     ], 
     "ci_platforms": [
       "windows", 
@@ -27546,7 +29011,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -27569,7 +29034,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -27637,7 +29102,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -27683,7 +29148,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -27821,7 +29286,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -27867,7 +29332,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -27890,7 +29355,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -27936,7 +29401,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -27959,7 +29424,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -28028,7 +29493,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -28097,7 +29562,30 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -28120,7 +29608,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -28166,7 +29654,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -28258,7 +29746,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -28327,7 +29815,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -28373,7 +29861,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -28396,7 +29884,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -28419,7 +29907,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -28442,7 +29930,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -28511,7 +29999,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -28557,7 +30045,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -28580,7 +30068,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -28642,7 +30130,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -28663,6 +30151,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "cancel_after_accept"
@@ -28696,7 +30207,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -28905,7 +30416,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -28951,7 +30462,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -28974,7 +30485,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29020,7 +30531,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29043,7 +30554,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29112,7 +30623,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29181,7 +30692,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29196,7 +30707,7 @@
   }, 
   {
     "args": [
-      "max_message_length"
+      "max_connection_age"
     ], 
     "ci_platforms": [
       "windows", 
@@ -29204,7 +30715,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29219,7 +30730,7 @@
   }, 
   {
     "args": [
-      "negative_deadline"
+      "max_connection_idle"
     ], 
     "ci_platforms": [
       "windows", 
@@ -29227,32 +30738,11 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "network_status_change"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
+    "exclude_iomgrs": [
+      "uv"
     ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "h2_full_nosec_test", 
@@ -29265,7 +30755,7 @@
   }, 
   {
     "args": [
-      "no_logging"
+      "max_message_length"
     ], 
     "ci_platforms": [
       "windows", 
@@ -29273,7 +30763,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29288,7 +30778,76 @@
   }, 
   {
     "args": [
-      "no_op"
+      "negative_deadline"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "network_status_change"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "no_logging"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "no_op"
     ], 
     "ci_platforms": [
       "windows", 
@@ -29342,7 +30901,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29365,7 +30924,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29434,7 +30993,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29480,7 +31039,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29503,7 +31062,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29526,7 +31085,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29549,7 +31108,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29641,7 +31200,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29687,7 +31246,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29710,7 +31269,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -29763,7 +31322,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "linux"
@@ -29780,6 +31339,25 @@
       "linux"
     ]
   }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
   {
     "args": [
       "cancel_after_accept"
@@ -29806,7 +31384,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -29977,7 +31555,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30015,7 +31593,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30034,7 +31612,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30072,7 +31650,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30091,7 +31669,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30148,7 +31726,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30205,7 +31783,45 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_idle"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30224,7 +31840,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30262,7 +31878,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30338,7 +31954,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30357,7 +31973,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30414,7 +32030,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30452,7 +32068,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30471,7 +32087,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30490,7 +32106,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30509,7 +32125,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30585,7 +32201,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30623,7 +32239,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30642,7 +32258,7 @@
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -30702,7 +32318,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -30723,6 +32339,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "cancel_after_accept"
@@ -30756,7 +32395,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -30965,7 +32604,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -31011,7 +32650,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -31034,7 +32673,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -31080,7 +32719,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -31149,7 +32788,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -31218,7 +32857,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -31233,7 +32872,7 @@
   }, 
   {
     "args": [
-      "max_message_length"
+      "max_connection_age"
     ], 
     "ci_platforms": [
       "windows", 
@@ -31241,7 +32880,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -31256,7 +32895,7 @@
   }, 
   {
     "args": [
-      "negative_deadline"
+      "max_connection_idle"
     ], 
     "ci_platforms": [
       "windows", 
@@ -31264,32 +32903,11 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full+trace_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "network_status_change"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
+    "exclude_iomgrs": [
+      "uv"
     ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "h2_full+trace_nosec_test", 
@@ -31302,7 +32920,7 @@
   }, 
   {
     "args": [
-      "no_op"
+      "max_message_length"
     ], 
     "ci_platforms": [
       "windows", 
@@ -31310,7 +32928,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -31325,7 +32943,7 @@
   }, 
   {
     "args": [
-      "payload"
+      "negative_deadline"
     ], 
     "ci_platforms": [
       "windows", 
@@ -31348,7 +32966,30 @@
   }, 
   {
     "args": [
-      "ping"
+      "network_status_change"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "no_op"
     ], 
     "ci_platforms": [
       "windows", 
@@ -31371,7 +33012,7 @@
   }, 
   {
     "args": [
-      "ping_pong_streaming"
+      "payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -31392,6 +33033,52 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "ping_pong_streaming"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "registered_call"
@@ -31448,7 +33135,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -31494,7 +33181,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -31517,7 +33204,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -31540,7 +33227,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -31563,7 +33250,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -31655,7 +33342,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -31701,7 +33388,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -31724,7 +33411,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -31787,7 +33474,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -31809,6 +33496,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_http_proxy_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "cancel_after_accept"
@@ -31842,7 +33553,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32058,7 +33769,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32106,7 +33817,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32130,7 +33841,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32178,7 +33889,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32202,7 +33913,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32274,7 +33985,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32346,7 +34057,55 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_http_proxy_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_http_proxy_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_idle"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32370,7 +34129,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32418,7 +34177,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32514,7 +34273,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32538,7 +34297,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32610,7 +34369,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32658,7 +34417,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32682,7 +34441,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32706,7 +34465,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32730,7 +34489,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32826,7 +34585,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32874,7 +34633,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32898,7 +34657,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -32961,7 +34720,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "windows", 
@@ -32984,7 +34743,7 @@
   }, 
   {
     "args": [
-      "cancel_after_accept"
+      "binary_metadata"
     ], 
     "ci_platforms": [
       "windows", 
@@ -33007,30 +34766,7 @@
   }, 
   {
     "args": [
-      "cancel_after_client_done"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_load_reporting_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "cancel_after_invoke"
+      "cancel_after_accept"
     ], 
     "ci_platforms": [
       "windows", 
@@ -33053,7 +34789,7 @@
   }, 
   {
     "args": [
-      "cancel_before_invoke"
+      "cancel_after_client_done"
     ], 
     "ci_platforms": [
       "windows", 
@@ -33076,7 +34812,7 @@
   }, 
   {
     "args": [
-      "cancel_in_a_vacuum"
+      "cancel_after_invoke"
     ], 
     "ci_platforms": [
       "windows", 
@@ -33099,7 +34835,7 @@
   }, 
   {
     "args": [
-      "cancel_with_status"
+      "cancel_before_invoke"
     ], 
     "ci_platforms": [
       "windows", 
@@ -33122,7 +34858,7 @@
   }, 
   {
     "args": [
-      "compressed_payload"
+      "cancel_in_a_vacuum"
     ], 
     "ci_platforms": [
       "windows", 
@@ -33130,7 +34866,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -33145,7 +34881,7 @@
   }, 
   {
     "args": [
-      "connectivity"
+      "cancel_with_status"
     ], 
     "ci_platforms": [
       "windows", 
@@ -33155,9 +34891,7 @@
     ], 
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "h2_load_reporting_nosec_test", 
@@ -33170,7 +34904,7 @@
   }, 
   {
     "args": [
-      "default_host"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -33193,7 +34927,7 @@
   }, 
   {
     "args": [
-      "disappearing_server"
+      "connectivity"
     ], 
     "ci_platforms": [
       "windows", 
@@ -33201,10 +34935,12 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": true, 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
     "language": "c", 
     "name": "h2_load_reporting_nosec_test", 
     "platforms": [
@@ -33216,7 +34952,7 @@
   }, 
   {
     "args": [
-      "empty_batch"
+      "default_host"
     ], 
     "ci_platforms": [
       "windows", 
@@ -33237,6 +34973,52 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "disappearing_server"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": true, 
+    "language": "c", 
+    "name": "h2_load_reporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "empty_batch"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_load_reporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "filter_call_init_fails"
@@ -33270,7 +35052,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -33293,7 +35075,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -33339,7 +35121,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -33362,7 +35144,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -33431,7 +35213,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -33500,7 +35282,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -33513,6 +35295,54 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_load_reporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_idle"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_load_reporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "max_message_length"
@@ -33523,7 +35353,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -33569,7 +35399,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -33661,7 +35491,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -33684,7 +35514,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -33753,7 +35583,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -33799,7 +35629,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -33822,7 +35652,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -33845,7 +35675,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -33868,7 +35698,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -33960,7 +35790,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -34006,7 +35836,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -34029,7 +35859,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
     "flaky": false, 
@@ -34099,7 +35929,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -34147,7 +35977,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -34315,7 +36145,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -34363,7 +36193,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -34387,7 +36217,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -34435,7 +36265,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -34546,6 +36376,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_proxy_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "max_message_length"
@@ -34555,7 +36409,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -34603,7 +36457,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -34699,7 +36553,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -34747,7 +36601,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -34771,7 +36625,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -34795,7 +36649,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -34819,7 +36673,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -34843,7 +36697,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -34939,7 +36793,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -34987,7 +36841,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35011,7 +36865,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35083,7 +36937,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35131,7 +36985,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35275,7 +37129,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35323,7 +37177,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35347,7 +37201,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35395,7 +37249,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35419,7 +37273,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35491,7 +37345,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35563,7 +37417,31 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35587,7 +37465,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35635,7 +37513,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35731,7 +37609,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35803,7 +37681,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35851,7 +37729,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35875,7 +37753,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35899,7 +37777,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35923,7 +37801,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -35995,7 +37873,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36043,7 +37921,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36067,7 +37945,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36139,7 +38017,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36187,7 +38065,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36331,7 +38209,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36379,7 +38257,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36403,7 +38281,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36451,7 +38329,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36523,7 +38401,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36595,7 +38473,31 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_connection_age"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36619,7 +38521,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36667,7 +38569,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36739,7 +38641,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36811,7 +38713,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36835,7 +38737,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36859,7 +38761,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36883,7 +38785,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36907,7 +38809,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -36979,7 +38881,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -37027,7 +38929,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -37051,7 +38953,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -37127,7 +39029,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -37179,7 +39081,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -37335,7 +39237,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -37387,7 +39289,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -37413,7 +39315,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -37465,7 +39367,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -37491,7 +39393,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -37569,7 +39471,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -37647,189 +39549,7 @@
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [
-      "msan"
-    ], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_sockpair_1byte_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "max_message_length"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [
-      "msan"
-    ], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_sockpair_1byte_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "negative_deadline"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [
-      "msan"
-    ], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_sockpair_1byte_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "network_status_change"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [
-      "msan"
-    ], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_sockpair_1byte_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "no_logging"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [
-      "msan"
-    ], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_sockpair_1byte_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "no_op"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [
-      "msan"
-    ], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_sockpair_1byte_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "payload"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [
-      "msan"
-    ], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_sockpair_1byte_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "ping_pong_streaming"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -37848,14 +39568,14 @@
   }, 
   {
     "args": [
-      "registered_call"
+      "max_connection_age"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -37874,7 +39594,7 @@
   }, 
   {
     "args": [
-      "request_with_flags"
+      "max_message_length"
     ], 
     "ci_platforms": [
       "windows", 
@@ -37900,7 +39620,7 @@
   }, 
   {
     "args": [
-      "request_with_payload"
+      "negative_deadline"
     ], 
     "ci_platforms": [
       "windows", 
@@ -37926,14 +39646,14 @@
   }, 
   {
     "args": [
-      "server_finishes_request"
+      "network_status_change"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -37952,7 +39672,7 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_calls"
+      "no_logging"
     ], 
     "ci_platforms": [
       "windows", 
@@ -37978,7 +39698,7 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_tags"
+      "no_op"
     ], 
     "ci_platforms": [
       "windows", 
@@ -38004,7 +39724,7 @@
   }, 
   {
     "args": [
-      "simple_cacheable_request"
+      "payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -38030,14 +39750,14 @@
   }, 
   {
     "args": [
-      "simple_metadata"
+      "ping_pong_streaming"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -38056,7 +39776,7 @@
   }, 
   {
     "args": [
-      "simple_request"
+      "registered_call"
     ], 
     "ci_platforms": [
       "windows", 
@@ -38082,14 +39802,14 @@
   }, 
   {
     "args": [
-      "streaming_error_response"
+      "request_with_flags"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -38108,14 +39828,14 @@
   }, 
   {
     "args": [
-      "trailing_metadata"
+      "request_with_payload"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -38134,14 +39854,14 @@
   }, 
   {
     "args": [
-      "write_buffering"
+      "server_finishes_request"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -38160,14 +39880,14 @@
   }, 
   {
     "args": [
-      "write_buffering_at_end"
+      "shutdown_finishes_calls"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [
       "msan"
     ], 
@@ -38186,22 +39906,25 @@
   }, 
   {
     "args": [
-      "authority_not_supported"
+      "shutdown_finishes_tags"
     ], 
     "ci_platforms": [
+      "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "msan"
+    ], 
     "exclude_iomgrs": [
       "uv"
     ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_uds_nosec_test", 
+    "name": "h2_sockpair_1byte_nosec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -38209,22 +39932,51 @@
   }, 
   {
     "args": [
-      "bad_hostname"
+      "simple_cacheable_request"
     ], 
     "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "msan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_1byte_nosec_test", 
+    "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
     ], 
     "cpu_cost": 1.0, 
-    "exclude_configs": [], 
+    "exclude_configs": [
+      "msan"
+    ], 
     "exclude_iomgrs": [
       "uv"
     ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_uds_nosec_test", 
+    "name": "h2_sockpair_1byte_nosec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -38232,22 +39984,25 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "simple_request"
     ], 
     "ci_platforms": [
+      "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
-    "exclude_configs": [], 
+    "exclude_configs": [
+      "msan"
+    ], 
     "exclude_iomgrs": [
       "uv"
     ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_uds_nosec_test", 
+    "name": "h2_sockpair_1byte_nosec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -38255,22 +40010,25 @@
   }, 
   {
     "args": [
-      "cancel_after_accept"
+      "streaming_error_response"
     ], 
     "ci_platforms": [
+      "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
-    "exclude_configs": [], 
+    "exclude_configs": [
+      "msan"
+    ], 
     "exclude_iomgrs": [
       "uv"
     ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_uds_nosec_test", 
+    "name": "h2_sockpair_1byte_nosec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -38278,22 +40036,25 @@
   }, 
   {
     "args": [
-      "cancel_after_client_done"
+      "trailing_metadata"
     ], 
     "ci_platforms": [
+      "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
-    "exclude_configs": [], 
+    "exclude_configs": [
+      "msan"
+    ], 
     "exclude_iomgrs": [
       "uv"
     ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_uds_nosec_test", 
+    "name": "h2_sockpair_1byte_nosec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -38301,22 +40062,25 @@
   }, 
   {
     "args": [
-      "cancel_after_invoke"
+      "write_buffering"
     ], 
     "ci_platforms": [
+      "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
-    "exclude_configs": [], 
+    "exclude_configs": [
+      "msan"
+    ], 
     "exclude_iomgrs": [
       "uv"
     ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_uds_nosec_test", 
+    "name": "h2_sockpair_1byte_nosec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -38324,22 +40088,25 @@
   }, 
   {
     "args": [
-      "cancel_before_invoke"
+      "write_buffering_at_end"
     ], 
     "ci_platforms": [
+      "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
-    "exclude_configs": [], 
+    "exclude_configs": [
+      "msan"
+    ], 
     "exclude_iomgrs": [
       "uv"
     ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_uds_nosec_test", 
+    "name": "h2_sockpair_1byte_nosec_test", 
     "platforms": [
+      "windows", 
       "linux", 
       "mac", 
       "posix"
@@ -38347,14 +40114,14 @@
   }, 
   {
     "args": [
-      "cancel_in_a_vacuum"
+      "authority_not_supported"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 0.1, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -38370,14 +40137,14 @@
   }, 
   {
     "args": [
-      "cancel_with_status"
+      "bad_hostname"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 0.1, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -38393,7 +40160,7 @@
   }, 
   {
     "args": [
-      "compressed_payload"
+      "bad_ping"
     ], 
     "ci_platforms": [
       "linux", 
@@ -38416,7 +40183,7 @@
   }, 
   {
     "args": [
-      "connectivity"
+      "binary_metadata"
     ], 
     "ci_platforms": [
       "linux", 
@@ -38439,19 +40206,19 @@
   }, 
   {
     "args": [
-      "disappearing_server"
+      "cancel_after_accept"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
     ], 
-    "flaky": true, 
+    "flaky": false, 
     "language": "c", 
     "name": "h2_uds_nosec_test", 
     "platforms": [
@@ -38462,14 +40229,14 @@
   }, 
   {
     "args": [
-      "empty_batch"
+      "cancel_after_client_done"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -38485,14 +40252,14 @@
   }, 
   {
     "args": [
-      "filter_call_init_fails"
+      "cancel_after_invoke"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -38508,14 +40275,14 @@
   }, 
   {
     "args": [
-      "filter_causes_close"
+      "cancel_before_invoke"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -38531,14 +40298,14 @@
   }, 
   {
     "args": [
-      "filter_latency"
+      "cancel_in_a_vacuum"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -38554,7 +40321,7 @@
   }, 
   {
     "args": [
-      "graceful_server_shutdown"
+      "cancel_with_status"
     ], 
     "ci_platforms": [
       "linux", 
@@ -38577,7 +40344,7 @@
   }, 
   {
     "args": [
-      "high_initial_seqno"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "linux", 
@@ -38600,14 +40367,14 @@
   }, 
   {
     "args": [
-      "hpack_size"
+      "connectivity"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -38623,7 +40390,7 @@
   }, 
   {
     "args": [
-      "idempotent_request"
+      "disappearing_server"
     ], 
     "ci_platforms": [
       "linux", 
@@ -38635,6 +40402,29 @@
     "exclude_iomgrs": [
       "uv"
     ], 
+    "flaky": true, 
+    "language": "c", 
+    "name": "h2_uds_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "empty_batch"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "language": "c", 
     "name": "h2_uds_nosec_test", 
@@ -38646,7 +40436,7 @@
   }, 
   {
     "args": [
-      "invoke_large_request"
+      "filter_call_init_fails"
     ], 
     "ci_platforms": [
       "linux", 
@@ -38669,14 +40459,14 @@
   }, 
   {
     "args": [
-      "keepalive_timeout"
+      "filter_causes_close"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -38692,14 +40482,14 @@
   }, 
   {
     "args": [
-      "large_metadata"
+      "filter_latency"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -38715,14 +40505,14 @@
   }, 
   {
     "args": [
-      "load_reporting_hook"
+      "graceful_server_shutdown"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -38738,14 +40528,14 @@
   }, 
   {
     "args": [
-      "max_concurrent_streams"
+      "high_initial_seqno"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -38761,14 +40551,14 @@
   }, 
   {
     "args": [
-      "max_message_length"
+      "hpack_size"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -38784,7 +40574,7 @@
   }, 
   {
     "args": [
-      "negative_deadline"
+      "idempotent_request"
     ], 
     "ci_platforms": [
       "linux", 
@@ -38807,7 +40597,7 @@
   }, 
   {
     "args": [
-      "network_status_change"
+      "invoke_large_request"
     ], 
     "ci_platforms": [
       "linux", 
@@ -38830,14 +40620,14 @@
   }, 
   {
     "args": [
-      "no_logging"
+      "keepalive_timeout"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -38853,7 +40643,7 @@
   }, 
   {
     "args": [
-      "no_op"
+      "large_metadata"
     ], 
     "ci_platforms": [
       "linux", 
@@ -38876,7 +40666,7 @@
   }, 
   {
     "args": [
-      "payload"
+      "load_reporting_hook"
     ], 
     "ci_platforms": [
       "linux", 
@@ -38899,14 +40689,14 @@
   }, 
   {
     "args": [
-      "ping"
+      "max_concurrent_streams"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -38922,14 +40712,14 @@
   }, 
   {
     "args": [
-      "ping_pong_streaming"
+      "max_connection_age"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -38945,14 +40735,14 @@
   }, 
   {
     "args": [
-      "registered_call"
+      "max_connection_idle"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -38968,7 +40758,7 @@
   }, 
   {
     "args": [
-      "request_with_flags"
+      "max_message_length"
     ], 
     "ci_platforms": [
       "linux", 
@@ -38991,7 +40781,7 @@
   }, 
   {
     "args": [
-      "request_with_payload"
+      "negative_deadline"
     ], 
     "ci_platforms": [
       "linux", 
@@ -39014,14 +40804,14 @@
   }, 
   {
     "args": [
-      "resource_quota_server"
+      "network_status_change"
     ], 
     "ci_platforms": [
       "linux", 
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -39037,7 +40827,7 @@
   }, 
   {
     "args": [
-      "server_finishes_request"
+      "no_logging"
     ], 
     "ci_platforms": [
       "linux", 
@@ -39060,7 +40850,7 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_calls"
+      "no_op"
     ], 
     "ci_platforms": [
       "linux", 
@@ -39083,7 +40873,7 @@
   }, 
   {
     "args": [
-      "shutdown_finishes_tags"
+      "payload"
     ], 
     "ci_platforms": [
       "linux", 
@@ -39106,7 +40896,122 @@
   }, 
   {
     "args": [
-      "simple_cacheable_request"
+      "ping"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "ping_pong_streaming"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "registered_call"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_flags"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_payload"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "resource_quota_server"
     ], 
     "ci_platforms": [
       "linux", 
@@ -39127,6 +41032,98 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "server_finishes_request"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "shutdown_finishes_calls"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "shutdown_finishes_tags"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "simple_delayed_request"
@@ -39205,7 +41202,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -39251,7 +41248,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -39274,7 +41271,7 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -39338,6 +41335,106 @@
     "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_secure", 
     "timeout_seconds": 360
   }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_1mps_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 1, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_1mps_secure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_10mps_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 10, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_10mps_secure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_1channel_1MBmsg_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_1channel_1MBmsg_secure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_64KBmsg_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 65536, \"req_size\": 65536}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 65536, \"req_size\": 65536}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_64KBmsg_secure", 
+    "timeout_seconds": 360
+  }, 
   {
     "args": [
       "--scenarios_json", 
@@ -39390,6 +41487,31 @@
     "shortname": "json_run_localhost:cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure", 
     "timeout_seconds": 360
   }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 8388608, \"req_size\": 128}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_secure", 
+    "timeout_seconds": 360
+  }, 
   {
     "args": [
       "--scenarios_json", 
@@ -39417,6 +41539,31 @@
     "shortname": "json_run_localhost:cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure", 
     "timeout_seconds": 360
   }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure_1MB\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_secure_1MB", 
+    "timeout_seconds": 360
+  }, 
   {
     "args": [
       "--scenarios_json", 
@@ -39470,7 +41617,82 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 2, 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_secure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 2, 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_ping_pong_secure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39489,13 +41711,63 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_secure_500kib_resource_quota", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_secure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_1mps_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 1, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1024, 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_1mps_secure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_10mps_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 10, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1024, 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_10mps_secure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39514,13 +41786,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_secure", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_ping_pong_secure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39539,13 +41811,265 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_secure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_1mps_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 1, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_1mps_secure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_10mps_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 10, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_10mps_secure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 2, 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_ping_pong_insecure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_insecure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_1mps_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 1, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_10mps_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 10, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 65536, \"req_size\": 65536}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 65536, \"req_size\": 65536}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_one_server_core_insecure", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "tsan", 
+      "asan"
+    ], 
+    "excluded_poll_engines": [
+      "poll-cv"
+    ], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 8388608, \"req_size\": 128}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39564,69 +42088,46 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure_500kib_resource_quota", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 2, 
+    "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
       "tsan", 
       "asan"
     ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_ping_pong_secure", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1024, 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "tsan", 
-      "asan"
+    "excluded_poll_engines": [
+      "poll-cv"
     ], 
-    "excluded_poll_engines": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "json_run_localhost", 
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_secure", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure_1MB\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1024, 
+    "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
       "tsan", 
@@ -39639,13 +42140,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_secure_500kib_resource_quota", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_insecure_1MB", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39664,44 +42165,19 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_ping_pong_secure", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": "capacity", 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "tsan", 
-      "asan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_secure", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_insecure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": "capacity", 
+    "cpu_cost": 1024, 
     "defaults": "boringssl", 
     "exclude_configs": [
       "tsan", 
@@ -39714,13 +42190,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_secure_500kib_resource_quota", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39739,13 +42215,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_generic_async_streaming_ping_pong_insecure", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_insecure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39764,19 +42240,19 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_insecure", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": "capacity", 
+    "cpu_cost": 2, 
     "defaults": "boringssl", 
     "exclude_configs": [
       "tsan", 
@@ -39789,73 +42265,69 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_one_server_core_insecure", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_ping_pong_insecure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": "capacity", 
+    "cpu_cost": 1024, 
     "defaults": "boringssl", 
     "exclude_configs": [
       "tsan", 
       "asan"
     ], 
-    "excluded_poll_engines": [
-      "poll-cv"
-    ], 
+    "excluded_poll_engines": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "json_run_localhost", 
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_insecure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 1, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": "capacity", 
+    "cpu_cost": 1024, 
     "defaults": "boringssl", 
     "exclude_configs": [
       "tsan", 
       "asan"
     ], 
-    "excluded_poll_engines": [
-      "poll-cv"
-    ], 
+    "excluded_poll_engines": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "json_run_localhost", 
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 10, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 2, 
+    "cpu_cost": 1024, 
     "defaults": "boringssl", 
     "exclude_configs": [
       "tsan", 
@@ -39868,19 +42340,19 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_insecure", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1024, 
+    "cpu_cost": 2, 
     "defaults": "boringssl", 
     "exclude_configs": [
       "tsan", 
@@ -39893,19 +42365,19 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_ping_pong_insecure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1024, 
+    "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
       "tsan", 
@@ -39918,19 +42390,19 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure_500kib_resource_quota", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_insecure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 1, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 2, 
+    "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
       "tsan", 
@@ -39943,13 +42415,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_insecure", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 10, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39968,23 +42440,36 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": "capacity", 
+    "cpu_cost": 2, 
     "defaults": "boringssl", 
     "exclude_configs": [
-      "tsan", 
-      "asan"
+      "asan-noleaks", 
+      "asan-trace-cmp", 
+      "basicprof", 
+      "c++-compat", 
+      "counters", 
+      "dbg", 
+      "gcov", 
+      "helgrind", 
+      "lto", 
+      "memcheck", 
+      "msan", 
+      "mutrace", 
+      "opt", 
+      "stapprof", 
+      "ubsan"
     ], 
     "excluded_poll_engines": [], 
     "flaky": false, 
@@ -39993,23 +42478,36 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure_500kib_resource_quota", 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_ping_pong_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 2, 
+    "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
-      "tsan", 
-      "asan"
+      "asan-noleaks", 
+      "asan-trace-cmp", 
+      "basicprof", 
+      "c++-compat", 
+      "counters", 
+      "dbg", 
+      "gcov", 
+      "helgrind", 
+      "lto", 
+      "memcheck", 
+      "msan", 
+      "mutrace", 
+      "opt", 
+      "stapprof", 
+      "ubsan"
     ], 
     "excluded_poll_engines": [], 
     "flaky": false, 
@@ -40018,23 +42516,36 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_ping_pong_insecure", 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_1mps_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 1, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1024, 
+    "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
-      "tsan", 
-      "asan"
+      "asan-noleaks", 
+      "asan-trace-cmp", 
+      "basicprof", 
+      "c++-compat", 
+      "counters", 
+      "dbg", 
+      "gcov", 
+      "helgrind", 
+      "lto", 
+      "memcheck", 
+      "msan", 
+      "mutrace", 
+      "opt", 
+      "stapprof", 
+      "ubsan"
     ], 
     "excluded_poll_engines": [], 
     "flaky": false, 
@@ -40043,23 +42554,36 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_insecure", 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_1mps_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_10mps_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 10, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 1024, 
+    "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
-      "tsan", 
-      "asan"
+      "asan-noleaks", 
+      "asan-trace-cmp", 
+      "basicprof", 
+      "c++-compat", 
+      "counters", 
+      "dbg", 
+      "gcov", 
+      "helgrind", 
+      "lto", 
+      "memcheck", 
+      "msan", 
+      "mutrace", 
+      "opt", 
+      "stapprof", 
+      "ubsan"
     ], 
     "excluded_poll_engines": [], 
     "flaky": false, 
@@ -40068,23 +42592,36 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_insecure_500kib_resource_quota", 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_10mps_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_1channel_1MBmsg_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 2, 
+    "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
-      "tsan", 
-      "asan"
+      "asan-noleaks", 
+      "asan-trace-cmp", 
+      "basicprof", 
+      "c++-compat", 
+      "counters", 
+      "dbg", 
+      "gcov", 
+      "helgrind", 
+      "lto", 
+      "memcheck", 
+      "msan", 
+      "mutrace", 
+      "opt", 
+      "stapprof", 
+      "ubsan"
     ], 
     "excluded_poll_engines": [], 
     "flaky": false, 
@@ -40093,13 +42630,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_ping_pong_insecure", 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_1channel_1MBmsg_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_64KBmsg_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 65536, \"req_size\": 65536}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 65536, \"req_size\": 65536}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40108,8 +42645,21 @@
     "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
-      "tsan", 
-      "asan"
+      "asan-noleaks", 
+      "asan-trace-cmp", 
+      "basicprof", 
+      "c++-compat", 
+      "counters", 
+      "dbg", 
+      "gcov", 
+      "helgrind", 
+      "lto", 
+      "memcheck", 
+      "msan", 
+      "mutrace", 
+      "opt", 
+      "stapprof", 
+      "ubsan"
     ], 
     "excluded_poll_engines": [], 
     "flaky": false, 
@@ -40118,13 +42668,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_insecure", 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_64KBmsg_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40133,8 +42683,21 @@
     "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
-      "tsan", 
-      "asan"
+      "asan-noleaks", 
+      "asan-trace-cmp", 
+      "basicprof", 
+      "c++-compat", 
+      "counters", 
+      "dbg", 
+      "gcov", 
+      "helgrind", 
+      "lto", 
+      "memcheck", 
+      "msan", 
+      "mutrace", 
+      "opt", 
+      "stapprof", 
+      "ubsan"
     ], 
     "excluded_poll_engines": [], 
     "flaky": false, 
@@ -40143,28 +42706,30 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_insecure_500kib_resource_quota", 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_one_server_core_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 2, 
+    "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40172,20 +42737,22 @@
       "stapprof", 
       "ubsan"
     ], 
-    "excluded_poll_engines": [], 
+    "excluded_poll_engines": [
+      "poll-cv"
+    ], 
     "flaky": false, 
     "language": "c++", 
     "name": "json_run_localhost", 
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_generic_async_streaming_ping_pong_secure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 8388608, \"req_size\": 128}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40197,10 +42764,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40215,13 +42784,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_secure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40233,10 +42802,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40244,20 +42815,22 @@
       "stapprof", 
       "ubsan"
     ], 
-    "excluded_poll_engines": [], 
+    "excluded_poll_engines": [
+      "poll-cv"
+    ], 
     "flaky": false, 
     "language": "c++", 
     "name": "json_run_localhost", 
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_one_server_core_secure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure_1MB\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40269,10 +42842,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40280,37 +42855,75 @@
       "stapprof", 
       "ubsan"
     ], 
-    "excluded_poll_engines": [
-      "poll-cv"
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_secure_1MB_low_thread_count", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 2, 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "asan-noleaks", 
+      "asan-trace-cmp", 
+      "basicprof", 
+      "c++-compat", 
+      "counters", 
+      "dbg", 
+      "gcov", 
+      "helgrind", 
+      "lto", 
+      "memcheck", 
+      "msan", 
+      "mutrace", 
+      "opt", 
+      "stapprof", 
+      "ubsan"
+    ], 
+    "excluded_poll_engines": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "json_run_localhost", 
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": "capacity", 
+    "cpu_cost": 64, 
     "defaults": "boringssl", 
     "exclude_configs": [
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40318,22 +42931,96 @@
       "stapprof", 
       "ubsan"
     ], 
-    "excluded_poll_engines": [
-      "poll-cv"
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
     ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_secure_low_thread_count", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 2, 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "asan-noleaks", 
+      "asan-trace-cmp", 
+      "basicprof", 
+      "c++-compat", 
+      "counters", 
+      "dbg", 
+      "gcov", 
+      "helgrind", 
+      "lto", 
+      "memcheck", 
+      "msan", 
+      "mutrace", 
+      "opt", 
+      "stapprof", 
+      "ubsan"
+    ], 
+    "excluded_poll_engines": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "json_run_localhost", 
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "asan-noleaks", 
+      "asan-trace-cmp", 
+      "basicprof", 
+      "c++-compat", 
+      "counters", 
+      "dbg", 
+      "gcov", 
+      "helgrind", 
+      "lto", 
+      "memcheck", 
+      "msan", 
+      "mutrace", 
+      "opt", 
+      "stapprof", 
+      "ubsan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure_low_thread_count", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40345,10 +43032,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40363,13 +43052,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_secure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_ping_pong_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40381,10 +43070,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40399,13 +43090,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_secure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_1mps_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40417,10 +43108,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40435,28 +43128,30 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_secure_500kib_resource_quota_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_1mps_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_10mps_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 10, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 2, 
+    "cpu_cost": 64, 
     "defaults": "boringssl", 
     "exclude_configs": [
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40471,28 +43166,30 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_secure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_10mps_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": "capacity", 
+    "cpu_cost": 2, 
     "defaults": "boringssl", 
     "exclude_configs": [
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40507,13 +43204,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_ping_pong_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40525,10 +43222,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40543,28 +43242,30 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure_500kib_resource_quota_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_1mps_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 1, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 2, 
+    "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40579,28 +43280,30 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_ping_pong_secure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_1mps_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_10mps_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 10, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 64, 
+    "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40615,28 +43318,30 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_secure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_10mps_secure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 64, 
+    "cpu_cost": 2, 
     "defaults": "boringssl", 
     "exclude_configs": [
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40651,28 +43356,30 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_secure_500kib_resource_quota_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_ping_pong_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 2, 
+    "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40687,13 +43394,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_ping_pong_secure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_1mps_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 1, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40705,10 +43412,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40723,13 +43432,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_secure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_1mps_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_10mps_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 10, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40741,10 +43450,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40759,28 +43470,30 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_secure_500kib_resource_quota_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_10mps_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 2, 
+    "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40795,13 +43508,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_generic_async_streaming_ping_pong_insecure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 65536, \"req_size\": 65536}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 65536, \"req_size\": 65536}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40813,10 +43526,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40831,7 +43546,7 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_insecure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
@@ -40849,10 +43564,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40885,10 +43602,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40908,6 +43627,44 @@
     "shortname": "json_run_localhost:cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 8388608, \"req_size\": 128}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": "capacity", 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "asan-noleaks", 
+      "asan-trace-cmp", 
+      "basicprof", 
+      "c++-compat", 
+      "counters", 
+      "dbg", 
+      "gcov", 
+      "helgrind", 
+      "lto", 
+      "memcheck", 
+      "msan", 
+      "mutrace", 
+      "opt", 
+      "stapprof", 
+      "ubsan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure_low_thread_count", 
+    "timeout_seconds": 360
+  }, 
   {
     "args": [
       "--scenarios_json", 
@@ -40923,10 +43680,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40949,22 +43708,24 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure_1MB\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 2, 
+    "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -40979,28 +43740,30 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_insecure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_insecure_1MB_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 64, 
+    "cpu_cost": 2, 
     "defaults": "boringssl", 
     "exclude_configs": [
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -41015,13 +43778,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -41033,10 +43796,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -41051,7 +43816,7 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure_500kib_resource_quota_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
@@ -41069,10 +43834,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -41105,10 +43872,50 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
+      "counters", 
+      "dbg", 
+      "gcov", 
+      "helgrind", 
+      "lto", 
+      "memcheck", 
+      "msan", 
+      "mutrace", 
+      "opt", 
+      "stapprof", 
+      "ubsan"
+    ], 
+    "excluded_poll_engines": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure_low_thread_count", 
+    "timeout_seconds": 360
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 2, 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "asan-noleaks", 
+      "asan-trace-cmp", 
+      "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -41123,28 +43930,30 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_ping_pong_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": "capacity", 
+    "cpu_cost": 64, 
     "defaults": "boringssl", 
     "exclude_configs": [
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -41159,28 +43968,30 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure_500kib_resource_quota_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 2, 
+    "cpu_cost": 64, 
     "defaults": "boringssl", 
     "exclude_configs": [
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -41195,13 +44006,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_ping_pong_insecure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 10, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -41213,10 +44024,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -41231,28 +44044,30 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_insecure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 64, 
+    "cpu_cost": 2, 
     "defaults": "boringssl", 
     "exclude_configs": [
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -41267,28 +44082,30 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_insecure_500kib_resource_quota_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_ping_pong_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
       "linux"
     ], 
-    "cpu_cost": 2, 
+    "cpu_cost": "capacity", 
     "defaults": "boringssl", 
     "exclude_configs": [
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -41303,13 +44120,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_ping_pong_insecure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 1, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -41321,10 +44138,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -41339,13 +44158,13 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_insecure_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"messages_per_stream\": 10, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -41357,10 +44176,12 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "c++-compat", 
       "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
+      "lto", 
       "memcheck", 
       "msan", 
       "mutrace", 
@@ -41375,7 +44196,7 @@
     "platforms": [
       "linux"
     ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_insecure_500kib_resource_quota_low_thread_count", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure_low_thread_count", 
     "timeout_seconds": 360
   }, 
   {
@@ -41396,6 +44217,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41418,6 +44240,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41440,6 +44263,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41462,6 +44286,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41484,6 +44309,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41506,6 +44332,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41528,6 +44355,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41550,6 +44378,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41572,6 +44401,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41594,6 +44424,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41616,6 +44447,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41638,6 +44470,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41660,6 +44493,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41682,6 +44516,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41704,6 +44539,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41726,6 +44562,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41748,6 +44585,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41770,6 +44608,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41792,6 +44631,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41814,6 +44654,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41836,6 +44677,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41858,6 +44700,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41880,6 +44723,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41902,6 +44746,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41924,6 +44769,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41946,6 +44792,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41968,6 +44815,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -41990,6 +44838,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42012,6 +44861,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42034,6 +44884,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42056,6 +44907,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42078,6 +44930,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42100,6 +44953,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42122,6 +44976,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42144,6 +44999,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42166,6 +45022,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42188,6 +45045,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42210,6 +45068,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42232,6 +45091,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42254,6 +45114,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42276,6 +45137,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42298,6 +45160,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42320,6 +45183,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42342,6 +45206,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42364,6 +45229,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42386,6 +45252,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42408,6 +45275,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42430,6 +45298,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42452,6 +45321,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42474,6 +45344,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42496,6 +45367,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42518,6 +45390,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42540,6 +45413,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42562,6 +45436,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42584,6 +45459,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42606,6 +45482,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42628,6 +45505,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42650,6 +45528,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42672,6 +45551,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42694,6 +45574,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42716,6 +45597,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42738,6 +45620,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42760,6 +45643,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42782,6 +45666,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42804,6 +45689,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42826,6 +45712,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42848,6 +45735,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42870,6 +45758,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42892,6 +45781,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42914,6 +45804,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42936,6 +45827,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42958,6 +45850,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -42980,6 +45873,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43002,6 +45896,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43024,6 +45919,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43046,6 +45942,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43068,6 +45965,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43090,6 +45988,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43112,6 +46011,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43134,6 +46034,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43156,6 +46057,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43178,6 +46080,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43200,6 +46103,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43222,6 +46126,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43244,6 +46149,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43266,6 +46172,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43288,6 +46195,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43310,6 +46218,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43332,6 +46241,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43354,6 +46264,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43376,6 +46287,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43398,6 +46310,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43420,6 +46333,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43442,6 +46356,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43464,6 +46379,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43486,6 +46402,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43508,6 +46425,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43530,6 +46448,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43552,6 +46471,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43574,6 +46494,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43596,6 +46517,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43618,6 +46540,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43640,6 +46563,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43662,6 +46586,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43684,6 +46609,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43706,6 +46632,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43728,6 +46655,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43750,6 +46678,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43772,6 +46701,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43794,6 +46724,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43816,6 +46747,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43838,6 +46770,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43860,6 +46793,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43882,6 +46816,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43904,6 +46839,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43926,6 +46862,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43948,6 +46885,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43970,6 +46908,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -43992,6 +46931,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44014,6 +46954,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44036,6 +46977,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44058,6 +47000,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44080,6 +47023,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44102,6 +47046,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44124,6 +47069,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44146,6 +47092,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44168,6 +47115,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44190,6 +47138,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44212,6 +47161,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44234,6 +47184,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44256,6 +47207,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44278,6 +47230,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44300,6 +47253,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44322,6 +47276,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44344,6 +47299,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44366,6 +47322,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44388,6 +47345,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44410,6 +47368,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44432,6 +47391,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44454,6 +47414,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44476,6 +47437,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44498,6 +47460,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44520,6 +47483,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44542,6 +47506,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44564,6 +47529,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44586,6 +47552,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44608,6 +47575,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44630,6 +47598,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44652,6 +47621,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44674,6 +47644,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44696,6 +47667,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44718,6 +47690,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44740,6 +47713,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44762,6 +47736,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44784,6 +47759,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44806,6 +47782,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44828,6 +47805,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44850,6 +47828,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44872,6 +47851,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44894,6 +47874,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44916,6 +47897,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44938,6 +47920,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44960,6 +47943,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -44982,6 +47966,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45004,6 +47989,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45026,6 +48012,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45048,6 +48035,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45070,6 +48058,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45092,6 +48081,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45114,6 +48104,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45136,6 +48127,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45158,6 +48150,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45180,6 +48173,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45202,6 +48196,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45224,6 +48219,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45246,6 +48242,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45268,6 +48265,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45290,6 +48288,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45312,6 +48311,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45334,6 +48334,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45356,6 +48357,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45378,6 +48380,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45400,6 +48403,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45422,6 +48426,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45444,6 +48449,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45466,6 +48472,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45488,6 +48495,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45510,6 +48518,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45532,6 +48541,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45554,6 +48564,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45576,6 +48587,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45598,6 +48610,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45620,6 +48633,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45642,6 +48656,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45664,6 +48679,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45686,6 +48702,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45708,6 +48725,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45730,6 +48748,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45752,6 +48771,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45774,6 +48794,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45796,6 +48817,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45818,6 +48840,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45840,6 +48863,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45862,6 +48886,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45884,6 +48909,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45906,6 +48932,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45928,6 +48955,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45950,6 +48978,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45972,6 +49001,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -45994,6 +49024,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46016,6 +49047,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46038,6 +49070,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46060,6 +49093,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46082,6 +49116,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46104,6 +49139,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46126,6 +49162,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46148,6 +49185,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46170,6 +49208,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46192,6 +49231,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46214,6 +49254,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46236,6 +49277,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46258,6 +49300,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46280,6 +49323,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46302,6 +49346,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46324,6 +49369,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46346,6 +49392,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46368,6 +49415,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46390,6 +49438,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46412,6 +49461,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46434,6 +49484,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46456,6 +49507,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46478,6 +49530,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46500,6 +49553,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46522,6 +49576,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46544,6 +49599,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46566,6 +49622,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46588,6 +49645,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46610,6 +49668,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46632,6 +49691,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46654,6 +49714,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46676,6 +49737,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46698,6 +49760,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46720,6 +49783,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46742,6 +49806,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46764,6 +49829,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46786,6 +49852,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46808,6 +49875,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46830,6 +49898,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46852,6 +49921,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46874,6 +49944,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46896,6 +49967,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46918,6 +49990,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46940,6 +50013,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46962,6 +50036,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -46984,6 +50059,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47006,6 +50082,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47028,6 +50105,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47050,6 +50128,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47072,6 +50151,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47094,6 +50174,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47116,6 +50197,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47138,6 +50220,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47160,6 +50243,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47182,6 +50266,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47204,6 +50289,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47226,6 +50312,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47248,6 +50335,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47270,6 +50358,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47292,6 +50381,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47314,6 +50404,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47336,6 +50427,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47358,6 +50450,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47380,6 +50473,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47402,6 +50496,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47424,6 +50519,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47446,6 +50542,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47468,6 +50565,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47490,6 +50588,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47512,6 +50611,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47534,6 +50634,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47556,6 +50657,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47578,6 +50680,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47600,6 +50703,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47622,6 +50726,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47644,6 +50749,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47666,6 +50772,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47688,6 +50795,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47710,6 +50818,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47732,6 +50841,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47754,6 +50864,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47776,6 +50887,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47798,6 +50910,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47820,6 +50933,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47842,6 +50956,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47864,6 +50979,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47886,6 +51002,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47908,6 +51025,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47930,6 +51048,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47952,6 +51071,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47974,6 +51094,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -47996,6 +51117,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48018,6 +51140,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48040,6 +51163,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48062,6 +51186,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48084,6 +51209,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48106,6 +51232,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48128,6 +51255,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48150,6 +51278,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48172,6 +51301,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48194,6 +51324,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48216,6 +51347,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48238,6 +51370,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48260,6 +51393,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48282,6 +51416,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48304,6 +51439,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48326,6 +51462,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48348,6 +51485,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48370,6 +51508,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48392,6 +51531,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48414,6 +51554,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48436,6 +51577,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48458,6 +51600,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48480,6 +51623,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48502,6 +51646,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48524,6 +51669,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48546,6 +51692,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48568,6 +51715,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48590,6 +51738,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48612,6 +51761,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48634,6 +51784,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48656,6 +51807,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48678,6 +51830,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48700,6 +51853,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48722,6 +51876,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48744,6 +51899,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48766,6 +51922,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48788,6 +51945,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48810,6 +51968,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48832,6 +51991,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48854,6 +52014,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48876,6 +52037,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48898,6 +52060,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48920,6 +52083,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48942,6 +52106,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48964,6 +52129,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -48986,6 +52152,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49008,6 +52175,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49030,6 +52198,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49052,6 +52221,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49074,6 +52244,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49096,6 +52267,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49118,6 +52290,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49140,6 +52313,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49162,6 +52336,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49184,6 +52359,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49206,6 +52382,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49228,6 +52405,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49250,6 +52428,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49272,6 +52451,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49294,6 +52474,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49316,6 +52497,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49338,6 +52520,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49360,6 +52543,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49382,6 +52566,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49404,6 +52589,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49426,6 +52612,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49448,6 +52635,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49470,6 +52658,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49492,6 +52681,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49514,6 +52704,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49536,6 +52727,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49558,6 +52750,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49580,6 +52773,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49602,6 +52796,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49624,6 +52819,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49646,6 +52842,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49668,6 +52865,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49690,6 +52888,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49712,6 +52911,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49734,6 +52934,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49756,6 +52957,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49778,6 +52980,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49800,6 +53003,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49822,6 +53026,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49844,6 +53049,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49866,6 +53072,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49888,6 +53095,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49910,6 +53118,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49932,6 +53141,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49954,6 +53164,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49976,6 +53187,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -49998,6 +53210,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50020,6 +53233,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50042,6 +53256,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50064,6 +53279,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50086,6 +53302,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50108,6 +53325,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50130,6 +53348,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50152,6 +53371,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50174,6 +53394,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50196,6 +53417,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50218,6 +53440,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50240,6 +53463,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50262,6 +53486,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50284,6 +53509,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50306,6 +53532,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50328,6 +53555,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50350,6 +53578,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50372,6 +53601,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50394,6 +53624,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50416,6 +53647,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50438,6 +53670,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50460,6 +53693,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50482,6 +53716,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50504,6 +53739,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50526,6 +53762,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50548,6 +53785,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50570,6 +53808,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50592,6 +53831,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50614,6 +53854,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50636,6 +53877,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50658,6 +53900,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50680,6 +53923,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50702,6 +53946,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50724,6 +53969,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50746,6 +53992,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50768,6 +54015,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50790,6 +54038,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50812,6 +54061,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50834,6 +54084,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50856,6 +54107,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50878,6 +54130,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50900,6 +54153,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50922,6 +54176,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50944,6 +54199,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50966,6 +54222,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -50988,6 +54245,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51010,6 +54268,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51032,6 +54291,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51054,6 +54314,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51076,6 +54337,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51098,6 +54360,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51120,6 +54383,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51142,6 +54406,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51164,6 +54429,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51186,6 +54452,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51208,6 +54475,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51230,6 +54498,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51252,6 +54521,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51274,6 +54544,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51296,6 +54567,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51318,6 +54590,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51340,6 +54613,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51362,6 +54636,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51384,6 +54659,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51406,6 +54682,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51428,6 +54705,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51450,6 +54728,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51472,6 +54751,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51494,6 +54774,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51516,6 +54797,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51538,6 +54820,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51560,6 +54843,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51582,6 +54866,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51604,6 +54889,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51626,6 +54912,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51648,6 +54935,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51670,6 +54958,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51692,6 +54981,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51714,6 +55004,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51736,6 +55027,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51758,6 +55050,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51780,6 +55073,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51802,6 +55096,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51824,6 +55119,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51846,6 +55142,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51868,6 +55165,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51890,6 +55188,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51912,6 +55211,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51934,6 +55234,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51956,6 +55257,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -51978,6 +55280,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52000,6 +55303,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52022,6 +55326,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52044,6 +55349,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52066,6 +55372,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52088,6 +55395,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52110,6 +55418,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52132,6 +55441,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52154,6 +55464,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52176,6 +55487,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52198,6 +55510,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52220,6 +55533,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52242,6 +55556,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52264,6 +55579,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52286,6 +55602,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52308,6 +55625,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52330,6 +55648,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52352,6 +55671,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52374,6 +55694,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52396,6 +55717,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52418,6 +55740,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52440,6 +55763,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52462,6 +55786,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52484,6 +55809,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52506,6 +55832,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52528,6 +55855,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52550,6 +55878,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52572,6 +55901,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52594,6 +55924,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52616,6 +55947,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52638,6 +55970,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52660,6 +55993,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52682,6 +56016,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52704,6 +56039,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52726,6 +56062,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52748,6 +56085,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52770,6 +56108,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52792,6 +56131,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52814,6 +56154,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52836,6 +56177,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52858,6 +56200,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52880,6 +56223,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52902,6 +56246,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52924,6 +56269,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52946,6 +56292,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52968,6 +56315,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -52990,6 +56338,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53012,6 +56361,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53034,6 +56384,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53056,6 +56407,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53078,6 +56430,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53100,6 +56453,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53122,6 +56476,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53144,6 +56499,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53166,6 +56522,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53188,6 +56545,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53210,6 +56568,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53232,6 +56591,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53254,6 +56614,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53276,6 +56637,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53298,6 +56660,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53320,6 +56683,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53342,6 +56706,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53364,6 +56729,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53386,6 +56752,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53408,6 +56775,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53430,6 +56798,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53452,6 +56821,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53474,6 +56844,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53496,6 +56867,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53518,6 +56890,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53540,6 +56913,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53562,6 +56936,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53584,6 +56959,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53606,6 +56982,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53628,6 +57005,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53650,6 +57028,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53672,6 +57051,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53694,6 +57074,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53716,6 +57097,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53738,6 +57120,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53760,6 +57143,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53782,6 +57166,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53804,6 +57189,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53826,6 +57212,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53848,6 +57235,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53870,6 +57258,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53892,6 +57281,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53914,6 +57304,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53936,6 +57327,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53958,6 +57350,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -53980,6 +57373,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54002,6 +57396,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54024,6 +57419,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54046,6 +57442,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54068,6 +57465,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54090,6 +57488,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54112,6 +57511,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54134,6 +57534,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54156,6 +57557,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54178,6 +57580,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54200,6 +57603,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54222,6 +57626,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54244,6 +57649,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54266,6 +57672,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54288,6 +57695,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54310,6 +57718,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54332,6 +57741,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54354,6 +57764,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54376,6 +57787,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54398,6 +57810,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54420,6 +57833,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54442,6 +57856,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54464,6 +57879,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54486,6 +57902,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54508,6 +57925,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54530,6 +57948,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54552,6 +57971,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54574,6 +57994,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54596,6 +58017,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54618,6 +58040,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54640,6 +58063,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54662,6 +58086,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54684,6 +58109,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54706,6 +58132,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54728,6 +58155,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54750,6 +58178,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54772,6 +58201,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54794,6 +58224,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54816,6 +58247,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54838,6 +58270,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54860,6 +58293,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54882,6 +58316,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54904,6 +58339,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54926,6 +58362,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54948,6 +58385,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54970,6 +58408,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -54992,6 +58431,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55014,6 +58454,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55036,6 +58477,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55058,6 +58500,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55080,6 +58523,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55102,6 +58546,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55124,6 +58569,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55146,6 +58592,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55168,6 +58615,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55190,6 +58638,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55212,6 +58661,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55234,6 +58684,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55256,6 +58707,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55278,6 +58730,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55300,6 +58753,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55322,6 +58776,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55344,6 +58799,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55366,6 +58822,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55388,6 +58845,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55410,6 +58868,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55432,6 +58891,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55454,6 +58914,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55476,6 +58937,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55498,6 +58960,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55520,6 +58983,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55542,6 +59006,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55564,6 +59029,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55586,6 +59052,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55608,6 +59075,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55630,6 +59098,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55652,6 +59121,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55674,6 +59144,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55696,6 +59167,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55718,6 +59190,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55740,6 +59213,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55762,6 +59236,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55784,6 +59259,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55806,6 +59282,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55828,6 +59305,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55850,6 +59328,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55872,6 +59351,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55894,6 +59374,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55916,6 +59397,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55938,6 +59420,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55960,6 +59443,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -55982,6 +59466,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56004,6 +59489,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56026,6 +59512,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56048,6 +59535,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56070,6 +59558,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56092,6 +59581,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56114,6 +59604,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56136,6 +59627,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56158,6 +59650,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56180,6 +59673,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56202,6 +59696,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56224,6 +59719,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56246,6 +59742,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56268,6 +59765,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56290,6 +59788,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56312,6 +59811,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56334,6 +59834,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56356,6 +59857,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56378,6 +59880,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56400,6 +59903,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56422,6 +59926,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56444,6 +59949,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56466,6 +59972,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56488,6 +59995,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56510,6 +60018,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56532,6 +60041,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56554,6 +60064,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56576,6 +60087,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56598,6 +60110,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56620,6 +60133,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56642,6 +60156,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56664,6 +60179,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56686,6 +60202,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56708,6 +60225,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56730,6 +60248,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56752,6 +60271,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56774,6 +60294,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56796,6 +60317,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56818,6 +60340,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56840,6 +60363,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56862,6 +60386,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56884,6 +60409,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56906,6 +60432,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56928,6 +60455,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56950,6 +60478,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56972,6 +60501,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -56994,6 +60524,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57016,6 +60547,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57038,6 +60570,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57060,6 +60593,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57082,6 +60616,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57104,6 +60639,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57126,6 +60662,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57148,6 +60685,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57170,6 +60708,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57192,6 +60731,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57214,6 +60754,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57236,6 +60777,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57258,6 +60800,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57280,6 +60823,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57302,6 +60846,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57324,6 +60869,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57346,6 +60892,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57368,6 +60915,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57390,6 +60938,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57412,6 +60961,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57434,6 +60984,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57456,6 +61007,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57478,6 +61030,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57500,6 +61053,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57522,6 +61076,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57544,6 +61099,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57566,6 +61122,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57588,6 +61145,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57610,6 +61168,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57632,6 +61191,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57654,6 +61214,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57676,6 +61237,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57698,6 +61260,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57720,6 +61283,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57742,6 +61306,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57764,6 +61329,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57786,6 +61352,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57808,6 +61375,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57830,6 +61398,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57852,6 +61421,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57874,6 +61444,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57896,6 +61467,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57918,6 +61490,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57940,6 +61513,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57962,6 +61536,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -57984,6 +61559,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58006,6 +61582,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58028,6 +61605,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58050,6 +61628,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58072,6 +61651,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58094,6 +61674,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58116,6 +61697,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58138,6 +61720,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58160,6 +61743,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58182,6 +61766,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58204,6 +61789,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58226,6 +61812,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58248,6 +61835,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58270,6 +61858,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58292,6 +61881,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58314,6 +61904,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58336,6 +61927,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58358,6 +61950,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58380,6 +61973,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58402,6 +61996,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58424,6 +62019,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58446,6 +62042,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58468,6 +62065,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58490,6 +62088,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58512,6 +62111,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58534,6 +62134,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58556,6 +62157,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58578,6 +62180,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58600,6 +62203,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58622,6 +62226,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58644,6 +62249,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58666,6 +62272,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58688,6 +62295,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58710,6 +62318,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58732,6 +62341,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58754,6 +62364,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58776,6 +62387,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58798,6 +62410,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58820,6 +62433,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58842,6 +62456,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58864,6 +62479,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58886,6 +62502,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58908,6 +62525,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58930,6 +62548,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58952,6 +62571,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58974,6 +62594,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -58996,6 +62617,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59018,6 +62640,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59040,6 +62663,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59062,6 +62686,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59084,6 +62709,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59106,6 +62732,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59128,6 +62755,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59150,6 +62778,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59172,6 +62801,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59194,6 +62824,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59216,6 +62847,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59238,6 +62870,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59260,6 +62893,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59282,6 +62916,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59304,6 +62939,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59326,6 +62962,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59348,6 +62985,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59370,6 +63008,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59392,6 +63031,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59414,6 +63054,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59436,6 +63077,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59458,6 +63100,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59480,6 +63123,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59502,6 +63146,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59524,6 +63169,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59546,6 +63192,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59568,6 +63215,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59590,6 +63238,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59612,6 +63261,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59634,6 +63284,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59656,6 +63307,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59678,6 +63330,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59700,6 +63353,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59722,6 +63376,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59744,6 +63399,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59766,6 +63422,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59788,6 +63445,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59810,6 +63468,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59832,6 +63491,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59854,6 +63514,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59876,6 +63537,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59898,6 +63560,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59920,6 +63583,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59942,6 +63606,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59964,6 +63629,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -59986,6 +63652,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60008,6 +63675,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60030,6 +63698,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60052,6 +63721,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60074,6 +63744,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60096,6 +63767,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60118,6 +63790,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60140,6 +63813,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60162,6 +63836,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60184,6 +63859,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60206,6 +63882,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60228,6 +63905,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60250,6 +63928,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60272,6 +63951,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60294,6 +63974,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60316,6 +63997,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60338,6 +64020,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60360,6 +64043,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60382,6 +64066,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60404,6 +64089,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60426,6 +64112,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60448,6 +64135,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60470,6 +64158,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60492,6 +64181,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60514,6 +64204,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60536,6 +64227,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60558,6 +64250,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60580,6 +64273,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60602,6 +64296,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60624,6 +64319,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60646,6 +64342,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60668,6 +64365,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60690,6 +64388,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60712,6 +64411,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60734,6 +64434,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60756,6 +64457,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60778,6 +64480,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60800,6 +64503,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60822,6 +64526,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60844,6 +64549,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60866,6 +64572,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60888,6 +64595,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60910,6 +64618,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60932,6 +64641,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60954,6 +64664,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60976,6 +64687,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -60998,6 +64710,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61020,6 +64733,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61042,6 +64756,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61064,6 +64779,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61086,6 +64802,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61108,6 +64825,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61130,6 +64848,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61152,6 +64871,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61174,6 +64894,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61196,6 +64917,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61218,6 +64940,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61240,6 +64963,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61262,6 +64986,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61284,6 +65009,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61306,6 +65032,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61328,6 +65055,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61350,6 +65078,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61372,6 +65101,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61394,6 +65124,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61416,6 +65147,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61438,6 +65170,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61460,6 +65193,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61482,6 +65216,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61504,6 +65239,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61526,6 +65262,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61548,6 +65285,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61570,6 +65308,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61592,6 +65331,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61614,6 +65354,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61636,6 +65377,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61658,6 +65400,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61680,6 +65423,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61702,6 +65446,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61724,6 +65469,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61746,6 +65492,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61768,6 +65515,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61790,6 +65538,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61812,6 +65561,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61834,6 +65584,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61856,6 +65607,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61878,6 +65630,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61900,6 +65653,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61922,6 +65676,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61944,6 +65699,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61966,6 +65722,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -61988,6 +65745,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62010,6 +65768,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62032,6 +65791,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62054,6 +65814,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62076,6 +65837,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62098,6 +65860,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62120,6 +65883,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62142,6 +65906,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62164,6 +65929,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62186,6 +65952,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62208,6 +65975,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62230,6 +65998,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62252,6 +66021,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62274,6 +66044,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62296,6 +66067,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62318,6 +66090,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62340,6 +66113,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62362,6 +66136,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62384,6 +66159,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62406,6 +66182,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62428,6 +66205,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62450,6 +66228,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62472,6 +66251,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62494,6 +66274,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62516,6 +66297,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62538,6 +66320,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62560,6 +66343,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62582,6 +66366,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62604,6 +66389,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62626,6 +66412,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62648,6 +66435,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62670,6 +66458,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62692,6 +66481,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62714,6 +66504,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62736,6 +66527,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62758,6 +66550,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62780,6 +66573,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62802,6 +66596,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62824,6 +66619,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62846,6 +66642,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62868,6 +66665,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62890,6 +66688,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62912,6 +66711,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62934,6 +66734,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62956,6 +66757,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -62978,6 +66780,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63000,6 +66803,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63022,6 +66826,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63044,6 +66849,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63066,6 +66872,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63088,6 +66895,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63110,6 +66918,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63132,6 +66941,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63154,6 +66964,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63176,6 +66987,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63198,6 +67010,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63220,6 +67033,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63242,6 +67056,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63264,6 +67079,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63286,6 +67102,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63308,6 +67125,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63330,6 +67148,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63352,6 +67171,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63374,6 +67194,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63396,6 +67217,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63418,6 +67240,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63440,6 +67263,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63462,6 +67286,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63484,6 +67309,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63506,6 +67332,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63528,6 +67355,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63550,6 +67378,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63572,6 +67401,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63594,6 +67424,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63616,6 +67447,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63638,6 +67470,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63660,6 +67493,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63682,6 +67516,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63704,6 +67539,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63726,6 +67562,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63748,6 +67585,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63770,6 +67608,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63792,6 +67631,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63814,6 +67654,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63836,6 +67677,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63858,6 +67700,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63880,6 +67723,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63902,6 +67746,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63924,6 +67769,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63946,6 +67792,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63968,6 +67815,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -63990,6 +67838,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64012,6 +67861,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64034,6 +67884,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64056,6 +67907,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64078,6 +67930,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64100,6 +67953,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64122,6 +67976,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64144,6 +67999,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64166,6 +68022,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64188,6 +68045,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64210,6 +68068,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64232,6 +68091,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64254,6 +68114,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64276,6 +68137,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64298,6 +68160,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64320,6 +68183,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64342,6 +68206,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64364,6 +68229,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64386,6 +68252,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64408,6 +68275,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64430,6 +68298,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64452,6 +68321,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64474,6 +68344,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64496,6 +68367,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64518,6 +68390,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64540,6 +68413,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64562,6 +68436,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64584,6 +68459,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64606,6 +68482,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64628,6 +68505,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64650,6 +68528,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64672,6 +68551,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64694,6 +68574,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64716,6 +68597,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64738,6 +68620,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64760,6 +68643,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64782,6 +68666,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64804,6 +68689,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64826,6 +68712,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64848,6 +68735,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64870,6 +68758,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64892,6 +68781,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64914,6 +68804,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64936,6 +68827,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64958,6 +68850,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -64980,6 +68873,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65002,6 +68896,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65024,6 +68919,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65046,6 +68942,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65068,6 +68965,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65090,6 +68988,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65112,6 +69011,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65134,6 +69034,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65156,6 +69057,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65178,6 +69080,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65200,6 +69103,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65222,6 +69126,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65244,6 +69149,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65266,6 +69172,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65288,6 +69195,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65310,6 +69218,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65332,6 +69241,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65354,6 +69264,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65376,6 +69287,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65398,6 +69310,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65420,6 +69333,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65442,6 +69356,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65464,6 +69379,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65486,6 +69402,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65508,6 +69425,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65530,6 +69448,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65552,6 +69471,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65574,6 +69494,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65596,6 +69517,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65618,6 +69540,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65640,6 +69563,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65662,6 +69586,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65684,6 +69609,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65706,6 +69632,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65728,6 +69655,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65750,6 +69678,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65772,6 +69701,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65794,6 +69724,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65816,6 +69747,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65838,6 +69770,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65860,6 +69793,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65882,6 +69816,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65904,6 +69839,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65926,6 +69862,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65948,6 +69885,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65970,6 +69908,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -65992,6 +69931,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66014,6 +69954,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66036,6 +69977,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66058,6 +70000,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66080,6 +70023,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66102,6 +70046,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66124,6 +70069,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66146,6 +70092,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66168,6 +70115,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66190,6 +70138,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66212,6 +70161,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66234,6 +70184,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66256,6 +70207,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66278,6 +70230,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66300,6 +70253,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66322,6 +70276,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66344,6 +70299,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66366,6 +70322,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66388,6 +70345,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66410,6 +70368,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66432,6 +70391,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66454,6 +70414,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66476,6 +70437,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66498,6 +70460,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66520,6 +70483,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66542,6 +70506,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66564,6 +70529,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66586,6 +70552,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66608,6 +70575,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66630,6 +70598,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66652,6 +70621,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66674,6 +70644,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66696,6 +70667,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66718,6 +70690,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66740,6 +70713,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66762,6 +70736,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66784,6 +70759,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66806,6 +70782,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66828,6 +70805,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66850,6 +70828,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66872,6 +70851,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66894,6 +70874,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66916,6 +70897,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66938,6 +70920,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66960,6 +70943,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -66982,6 +70966,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67004,6 +70989,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67026,6 +71012,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67048,6 +71035,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67070,6 +71058,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67092,6 +71081,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67114,6 +71104,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67136,6 +71127,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67158,6 +71150,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67180,6 +71173,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67202,6 +71196,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67224,6 +71219,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67246,6 +71242,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67268,6 +71265,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67290,6 +71288,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67312,6 +71311,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67334,6 +71334,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67356,6 +71357,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67378,6 +71380,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67400,6 +71403,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67422,6 +71426,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67444,6 +71449,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67466,6 +71472,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67488,6 +71495,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67510,6 +71518,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67532,6 +71541,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67554,6 +71564,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67576,6 +71587,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67598,6 +71610,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67620,6 +71633,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67642,6 +71656,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67664,6 +71679,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67686,6 +71702,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67708,6 +71725,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67730,6 +71748,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67752,6 +71771,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67774,6 +71794,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67796,6 +71817,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67818,6 +71840,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67840,6 +71863,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67862,6 +71886,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67884,6 +71909,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67906,6 +71932,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67928,6 +71955,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67950,6 +71978,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67972,6 +72001,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -67994,6 +72024,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68016,6 +72047,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68038,6 +72070,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68060,6 +72093,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68082,6 +72116,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68104,6 +72139,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68126,6 +72162,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68148,6 +72185,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68170,6 +72208,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68192,6 +72231,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68214,6 +72254,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68236,6 +72277,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68258,6 +72300,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68280,6 +72323,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68302,6 +72346,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68324,6 +72369,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68346,6 +72392,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68368,6 +72415,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68390,6 +72438,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68412,6 +72461,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68434,6 +72484,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68456,6 +72507,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68478,6 +72530,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68500,6 +72553,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68522,6 +72576,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68544,6 +72599,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68566,6 +72622,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68588,6 +72645,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68610,6 +72668,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68632,6 +72691,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68654,6 +72714,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68676,6 +72737,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68698,6 +72760,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68720,6 +72783,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68742,6 +72806,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68764,6 +72829,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68786,6 +72852,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68808,6 +72875,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68830,6 +72898,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68852,6 +72921,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68874,6 +72944,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68896,6 +72967,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68918,6 +72990,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68940,6 +73013,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68962,6 +73036,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -68984,6 +73059,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69006,6 +73082,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69028,6 +73105,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69050,6 +73128,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69072,6 +73151,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69094,6 +73174,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69116,6 +73197,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69138,6 +73220,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69160,6 +73243,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69182,6 +73266,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69204,6 +73289,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69226,6 +73312,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69248,6 +73335,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69270,6 +73358,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69292,6 +73381,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69314,6 +73404,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69336,6 +73427,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69358,6 +73450,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69380,6 +73473,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69402,6 +73496,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69424,6 +73519,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69446,6 +73542,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69468,6 +73565,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69490,6 +73588,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69512,6 +73611,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69534,6 +73634,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69556,6 +73657,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69578,6 +73680,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69600,6 +73703,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69622,6 +73726,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69644,6 +73749,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69666,6 +73772,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69688,6 +73795,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69710,6 +73818,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69732,6 +73841,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69754,6 +73864,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69776,6 +73887,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69798,6 +73910,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69820,6 +73933,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69842,6 +73956,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69864,6 +73979,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69886,6 +74002,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69908,6 +74025,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69930,6 +74048,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69952,6 +74071,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69974,6 +74094,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -69996,6 +74117,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70018,6 +74140,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70040,6 +74163,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70062,6 +74186,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70084,6 +74209,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70106,6 +74232,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70128,6 +74255,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70150,6 +74278,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70172,6 +74301,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70194,6 +74324,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70216,6 +74347,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70238,6 +74370,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70260,6 +74393,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70282,6 +74416,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70304,6 +74439,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70326,6 +74462,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70348,6 +74485,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70370,6 +74508,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70392,6 +74531,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70414,6 +74554,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70436,6 +74577,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70458,6 +74600,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70480,6 +74623,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70502,6 +74646,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70524,6 +74669,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70546,6 +74692,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70568,6 +74715,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70590,6 +74738,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70612,6 +74761,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70634,6 +74784,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70656,6 +74807,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70678,6 +74830,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70700,6 +74853,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70722,6 +74876,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70744,6 +74899,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70766,6 +74922,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70788,6 +74945,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70810,6 +74968,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70832,6 +74991,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70854,6 +75014,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70876,6 +75037,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70898,6 +75060,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70920,6 +75083,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70942,6 +75106,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70964,6 +75129,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -70986,6 +75152,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71008,6 +75175,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71030,6 +75198,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71052,6 +75221,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71074,6 +75244,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71096,6 +75267,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71118,6 +75290,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71140,6 +75313,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71162,6 +75336,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71184,6 +75359,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71206,6 +75382,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71228,6 +75405,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71250,6 +75428,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71272,6 +75451,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71294,6 +75474,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71316,6 +75497,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71338,6 +75520,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71360,6 +75543,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71382,6 +75566,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71404,6 +75589,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71426,6 +75612,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71448,6 +75635,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71470,6 +75658,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71492,6 +75681,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71514,6 +75704,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71536,6 +75727,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71558,6 +75750,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71580,6 +75773,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71602,6 +75796,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71624,6 +75819,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71646,6 +75842,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71668,6 +75865,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71690,6 +75888,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71712,6 +75911,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71734,6 +75934,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71756,6 +75957,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71778,6 +75980,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71800,6 +76003,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71822,6 +76026,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71844,6 +76049,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71866,6 +76072,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71888,6 +76095,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71910,6 +76118,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71932,6 +76141,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71954,6 +76164,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71976,6 +76187,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -71998,6 +76210,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72020,6 +76233,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72042,6 +76256,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72064,6 +76279,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72086,6 +76302,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72108,6 +76325,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72130,6 +76348,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72152,6 +76371,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72174,6 +76394,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72196,6 +76417,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72218,6 +76440,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72240,6 +76463,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72262,6 +76486,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72284,6 +76509,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72306,6 +76532,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72328,6 +76555,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72350,6 +76578,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72372,6 +76601,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72394,6 +76624,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72416,6 +76647,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72438,6 +76670,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72460,6 +76693,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72482,6 +76716,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72504,6 +76739,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72526,6 +76762,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72548,6 +76785,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72570,6 +76808,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72592,6 +76831,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72614,6 +76854,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72636,6 +76877,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72658,6 +76900,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72680,6 +76923,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72702,6 +76946,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72724,6 +76969,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72746,6 +76992,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72768,6 +77015,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72790,6 +77038,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72812,6 +77061,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72834,6 +77084,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72856,6 +77107,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72878,6 +77130,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72900,6 +77153,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72922,6 +77176,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72944,6 +77199,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72966,6 +77222,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -72988,6 +77245,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73010,6 +77268,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73032,6 +77291,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73054,6 +77314,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73076,6 +77337,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73098,6 +77360,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73120,6 +77383,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73142,6 +77406,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73164,6 +77429,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73186,6 +77452,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73208,6 +77475,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73230,6 +77498,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73252,6 +77521,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73274,6 +77544,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73296,6 +77567,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73318,6 +77590,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73340,6 +77613,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73362,6 +77636,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73384,6 +77659,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73406,6 +77682,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73428,6 +77705,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73450,6 +77728,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73472,6 +77751,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73494,6 +77774,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73516,6 +77797,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73538,6 +77820,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73560,6 +77843,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73582,6 +77866,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73604,6 +77889,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73626,6 +77912,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73648,6 +77935,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73670,6 +77958,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73692,6 +77981,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73714,6 +78004,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73736,6 +78027,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73758,6 +78050,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73780,6 +78073,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73802,6 +78096,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73824,6 +78119,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73846,6 +78142,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73868,6 +78165,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73890,6 +78188,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73912,6 +78211,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73934,6 +78234,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73956,6 +78257,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -73978,6 +78280,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74000,6 +78303,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74022,6 +78326,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74044,6 +78349,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74066,6 +78372,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74088,6 +78395,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74110,6 +78418,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74132,6 +78441,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74154,6 +78464,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74176,6 +78487,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74198,6 +78510,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74220,6 +78533,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74242,6 +78556,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74264,6 +78579,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74286,6 +78602,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74308,6 +78625,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74330,6 +78648,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74352,6 +78671,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74374,6 +78694,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74396,6 +78717,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74418,6 +78740,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74440,6 +78763,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74462,6 +78786,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74484,6 +78809,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74506,6 +78832,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74528,6 +78855,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74550,6 +78878,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74572,6 +78901,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74594,6 +78924,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74616,6 +78947,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74638,6 +78970,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74660,6 +78993,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74682,6 +79016,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74704,6 +79039,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74726,6 +79062,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74748,6 +79085,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74770,6 +79108,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74792,6 +79131,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74814,6 +79154,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74836,6 +79177,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74858,6 +79200,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74880,6 +79223,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74902,6 +79246,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74924,6 +79269,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74946,6 +79292,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74968,6 +79315,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -74990,6 +79338,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75012,6 +79361,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75034,6 +79384,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75056,6 +79407,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75078,6 +79430,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75100,6 +79453,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75122,6 +79476,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75144,6 +79499,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75166,6 +79522,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75188,6 +79545,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75210,6 +79568,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75232,6 +79591,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75254,6 +79614,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75276,6 +79637,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75298,6 +79660,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75320,6 +79683,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75342,6 +79706,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75364,6 +79729,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75386,6 +79752,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75408,6 +79775,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75430,6 +79798,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75452,6 +79821,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75474,6 +79844,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75496,6 +79867,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75518,6 +79890,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75540,6 +79913,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75562,6 +79936,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75584,6 +79959,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75606,6 +79982,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75628,6 +80005,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75650,6 +80028,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75672,6 +80051,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75694,6 +80074,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75716,6 +80097,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75738,6 +80120,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75760,6 +80143,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75782,6 +80166,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75804,6 +80189,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75826,6 +80212,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75848,6 +80235,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75870,6 +80258,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75892,6 +80281,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75914,6 +80304,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75936,6 +80327,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75958,6 +80350,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -75980,6 +80373,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76002,6 +80396,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76024,6 +80419,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76046,6 +80442,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76068,6 +80465,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76090,6 +80488,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76112,6 +80511,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76134,6 +80534,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76156,6 +80557,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76178,6 +80580,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76200,6 +80603,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76222,6 +80626,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76244,6 +80649,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76266,6 +80672,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76288,6 +80695,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76310,6 +80718,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76332,6 +80741,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76354,6 +80764,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76376,6 +80787,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76398,6 +80810,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76420,6 +80833,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76442,6 +80856,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76464,6 +80879,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76486,6 +80902,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76508,6 +80925,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76530,6 +80948,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76552,6 +80971,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76574,6 +80994,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76596,6 +81017,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76618,6 +81040,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76640,6 +81063,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76662,6 +81086,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76684,6 +81109,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76706,6 +81132,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76728,6 +81155,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76750,6 +81178,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76772,6 +81201,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76794,6 +81224,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76816,6 +81247,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76838,6 +81270,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76860,6 +81293,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76882,6 +81316,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76904,6 +81339,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76926,6 +81362,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76948,6 +81385,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76970,6 +81408,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -76992,6 +81431,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77014,6 +81454,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77036,6 +81477,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77058,6 +81500,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77080,6 +81523,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77102,6 +81546,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77124,6 +81569,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77146,6 +81592,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77168,6 +81615,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77190,6 +81638,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77212,6 +81661,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77234,6 +81684,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77256,6 +81707,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77278,6 +81730,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77300,6 +81753,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77322,6 +81776,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77344,6 +81799,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77366,6 +81822,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77388,6 +81845,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77410,6 +81868,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77432,6 +81891,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77454,6 +81914,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77476,6 +81937,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77498,6 +81960,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77520,6 +81983,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77542,6 +82006,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77564,6 +82029,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77586,6 +82052,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77608,6 +82075,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77630,6 +82098,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77652,6 +82121,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77674,6 +82144,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77696,6 +82167,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77718,6 +82190,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77740,6 +82213,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77762,6 +82236,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77784,6 +82259,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77806,6 +82282,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77828,6 +82305,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77850,6 +82328,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77872,6 +82351,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77894,6 +82374,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77916,6 +82397,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77938,6 +82420,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77960,6 +82443,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -77982,6 +82466,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78004,6 +82489,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78026,6 +82512,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78048,6 +82535,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78070,6 +82558,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78092,6 +82581,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78114,6 +82604,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78136,6 +82627,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78158,6 +82650,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78180,6 +82673,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78202,6 +82696,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78224,6 +82719,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78246,6 +82742,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78268,6 +82765,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78290,6 +82788,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78312,6 +82811,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78334,6 +82834,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78356,6 +82857,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78378,6 +82880,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78400,6 +82903,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78422,6 +82926,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78444,6 +82949,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78466,6 +82972,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78488,6 +82995,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78510,6 +83018,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78532,6 +83041,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78554,6 +83064,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78576,6 +83087,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78598,6 +83110,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78620,6 +83133,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78642,6 +83156,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78664,6 +83179,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78686,6 +83202,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78708,6 +83225,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78730,6 +83248,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78752,6 +83271,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78774,6 +83294,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78796,6 +83317,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78818,6 +83340,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78840,6 +83363,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78862,6 +83386,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78884,6 +83409,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78906,6 +83432,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78928,6 +83455,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78950,6 +83478,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78972,6 +83501,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -78994,6 +83524,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79016,6 +83547,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79038,6 +83570,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79060,6 +83593,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79082,6 +83616,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79104,6 +83639,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79126,6 +83662,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79148,6 +83685,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79170,6 +83708,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79192,6 +83731,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79214,6 +83754,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79236,6 +83777,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79258,6 +83800,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79280,6 +83823,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79302,6 +83846,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79324,6 +83869,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79346,6 +83892,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79368,6 +83915,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79390,6 +83938,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79412,6 +83961,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79434,6 +83984,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79456,6 +84007,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79478,6 +84030,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79500,6 +84053,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79522,6 +84076,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79544,6 +84099,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79566,6 +84122,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79588,6 +84145,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79610,6 +84168,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79632,6 +84191,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79654,6 +84214,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79676,6 +84237,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79698,6 +84260,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79720,6 +84283,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79742,6 +84306,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79764,6 +84329,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79786,6 +84352,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79808,6 +84375,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79830,6 +84398,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79852,6 +84421,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79874,6 +84444,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79896,6 +84467,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79918,6 +84490,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79940,6 +84513,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79962,6 +84536,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -79984,6 +84559,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80006,6 +84582,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80028,6 +84605,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80050,6 +84628,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80072,6 +84651,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80094,6 +84674,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80116,6 +84697,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80138,6 +84720,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80160,6 +84743,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80182,6 +84766,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80204,6 +84789,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80226,6 +84812,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80248,6 +84835,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80270,6 +84858,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80292,6 +84881,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80314,6 +84904,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80336,6 +84927,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80358,6 +84950,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80380,6 +84973,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80402,6 +84996,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80424,6 +85019,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80446,6 +85042,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80468,6 +85065,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80490,6 +85088,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80512,6 +85111,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80534,6 +85134,30 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5242554383597568"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80556,6 +85180,191 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5867145026076672"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "mac", 
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5965570207907840"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "mac", 
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6462055064272896"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "mac", 
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6499902139924480"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "mac", 
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6520142139752448"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "mac", 
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6699208922890240"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "mac", 
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6723650944237568"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "mac", 
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-5175380371570688"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80578,6 +85387,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80600,6 +85410,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80622,6 +85433,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80644,6 +85456,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80666,6 +85479,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80688,6 +85502,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80710,6 +85525,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80732,6 +85548,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80754,6 +85571,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80776,6 +85594,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80798,6 +85617,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80820,6 +85640,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80842,6 +85663,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80864,6 +85686,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80886,6 +85709,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80908,6 +85732,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80930,6 +85755,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80952,6 +85778,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80974,6 +85801,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -80996,6 +85824,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81018,6 +85847,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81040,6 +85870,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81062,6 +85893,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81084,6 +85916,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81106,6 +85939,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81128,6 +85962,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81150,6 +85985,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81172,6 +86008,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81194,6 +86031,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81216,6 +86054,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81238,6 +86077,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81260,6 +86100,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81282,6 +86123,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81304,6 +86146,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81326,6 +86169,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81348,6 +86192,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81370,6 +86215,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81392,6 +86238,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81414,6 +86261,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81436,6 +86284,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81458,6 +86307,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81480,6 +86330,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81502,6 +86353,30 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/crash-59a56fa18034a104fb9f16cd58071b6ff93b8756"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81524,6 +86399,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81546,6 +86422,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81568,6 +86445,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81590,6 +86468,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81612,6 +86491,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81634,6 +86514,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81656,6 +86537,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81678,6 +86560,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81700,6 +86583,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81722,6 +86606,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81744,6 +86629,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81766,6 +86652,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81788,6 +86675,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81810,6 +86698,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81832,6 +86721,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81854,6 +86744,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81876,6 +86767,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81898,6 +86790,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81920,6 +86813,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81942,6 +86836,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81964,6 +86859,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -81986,6 +86882,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82008,6 +86905,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82030,6 +86928,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82052,6 +86951,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82074,6 +86974,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82096,6 +86997,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82118,6 +87020,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82140,6 +87043,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82162,6 +87066,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82184,6 +87089,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82206,6 +87112,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82228,6 +87135,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82250,6 +87158,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82272,6 +87181,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82294,6 +87204,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82316,6 +87227,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82338,6 +87250,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82360,6 +87273,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82382,6 +87296,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82404,6 +87319,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82426,6 +87342,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82448,6 +87365,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82470,6 +87388,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82492,6 +87411,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82514,6 +87434,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82536,6 +87457,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82558,6 +87480,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82580,6 +87503,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82602,6 +87526,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82624,6 +87549,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82646,6 +87572,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82668,6 +87595,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82690,6 +87618,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82712,6 +87641,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82734,6 +87664,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82756,6 +87687,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82778,6 +87710,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82800,6 +87733,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82822,6 +87756,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82844,6 +87779,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82866,6 +87802,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82888,6 +87825,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82910,6 +87848,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82932,6 +87871,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82954,6 +87894,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82976,6 +87917,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -82998,6 +87940,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83020,6 +87963,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83042,6 +87986,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83064,6 +88009,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83086,6 +88032,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83108,6 +88055,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83130,6 +88078,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83152,6 +88101,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83174,6 +88124,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83196,6 +88147,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83218,6 +88170,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83240,6 +88193,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83262,6 +88216,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83284,6 +88239,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83306,6 +88262,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83328,6 +88285,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83350,6 +88308,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83372,6 +88331,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83394,6 +88354,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83416,6 +88377,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83438,6 +88400,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83460,6 +88423,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83482,6 +88446,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83504,6 +88469,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83526,6 +88492,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83548,6 +88515,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83570,6 +88538,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83592,6 +88561,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83614,6 +88584,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83636,6 +88607,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83658,6 +88630,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83680,6 +88653,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83702,6 +88676,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83724,6 +88699,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83746,6 +88722,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83768,6 +88745,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83790,6 +88768,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83812,6 +88791,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83834,6 +88814,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83856,6 +88837,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83878,6 +88860,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83900,6 +88883,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83922,6 +88906,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83944,6 +88929,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83966,6 +88952,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -83988,6 +88975,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84010,6 +88998,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84032,6 +89021,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84054,6 +89044,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84076,6 +89067,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84098,6 +89090,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84120,6 +89113,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84142,6 +89136,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84164,6 +89159,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84186,6 +89182,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84208,6 +89205,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84230,6 +89228,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84252,6 +89251,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84274,6 +89274,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84296,6 +89297,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84318,6 +89320,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84340,6 +89343,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84362,6 +89366,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84384,6 +89389,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84406,6 +89412,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84428,6 +89435,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84450,6 +89458,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84472,6 +89481,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84494,6 +89504,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84516,6 +89527,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84538,6 +89550,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84560,6 +89573,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84582,6 +89596,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84604,6 +89619,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84626,6 +89642,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84648,6 +89665,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84670,6 +89688,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84692,6 +89711,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84714,6 +89734,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84736,6 +89757,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84758,6 +89780,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84780,6 +89803,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84802,6 +89826,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84824,6 +89849,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84846,6 +89872,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84868,6 +89895,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84890,6 +89918,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84912,6 +89941,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84934,6 +89964,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84956,6 +89987,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -84978,6 +90010,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85000,6 +90033,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85022,6 +90056,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85044,6 +90079,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85066,6 +90102,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85088,6 +90125,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85110,6 +90148,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85132,6 +90171,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85154,6 +90194,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85176,6 +90217,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85198,6 +90240,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85220,6 +90263,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85242,6 +90286,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85264,6 +90309,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85286,6 +90332,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85308,6 +90355,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85330,6 +90378,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85352,6 +90401,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85374,6 +90424,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85396,6 +90447,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85418,6 +90470,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85440,6 +90493,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85462,6 +90516,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85484,6 +90539,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85506,6 +90562,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85528,6 +90585,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85550,6 +90608,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85572,6 +90631,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85594,6 +90654,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85616,6 +90677,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85638,6 +90700,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85660,6 +90723,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85682,6 +90746,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85704,6 +90769,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85726,6 +90792,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85748,6 +90815,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85770,6 +90838,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85792,6 +90861,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85814,6 +90884,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85836,6 +90907,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85858,6 +90930,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85880,6 +90953,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85902,6 +90976,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85924,6 +90999,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85946,6 +91022,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85968,6 +91045,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -85990,6 +91068,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86012,6 +91091,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86034,6 +91114,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86056,6 +91137,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86078,6 +91160,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86100,6 +91183,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86122,6 +91206,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86144,6 +91229,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86166,6 +91252,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86188,6 +91275,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86210,6 +91298,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86232,6 +91321,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86254,6 +91344,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86276,6 +91367,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86298,6 +91390,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86320,6 +91413,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86342,6 +91436,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86364,6 +91459,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86386,6 +91482,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86408,6 +91505,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86430,6 +91528,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86452,6 +91551,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86474,6 +91574,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86496,6 +91597,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86518,6 +91620,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86540,6 +91643,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86562,6 +91666,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86584,6 +91689,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86606,6 +91712,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86628,6 +91735,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86650,6 +91758,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86672,6 +91781,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86694,6 +91804,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86716,6 +91827,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86738,6 +91850,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86760,6 +91873,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86782,6 +91896,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86804,6 +91919,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86826,6 +91942,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86848,6 +91965,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86870,6 +91988,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86892,6 +92011,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86914,6 +92034,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86936,6 +92057,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86958,6 +92080,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -86980,6 +92103,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87002,6 +92126,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87024,6 +92149,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87046,6 +92172,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87068,6 +92195,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87090,6 +92218,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87112,6 +92241,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87134,6 +92264,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87156,6 +92287,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87178,6 +92310,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87200,6 +92333,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87222,6 +92356,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87244,6 +92379,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87266,6 +92402,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87288,6 +92425,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87310,6 +92448,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87332,6 +92471,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87354,6 +92494,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87376,6 +92517,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87398,6 +92540,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87420,6 +92563,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87442,6 +92586,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87464,6 +92609,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87486,6 +92632,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87508,6 +92655,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87530,6 +92678,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87552,6 +92701,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87574,6 +92724,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87596,6 +92747,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87618,6 +92770,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87640,6 +92793,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87662,6 +92816,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87684,6 +92839,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87706,6 +92862,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87728,6 +92885,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87750,6 +92908,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87772,6 +92931,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87794,6 +92954,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87816,6 +92977,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87838,6 +93000,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87860,6 +93023,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87882,6 +93046,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87904,6 +93069,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87926,6 +93092,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87948,6 +93115,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87970,6 +93138,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -87992,6 +93161,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88014,6 +93184,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88036,6 +93207,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88058,6 +93230,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88080,6 +93253,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88102,6 +93276,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88124,6 +93299,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88146,6 +93322,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88168,6 +93345,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88190,6 +93368,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88212,6 +93391,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88234,6 +93414,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88256,6 +93437,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88278,6 +93460,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88300,6 +93483,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88322,6 +93506,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88344,6 +93529,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88366,6 +93552,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88388,6 +93575,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88410,6 +93598,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88432,6 +93621,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88454,6 +93644,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88476,6 +93667,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88498,6 +93690,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88520,6 +93713,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88542,6 +93736,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88564,6 +93759,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88586,6 +93782,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88608,6 +93805,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88630,6 +93828,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88652,6 +93851,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88674,6 +93874,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88696,6 +93897,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88718,6 +93920,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88740,6 +93943,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88762,6 +93966,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88784,6 +93989,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88806,6 +94012,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88828,6 +94035,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88850,6 +94058,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88872,6 +94081,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88894,6 +94104,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88916,6 +94127,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88938,6 +94150,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88960,6 +94173,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -88982,6 +94196,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89004,6 +94219,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89026,6 +94242,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89048,6 +94265,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89070,6 +94288,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89092,6 +94311,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89114,6 +94334,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89136,6 +94357,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89158,6 +94380,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89180,6 +94403,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89202,6 +94426,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89224,6 +94449,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89246,6 +94472,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89268,6 +94495,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89290,6 +94518,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89312,6 +94541,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89334,6 +94564,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89356,6 +94587,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89378,6 +94610,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89400,6 +94633,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89422,6 +94656,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89444,6 +94679,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89466,6 +94702,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89488,6 +94725,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89510,6 +94748,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89532,6 +94771,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89554,6 +94794,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89576,6 +94817,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89598,6 +94840,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89620,6 +94863,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89642,6 +94886,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89664,6 +94909,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89686,6 +94932,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89708,6 +94955,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89730,6 +94978,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89752,6 +95001,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89774,6 +95024,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89796,6 +95047,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89818,6 +95070,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89840,6 +95093,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89862,6 +95116,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89884,6 +95139,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89906,6 +95162,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89928,6 +95185,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89950,6 +95208,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89972,6 +95231,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -89994,6 +95254,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90016,6 +95277,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90038,6 +95300,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90060,6 +95323,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90082,6 +95346,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90104,6 +95369,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90126,6 +95392,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90148,6 +95415,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90170,6 +95438,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90192,6 +95461,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90214,6 +95484,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90236,6 +95507,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90258,6 +95530,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90280,6 +95553,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90302,6 +95576,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90324,6 +95599,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90346,6 +95622,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90368,6 +95645,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90390,6 +95668,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90412,6 +95691,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90434,6 +95714,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90456,6 +95737,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90478,6 +95760,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90500,6 +95783,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90522,6 +95806,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90544,6 +95829,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90566,6 +95852,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90588,6 +95875,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90610,6 +95898,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90632,6 +95921,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90654,6 +95944,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90676,6 +95967,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90698,6 +95990,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90720,6 +96013,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90742,6 +96036,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90764,6 +96059,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90786,6 +96082,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90808,6 +96105,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90830,6 +96128,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90852,6 +96151,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90874,6 +96174,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90896,6 +96197,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90918,6 +96220,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90940,6 +96243,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90962,6 +96266,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -90984,6 +96289,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91006,6 +96312,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91028,6 +96335,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91050,6 +96358,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91072,6 +96381,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91094,6 +96404,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91116,6 +96427,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91138,6 +96450,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91160,6 +96473,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91182,6 +96496,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91204,6 +96519,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91226,6 +96542,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91248,6 +96565,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91270,6 +96588,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91292,6 +96611,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91314,6 +96634,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91336,6 +96657,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91358,6 +96680,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91380,6 +96703,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91402,6 +96726,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91424,6 +96749,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91446,6 +96772,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91468,6 +96795,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91490,6 +96818,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91512,6 +96841,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91534,6 +96864,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91556,6 +96887,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91578,6 +96910,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91600,6 +96933,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91622,6 +96956,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91644,6 +96979,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91666,6 +97002,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91688,6 +97025,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91710,6 +97048,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91732,6 +97071,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91754,6 +97094,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91776,6 +97117,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91798,6 +97140,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91820,6 +97163,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91842,6 +97186,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91864,6 +97209,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91886,6 +97232,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91908,6 +97255,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91930,6 +97278,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91952,6 +97301,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91974,6 +97324,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -91996,6 +97347,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92018,6 +97370,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92040,6 +97393,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92062,6 +97416,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92084,6 +97439,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92106,6 +97462,30 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/poc-c726ee220e980ed6ad17809fd9efe2844ee61555ac08e4f88afd8901cc2dd53a"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92128,6 +97508,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92150,6 +97531,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92172,6 +97554,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92194,6 +97577,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92216,6 +97600,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92238,6 +97623,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92260,6 +97646,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92282,6 +97669,7 @@
     "language": "c", 
     "name": "api_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92304,6 +97692,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92326,6 +97715,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92348,6 +97738,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92370,6 +97761,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92392,6 +97784,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92414,6 +97807,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92436,6 +97830,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92458,6 +97853,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92480,6 +97876,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92502,6 +97899,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92524,6 +97922,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92546,6 +97945,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92568,6 +97968,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92590,6 +97991,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92612,6 +98014,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92634,6 +98037,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92656,6 +98060,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92678,6 +98083,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92700,6 +98106,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92722,6 +98129,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92744,6 +98152,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92766,6 +98175,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92788,6 +98198,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92810,6 +98221,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92832,6 +98244,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92854,6 +98267,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92876,6 +98290,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92898,6 +98313,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92920,6 +98336,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92942,6 +98359,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92964,6 +98382,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -92986,6 +98405,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93008,6 +98428,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93030,6 +98451,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93052,6 +98474,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93074,6 +98497,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93096,6 +98520,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93118,6 +98543,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93140,6 +98566,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93162,6 +98589,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93184,6 +98612,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93206,6 +98635,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93228,6 +98658,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93250,6 +98681,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93272,6 +98704,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93294,6 +98727,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93316,6 +98750,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93338,6 +98773,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93360,6 +98796,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93382,6 +98819,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93404,6 +98842,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93426,6 +98865,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93448,6 +98888,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93470,6 +98911,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93492,6 +98934,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93514,6 +98957,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93536,6 +98980,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93558,6 +99003,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93580,6 +99026,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93602,6 +99049,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93624,6 +99072,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93646,6 +99095,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93668,6 +99118,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93690,6 +99141,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93712,6 +99164,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93734,6 +99187,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93756,6 +99210,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93778,6 +99233,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93800,6 +99256,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93822,6 +99279,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93844,6 +99302,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93866,6 +99325,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93888,6 +99348,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93910,6 +99371,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93932,6 +99394,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93954,6 +99417,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93976,6 +99440,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -93998,6 +99463,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94020,6 +99486,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94042,6 +99509,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94064,6 +99532,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94086,6 +99555,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94108,6 +99578,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94130,6 +99601,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94152,6 +99624,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94174,6 +99647,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94196,6 +99670,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94218,6 +99693,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94240,6 +99716,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94262,6 +99739,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94284,6 +99762,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94306,6 +99785,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94328,6 +99808,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94350,6 +99831,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94372,6 +99854,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94394,6 +99877,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94416,6 +99900,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94438,6 +99923,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94460,6 +99946,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94482,6 +99969,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94504,6 +99992,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94526,6 +100015,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94548,6 +100038,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94570,6 +100061,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94592,6 +100084,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94614,6 +100107,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94636,6 +100130,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94658,6 +100153,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94680,6 +100176,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94702,6 +100199,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94724,6 +100222,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94746,6 +100245,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94768,6 +100268,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94790,6 +100291,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94812,6 +100314,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94834,6 +100337,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94856,6 +100360,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94878,6 +100383,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94900,6 +100406,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94922,6 +100429,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94944,6 +100452,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94966,6 +100475,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -94988,6 +100498,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95010,6 +100521,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95032,6 +100544,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95054,6 +100567,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95076,6 +100590,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95098,6 +100613,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95120,6 +100636,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95142,6 +100659,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95164,6 +100682,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95186,6 +100705,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95208,6 +100728,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95230,6 +100751,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95252,6 +100774,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95274,6 +100797,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95296,6 +100820,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95318,6 +100843,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95340,6 +100866,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95362,6 +100889,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95384,6 +100912,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95406,6 +100935,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95428,6 +100958,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95450,6 +100981,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95472,6 +101004,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95494,6 +101027,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95516,6 +101050,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95538,6 +101073,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95560,6 +101096,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95582,6 +101119,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95604,6 +101142,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95626,6 +101165,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95648,6 +101188,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95670,6 +101211,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95692,6 +101234,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95714,6 +101257,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95736,6 +101280,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95758,6 +101303,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95780,6 +101326,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95802,6 +101349,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95824,6 +101372,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95846,6 +101395,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95868,6 +101418,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95890,6 +101441,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95912,6 +101464,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95934,6 +101487,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95956,6 +101510,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -95978,6 +101533,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96000,6 +101556,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96022,6 +101579,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96044,6 +101602,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96066,6 +101625,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96088,6 +101648,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96110,6 +101671,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96132,6 +101694,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96154,6 +101717,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96176,6 +101740,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96198,6 +101763,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96220,6 +101786,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96242,6 +101809,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96264,6 +101832,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96286,6 +101855,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96308,6 +101878,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96330,6 +101901,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96352,6 +101924,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96374,6 +101947,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96396,6 +101970,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96418,6 +101993,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96440,6 +102016,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96462,6 +102039,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96484,6 +102062,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96506,6 +102085,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96528,6 +102108,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96550,6 +102131,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96572,6 +102154,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96594,6 +102177,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96616,6 +102200,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96638,6 +102223,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96660,6 +102246,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96682,6 +102269,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96704,6 +102292,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96726,6 +102315,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96748,6 +102338,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96770,6 +102361,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96792,6 +102384,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96814,6 +102407,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96836,6 +102430,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96858,6 +102453,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96880,6 +102476,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96902,6 +102499,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96924,6 +102522,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96946,6 +102545,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96968,6 +102568,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -96990,6 +102591,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97012,6 +102614,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97034,6 +102637,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97056,6 +102660,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97078,6 +102683,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97100,6 +102706,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97122,6 +102729,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97144,6 +102752,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97166,6 +102775,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97188,6 +102798,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97210,6 +102821,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97232,6 +102844,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97254,6 +102867,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97276,6 +102890,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97298,6 +102913,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97320,6 +102936,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97342,6 +102959,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97364,6 +102982,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97386,6 +103005,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97408,6 +103028,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97430,6 +103051,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97452,6 +103074,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97474,6 +103097,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97496,6 +103120,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97518,6 +103143,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97540,6 +103166,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97562,6 +103189,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97584,6 +103212,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97606,6 +103235,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97628,6 +103258,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97650,6 +103281,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97672,6 +103304,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97694,6 +103327,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97716,6 +103350,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97738,6 +103373,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97760,6 +103396,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97782,6 +103419,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97804,6 +103442,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97826,6 +103465,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97848,6 +103488,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97870,6 +103511,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97892,6 +103534,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97914,6 +103557,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97936,6 +103580,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97958,6 +103603,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -97980,6 +103626,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98002,6 +103649,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98024,6 +103672,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98046,6 +103695,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98068,6 +103718,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98090,6 +103741,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98112,6 +103764,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98134,6 +103787,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98156,6 +103810,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98178,6 +103833,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98200,6 +103856,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98222,6 +103879,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98244,6 +103902,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98266,6 +103925,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98288,6 +103948,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98310,6 +103971,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98332,6 +103994,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98354,6 +104017,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98376,6 +104040,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98398,6 +104063,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98420,6 +104086,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98442,6 +104109,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98464,6 +104132,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98486,6 +104155,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98508,6 +104178,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98530,6 +104201,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98552,6 +104224,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98574,6 +104247,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98596,6 +104270,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98618,6 +104293,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98640,6 +104316,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98662,6 +104339,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98684,6 +104362,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98706,6 +104385,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98728,6 +104408,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98750,6 +104431,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98772,6 +104454,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98794,6 +104477,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98816,6 +104500,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98838,6 +104523,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98860,6 +104546,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98882,6 +104569,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98904,6 +104592,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98926,6 +104615,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98948,6 +104638,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98970,6 +104661,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -98992,6 +104684,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99014,6 +104707,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99036,6 +104730,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99058,6 +104753,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99080,6 +104776,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99102,6 +104799,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99124,6 +104822,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99146,6 +104845,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99168,6 +104868,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99190,6 +104891,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99212,6 +104914,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99234,6 +104937,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99256,6 +104960,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99278,6 +104983,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99300,6 +105006,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99322,6 +105029,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99344,6 +105052,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99366,6 +105075,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99388,6 +105098,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99410,6 +105121,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99432,6 +105144,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99454,6 +105167,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99476,6 +105190,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99498,6 +105213,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99520,6 +105236,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99542,6 +105259,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99564,6 +105282,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99586,6 +105305,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99608,6 +105328,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99630,6 +105351,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99652,6 +105374,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99674,6 +105397,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99696,6 +105420,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99718,6 +105443,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99740,6 +105466,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99762,6 +105489,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99784,6 +105512,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99806,6 +105535,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99828,6 +105558,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99850,6 +105581,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99872,6 +105604,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99894,6 +105627,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99916,6 +105650,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99938,6 +105673,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99960,6 +105696,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -99982,6 +105719,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100004,6 +105742,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100026,6 +105765,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100048,6 +105788,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100070,6 +105811,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100092,6 +105834,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100114,6 +105857,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100136,6 +105880,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100158,6 +105903,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100180,6 +105926,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100202,6 +105949,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100224,6 +105972,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100246,6 +105995,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100268,6 +106018,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100290,6 +106041,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100312,6 +106064,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100334,6 +106087,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100356,6 +106110,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100378,6 +106133,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100400,6 +106156,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100422,6 +106179,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100444,6 +106202,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100466,6 +106225,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100488,6 +106248,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100510,6 +106271,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100532,6 +106294,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100554,6 +106317,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100576,6 +106340,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100598,6 +106363,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100620,6 +106386,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100642,6 +106409,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100664,6 +106432,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100686,6 +106455,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100708,6 +106478,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100730,6 +106501,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100752,6 +106524,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100774,6 +106547,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100796,6 +106570,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100818,6 +106593,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100840,6 +106616,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100862,6 +106639,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100884,6 +106662,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100906,6 +106685,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100928,6 +106708,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100950,6 +106731,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100972,6 +106754,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -100994,6 +106777,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101016,6 +106800,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101038,6 +106823,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101060,6 +106846,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101082,6 +106869,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101104,6 +106892,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101126,6 +106915,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101148,6 +106938,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101170,6 +106961,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101192,6 +106984,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101214,6 +107007,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101236,6 +107030,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101258,6 +107053,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101280,6 +107076,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101302,6 +107099,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101324,6 +107122,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101346,6 +107145,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101368,6 +107168,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101390,6 +107191,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101412,6 +107214,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101434,6 +107237,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101456,6 +107260,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101478,6 +107283,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101500,6 +107306,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101522,6 +107329,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101544,6 +107352,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101566,6 +107375,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101588,6 +107398,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101610,6 +107421,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101632,6 +107444,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101654,6 +107467,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101676,6 +107490,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101698,6 +107513,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101720,6 +107536,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101742,6 +107559,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101764,6 +107582,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101786,6 +107605,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101808,6 +107628,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101830,6 +107651,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101852,6 +107674,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101874,6 +107697,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101896,6 +107720,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101918,6 +107743,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101940,6 +107766,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101962,6 +107789,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -101984,6 +107812,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102006,6 +107835,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102028,6 +107858,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102050,6 +107881,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102072,6 +107904,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102094,6 +107927,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102116,6 +107950,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102138,6 +107973,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102160,6 +107996,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102182,6 +108019,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102204,6 +108042,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102226,6 +108065,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102248,6 +108088,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102270,6 +108111,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102292,6 +108134,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102314,6 +108157,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102336,6 +108180,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102358,6 +108203,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102380,6 +108226,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102402,6 +108249,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102424,6 +108272,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102446,6 +108295,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102468,6 +108318,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102490,6 +108341,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102512,6 +108364,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102534,6 +108387,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102556,6 +108410,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102578,6 +108433,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102600,6 +108456,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102622,6 +108479,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102644,6 +108502,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102666,6 +108525,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102688,6 +108548,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102710,6 +108571,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102732,6 +108594,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102754,6 +108617,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102776,6 +108640,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102798,6 +108663,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102820,6 +108686,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102842,6 +108709,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102864,6 +108732,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102886,6 +108755,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102908,6 +108778,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102930,6 +108801,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102952,6 +108824,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102974,6 +108847,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -102996,6 +108870,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103018,6 +108893,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103040,6 +108916,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103062,6 +108939,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103084,6 +108962,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103106,6 +108985,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103128,6 +109008,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103150,6 +109031,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103172,6 +109054,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103194,6 +109077,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103216,6 +109100,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103238,6 +109123,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103260,6 +109146,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103282,6 +109169,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103304,6 +109192,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103326,6 +109215,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103348,6 +109238,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103370,6 +109261,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103392,6 +109284,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103414,6 +109307,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103436,6 +109330,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103458,6 +109353,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103480,6 +109376,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103502,6 +109399,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103524,6 +109422,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103546,6 +109445,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103568,6 +109468,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103590,6 +109491,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103612,6 +109514,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103634,6 +109537,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103656,6 +109560,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103678,6 +109583,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103700,6 +109606,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103722,6 +109629,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103744,6 +109652,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103766,6 +109675,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103788,6 +109698,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103810,6 +109721,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103832,6 +109744,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103854,6 +109767,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103876,6 +109790,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103898,6 +109813,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103920,6 +109836,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103942,6 +109859,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103964,6 +109882,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -103986,6 +109905,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104008,6 +109928,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104030,6 +109951,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104052,6 +109974,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104074,6 +109997,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104096,6 +110020,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104118,6 +110043,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104140,6 +110066,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104162,6 +110089,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104184,6 +110112,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104206,6 +110135,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104228,6 +110158,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104250,6 +110181,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104272,6 +110204,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104294,6 +110227,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104316,6 +110250,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104338,6 +110273,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104360,6 +110296,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104382,6 +110319,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104404,6 +110342,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104426,6 +110365,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104448,6 +110388,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104470,6 +110411,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104492,6 +110434,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104514,6 +110457,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104536,6 +110480,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104558,6 +110503,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104580,6 +110526,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104602,6 +110549,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104624,6 +110572,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104646,6 +110595,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104668,6 +110618,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104690,6 +110641,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104712,6 +110664,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104734,6 +110687,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104756,6 +110710,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104778,6 +110733,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104800,6 +110756,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104822,6 +110779,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104844,6 +110802,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104866,6 +110825,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104888,6 +110848,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104910,6 +110871,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104932,6 +110894,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104954,6 +110917,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104976,6 +110940,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -104998,6 +110963,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105020,6 +110986,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105042,6 +111009,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105064,6 +111032,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105086,6 +111055,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105108,6 +111078,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105130,6 +111101,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105152,6 +111124,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105174,6 +111147,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105196,6 +111170,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105218,6 +111193,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105240,6 +111216,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105262,6 +111239,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105284,6 +111262,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105306,6 +111285,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105328,6 +111308,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105350,6 +111331,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105372,6 +111354,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105394,6 +111377,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105416,6 +111400,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105438,6 +111423,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105460,6 +111446,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105482,6 +111469,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105504,6 +111492,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105526,6 +111515,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105548,6 +111538,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105570,6 +111561,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105592,6 +111584,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105614,6 +111607,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105636,6 +111630,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105658,6 +111653,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105680,6 +111676,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105702,6 +111699,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105724,6 +111722,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105746,6 +111745,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105768,6 +111768,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105790,6 +111791,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105812,6 +111814,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105834,6 +111837,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105856,6 +111860,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105878,6 +111883,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105900,6 +111906,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105922,6 +111929,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105944,6 +111952,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105966,6 +111975,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -105988,6 +111998,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106010,6 +112021,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106032,6 +112044,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106054,6 +112067,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106076,6 +112090,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106098,6 +112113,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106120,6 +112136,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106142,6 +112159,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106164,6 +112182,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106186,6 +112205,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106208,6 +112228,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106230,6 +112251,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106252,6 +112274,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106274,6 +112297,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106296,6 +112320,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106318,6 +112343,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106340,6 +112366,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106362,6 +112389,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106384,6 +112412,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106406,6 +112435,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106428,6 +112458,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106450,6 +112481,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106472,6 +112504,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106494,6 +112527,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106516,6 +112550,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106538,6 +112573,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106560,6 +112596,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106582,6 +112619,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106604,6 +112642,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106626,6 +112665,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106648,6 +112688,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106670,6 +112711,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106692,6 +112734,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106714,6 +112757,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106736,6 +112780,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106758,6 +112803,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106780,6 +112826,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106802,6 +112849,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106824,6 +112872,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106846,6 +112895,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106868,6 +112918,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106890,6 +112941,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106912,6 +112964,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106934,6 +112987,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106956,6 +113010,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -106978,6 +113033,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107000,6 +113056,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107022,6 +113079,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107044,6 +113102,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107066,6 +113125,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107088,6 +113148,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107110,6 +113171,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107132,6 +113194,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107154,6 +113217,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107176,6 +113240,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107198,6 +113263,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107220,6 +113286,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107242,6 +113309,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107264,6 +113332,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107286,6 +113355,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107308,6 +113378,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107330,6 +113401,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107352,6 +113424,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107374,6 +113447,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107396,6 +113470,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107418,6 +113493,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107440,6 +113516,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107462,6 +113539,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107484,6 +113562,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107506,6 +113585,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107528,6 +113608,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107550,6 +113631,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107572,6 +113654,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107594,6 +113677,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107616,6 +113700,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107638,6 +113723,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107660,6 +113746,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107682,6 +113769,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107704,6 +113792,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107726,6 +113815,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107748,6 +113838,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107770,6 +113861,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107792,6 +113884,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107814,6 +113907,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107836,6 +113930,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107858,6 +113953,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107880,6 +113976,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107902,6 +113999,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107924,6 +114022,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107946,6 +114045,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107968,6 +114068,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -107990,6 +114091,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108012,6 +114114,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108034,6 +114137,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108056,6 +114160,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108078,6 +114183,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108100,6 +114206,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108122,6 +114229,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108144,6 +114252,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108166,6 +114275,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108188,6 +114298,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108210,6 +114321,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108232,6 +114344,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108254,6 +114367,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108276,6 +114390,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108298,6 +114413,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108320,6 +114436,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108342,6 +114459,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108364,6 +114482,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108386,6 +114505,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108408,6 +114528,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108430,6 +114551,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108452,6 +114574,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108474,6 +114597,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108496,6 +114620,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108518,6 +114643,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108540,6 +114666,7 @@
     "language": "c", 
     "name": "client_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108562,6 +114689,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108584,6 +114712,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108606,6 +114735,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108628,6 +114758,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108650,6 +114781,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108672,6 +114804,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108694,6 +114827,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108716,6 +114850,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108738,6 +114873,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108760,6 +114896,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108782,6 +114919,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108804,6 +114942,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108826,6 +114965,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108848,6 +114988,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108870,6 +115011,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108892,6 +115034,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108914,6 +115057,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108936,6 +115080,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108958,6 +115103,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -108980,6 +115126,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109002,6 +115149,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109024,6 +115172,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109046,6 +115195,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109068,6 +115218,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109090,6 +115241,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109112,6 +115264,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109134,6 +115287,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109156,6 +115310,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109178,6 +115333,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109200,6 +115356,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109222,6 +115379,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109244,6 +115402,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109266,6 +115425,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109288,6 +115448,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109310,6 +115471,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109332,6 +115494,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109354,6 +115517,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109376,6 +115540,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109398,6 +115563,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109420,6 +115586,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109442,6 +115609,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109464,6 +115632,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109486,6 +115655,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109508,6 +115678,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109530,6 +115701,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109552,6 +115724,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109574,6 +115747,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109596,6 +115770,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109618,6 +115793,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109640,6 +115816,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109662,6 +115839,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109684,6 +115862,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109706,6 +115885,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109728,6 +115908,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109750,6 +115931,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109772,6 +115954,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109794,6 +115977,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109816,6 +116000,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109838,6 +116023,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109860,6 +116046,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109882,6 +116069,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109904,6 +116092,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109926,6 +116115,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109948,6 +116138,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109970,6 +116161,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -109992,6 +116184,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110014,6 +116207,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110036,6 +116230,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110058,6 +116253,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110080,6 +116276,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110102,6 +116299,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110124,6 +116322,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110146,6 +116345,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110168,6 +116368,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110190,6 +116391,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110212,6 +116414,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110234,6 +116437,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110256,6 +116460,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110278,6 +116483,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110300,6 +116506,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110322,6 +116529,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110344,6 +116552,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110366,6 +116575,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110388,6 +116598,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110410,6 +116621,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110432,6 +116644,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110454,6 +116667,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110476,6 +116690,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110498,6 +116713,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110520,6 +116736,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110542,6 +116759,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110564,6 +116782,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110586,6 +116805,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110608,6 +116828,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110630,6 +116851,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110652,6 +116874,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110674,6 +116897,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110696,6 +116920,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110718,6 +116943,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110740,6 +116966,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110762,6 +116989,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110784,6 +117012,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110806,6 +117035,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110828,6 +117058,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110850,6 +117081,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110872,6 +117104,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110894,6 +117127,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110916,6 +117150,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110938,6 +117173,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110960,6 +117196,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -110982,6 +117219,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111004,6 +117242,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111026,6 +117265,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111048,6 +117288,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111070,6 +117311,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111092,6 +117334,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111114,6 +117357,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111136,6 +117380,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111158,6 +117403,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111180,6 +117426,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111202,6 +117449,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111224,6 +117472,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111246,6 +117495,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111268,6 +117518,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111290,6 +117541,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111312,6 +117564,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111334,6 +117587,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111356,6 +117610,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111378,6 +117633,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111400,6 +117656,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111422,6 +117679,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111444,6 +117702,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111466,6 +117725,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111488,6 +117748,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111510,6 +117771,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111532,6 +117794,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111554,6 +117817,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111576,6 +117840,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111598,6 +117863,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111620,6 +117886,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111642,6 +117909,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111664,6 +117932,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111686,6 +117955,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111708,6 +117978,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111730,6 +118001,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111752,6 +118024,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111774,6 +118047,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111796,6 +118070,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111818,6 +118093,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111840,6 +118116,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111862,6 +118139,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111884,6 +118162,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111906,6 +118185,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111928,6 +118208,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111950,6 +118231,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111972,6 +118254,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -111994,6 +118277,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112016,6 +118300,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112038,6 +118323,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112060,6 +118346,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112082,6 +118369,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112104,6 +118392,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112126,6 +118415,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112148,6 +118438,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112170,6 +118461,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112192,6 +118484,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112214,6 +118507,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112236,6 +118530,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112258,6 +118553,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112280,6 +118576,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112302,6 +118599,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112324,6 +118622,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112346,6 +118645,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112368,6 +118668,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112390,6 +118691,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112412,6 +118714,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112434,6 +118737,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112456,6 +118760,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112478,6 +118783,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112500,6 +118806,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112522,6 +118829,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112544,6 +118852,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112566,6 +118875,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112588,6 +118898,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112610,6 +118921,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112632,6 +118944,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112654,6 +118967,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112676,6 +118990,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112698,6 +119013,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112720,6 +119036,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112742,6 +119059,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112764,6 +119082,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112786,6 +119105,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112808,6 +119128,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112830,6 +119151,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112852,6 +119174,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112874,6 +119197,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112896,6 +119220,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112918,6 +119243,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112940,6 +119266,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112962,6 +119289,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -112984,6 +119312,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113006,6 +119335,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113028,6 +119358,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113050,6 +119381,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113072,6 +119404,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113094,6 +119427,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113116,6 +119450,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113138,6 +119473,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113160,6 +119496,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113182,6 +119519,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113204,6 +119542,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113226,6 +119565,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113248,6 +119588,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113270,6 +119611,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113292,6 +119634,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113314,6 +119657,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113336,6 +119680,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113358,6 +119703,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113380,6 +119726,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113402,6 +119749,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113424,6 +119772,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113446,6 +119795,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113468,6 +119818,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113490,6 +119841,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113512,6 +119864,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113534,6 +119887,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113556,6 +119910,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113578,6 +119933,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113600,6 +119956,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113622,6 +119979,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113644,6 +120002,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113666,6 +120025,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113688,6 +120048,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113710,6 +120071,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113732,6 +120094,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113754,6 +120117,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113776,6 +120140,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113798,6 +120163,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113820,6 +120186,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113842,6 +120209,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113864,6 +120232,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113886,6 +120255,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113908,6 +120278,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113930,6 +120301,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113952,6 +120324,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113974,6 +120347,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -113996,6 +120370,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114018,6 +120393,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114040,6 +120416,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114062,6 +120439,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114084,6 +120462,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114106,6 +120485,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114128,6 +120508,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114150,6 +120531,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114172,6 +120554,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114194,6 +120577,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114216,6 +120600,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114238,6 +120623,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114260,6 +120646,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114282,6 +120669,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114304,6 +120692,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114326,6 +120715,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114348,6 +120738,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114370,6 +120761,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114392,6 +120784,30 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/transport/chttp2/hpack_parser_corpus/clusterfuzz-testcase-5298216461402112"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "hpack_parser_fuzzer_test_one_entry", 
+    "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114414,6 +120830,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114436,6 +120853,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114458,6 +120876,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114480,6 +120899,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114502,6 +120922,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114524,6 +120945,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114546,6 +120968,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114568,6 +120991,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114590,6 +121014,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114612,6 +121037,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114634,6 +121060,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114656,6 +121083,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114678,6 +121106,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114700,6 +121129,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114722,6 +121152,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114744,6 +121175,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114766,6 +121198,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114788,6 +121221,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114810,6 +121244,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114832,6 +121267,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114854,6 +121290,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114876,6 +121313,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114898,6 +121336,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114920,6 +121359,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114942,6 +121382,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114964,6 +121405,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -114986,6 +121428,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115008,6 +121451,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115030,6 +121474,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115052,6 +121497,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115074,6 +121520,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115096,6 +121543,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115118,6 +121566,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115140,6 +121589,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115162,6 +121612,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115184,6 +121635,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115206,6 +121658,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115228,6 +121681,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115250,6 +121704,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115272,6 +121727,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115294,6 +121750,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115316,6 +121773,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115338,6 +121796,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115360,6 +121819,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115382,6 +121842,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115404,6 +121865,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115426,6 +121888,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115448,6 +121911,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115470,6 +121934,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115492,6 +121957,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115514,6 +121980,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115536,6 +122003,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115558,6 +122026,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115580,6 +122049,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115602,6 +122072,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115624,6 +122095,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115646,6 +122118,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115668,6 +122141,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115690,6 +122164,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115712,6 +122187,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115734,6 +122210,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115756,6 +122233,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115778,6 +122256,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115800,6 +122279,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115822,6 +122302,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115844,6 +122325,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115866,6 +122348,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115888,6 +122371,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115910,6 +122394,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115932,6 +122417,7 @@
     "language": "c", 
     "name": "hpack_parser_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115954,6 +122440,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115976,6 +122463,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -115998,6 +122486,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116020,6 +122509,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116042,6 +122532,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116064,6 +122555,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116086,6 +122578,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116108,6 +122601,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116130,6 +122624,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116152,6 +122647,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116174,6 +122670,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116196,6 +122693,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116218,6 +122716,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116240,6 +122739,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116262,6 +122762,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116284,6 +122785,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116306,6 +122808,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116328,6 +122831,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116350,6 +122854,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116372,6 +122877,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116394,6 +122900,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116416,6 +122923,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116438,6 +122946,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116460,6 +122969,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116482,6 +122992,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116504,6 +123015,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116526,6 +123038,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116548,6 +123061,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116570,6 +123084,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116592,6 +123107,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116614,6 +123130,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116636,6 +123153,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116658,6 +123176,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116680,6 +123199,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116702,6 +123222,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116724,6 +123245,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116746,6 +123268,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116768,6 +123291,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116790,6 +123314,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116812,6 +123337,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116834,6 +123360,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116856,6 +123383,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116878,6 +123406,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116900,6 +123429,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116922,6 +123452,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116944,6 +123475,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116966,6 +123498,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -116988,6 +123521,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117010,6 +123544,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117032,6 +123567,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117054,6 +123590,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117076,6 +123613,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117098,6 +123636,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117120,6 +123659,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117142,6 +123682,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117164,6 +123705,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117186,6 +123728,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117208,6 +123751,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117230,6 +123774,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117252,6 +123797,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117274,6 +123820,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117296,6 +123843,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117318,6 +123866,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117340,6 +123889,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117362,6 +123912,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117384,6 +123935,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117406,6 +123958,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117428,6 +123981,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117450,6 +124004,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117472,6 +124027,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117494,6 +124050,7 @@
     "language": "c", 
     "name": "http_request_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117516,6 +124073,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117538,6 +124096,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117560,6 +124119,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117582,6 +124142,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117604,6 +124165,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117626,6 +124188,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117648,6 +124211,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117670,6 +124234,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117692,6 +124257,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117714,6 +124280,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117736,6 +124303,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117758,6 +124326,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117780,6 +124349,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117802,6 +124372,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117824,6 +124395,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117846,6 +124418,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117868,6 +124441,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117890,6 +124464,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117912,6 +124487,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117934,6 +124510,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117956,6 +124533,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -117978,6 +124556,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118000,6 +124579,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118022,6 +124602,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118044,6 +124625,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118066,6 +124648,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118088,6 +124671,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118110,6 +124694,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118132,6 +124717,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118154,6 +124740,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118176,6 +124763,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118198,6 +124786,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118220,6 +124809,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118242,6 +124832,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118264,6 +124855,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118286,6 +124878,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118308,6 +124901,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118330,6 +124924,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118352,6 +124947,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118374,6 +124970,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118396,6 +124993,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118418,6 +125016,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118440,6 +125039,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118462,6 +125062,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118484,6 +125085,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118506,6 +125108,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118528,6 +125131,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118550,6 +125154,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118572,6 +125177,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118594,6 +125200,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118616,6 +125223,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118638,6 +125246,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118660,6 +125269,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118682,6 +125292,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118704,6 +125315,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118726,6 +125338,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118748,6 +125361,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118770,6 +125384,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118792,6 +125407,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118814,6 +125430,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118836,6 +125453,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118858,6 +125476,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118880,6 +125499,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118902,6 +125522,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118924,6 +125545,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118946,6 +125568,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118968,6 +125591,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -118990,6 +125614,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119012,6 +125637,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119034,6 +125660,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119056,6 +125683,7 @@
     "language": "c", 
     "name": "http_response_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119078,6 +125706,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119100,6 +125729,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119122,6 +125752,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119144,6 +125775,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119166,6 +125798,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119188,6 +125821,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119210,6 +125844,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119232,6 +125867,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119254,6 +125890,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119276,6 +125913,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119298,6 +125936,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119320,6 +125959,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119342,6 +125982,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119364,6 +126005,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119386,6 +126028,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119408,6 +126051,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119430,6 +126074,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119452,6 +126097,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119474,6 +126120,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119496,6 +126143,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119518,6 +126166,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119540,6 +126189,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119562,6 +126212,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119584,6 +126235,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119606,6 +126258,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119628,6 +126281,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119650,6 +126304,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119672,6 +126327,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119694,6 +126350,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119716,6 +126373,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119738,6 +126396,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119760,6 +126419,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119782,6 +126442,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119804,6 +126465,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119826,6 +126488,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119848,6 +126511,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119870,6 +126534,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119892,6 +126557,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119914,6 +126580,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119936,6 +126603,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119958,6 +126626,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -119980,6 +126649,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120002,6 +126672,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120024,6 +126695,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120046,6 +126718,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120068,6 +126741,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120090,6 +126764,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120112,6 +126787,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120134,6 +126810,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120156,6 +126833,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120178,6 +126856,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120200,6 +126879,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120222,6 +126902,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120244,6 +126925,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120266,6 +126948,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120288,6 +126971,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120310,6 +126994,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120332,6 +127017,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120354,6 +127040,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120376,6 +127063,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120398,6 +127086,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120420,6 +127109,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120442,6 +127132,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120464,6 +127155,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120486,6 +127178,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120508,6 +127201,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120530,6 +127224,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120552,6 +127247,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120574,6 +127270,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120596,6 +127293,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120618,6 +127316,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120640,6 +127339,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120662,6 +127362,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120684,6 +127385,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120706,6 +127408,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120728,6 +127431,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120750,6 +127454,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120772,6 +127477,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120794,6 +127500,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120816,6 +127523,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120838,6 +127546,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120860,6 +127569,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120882,6 +127592,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120904,6 +127615,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120926,6 +127638,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120948,6 +127661,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120970,6 +127684,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -120992,6 +127707,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121014,6 +127730,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121036,6 +127753,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121058,6 +127776,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121080,6 +127799,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121102,6 +127822,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121124,6 +127845,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121146,6 +127868,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121168,6 +127891,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121190,6 +127914,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121212,6 +127937,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121234,6 +127960,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121256,6 +127983,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121278,6 +128006,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121300,6 +128029,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121322,6 +128052,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121344,6 +128075,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121366,6 +128098,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121388,6 +128121,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121410,6 +128144,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121432,6 +128167,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121454,6 +128190,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121476,6 +128213,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121498,6 +128236,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121520,6 +128259,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121542,6 +128282,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121564,6 +128305,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121586,6 +128328,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121608,6 +128351,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121630,6 +128374,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121652,6 +128397,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121674,6 +128420,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121696,6 +128443,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121718,6 +128466,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121740,6 +128489,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121762,6 +128512,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121784,6 +128535,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121806,6 +128558,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121828,6 +128581,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121850,6 +128604,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121872,6 +128627,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121894,6 +128650,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121916,6 +128673,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121938,6 +128696,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121960,6 +128719,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -121982,6 +128742,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122004,6 +128765,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122026,6 +128788,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122048,6 +128811,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122070,6 +128834,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122092,6 +128857,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122114,6 +128880,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122136,6 +128903,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122158,6 +128926,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122180,6 +128949,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122202,6 +128972,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122224,6 +128995,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122246,6 +129018,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122268,6 +129041,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122290,6 +129064,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122312,6 +129087,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122334,6 +129110,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122356,6 +129133,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122378,6 +129156,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122400,6 +129179,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122422,6 +129202,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122444,6 +129225,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122466,6 +129248,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122488,6 +129271,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122510,6 +129294,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122532,6 +129317,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122554,6 +129340,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122576,6 +129363,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122598,6 +129386,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122620,6 +129409,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122642,6 +129432,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122664,6 +129455,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122686,6 +129478,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122708,6 +129501,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122730,6 +129524,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122752,6 +129547,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122774,6 +129570,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122796,6 +129593,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122818,6 +129616,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122840,6 +129639,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122862,6 +129662,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122884,6 +129685,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122906,6 +129708,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122928,6 +129731,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122950,6 +129754,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122972,6 +129777,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -122994,6 +129800,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123016,6 +129823,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123038,6 +129846,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123060,6 +129869,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123082,6 +129892,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123104,6 +129915,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123126,6 +129938,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123148,6 +129961,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123170,6 +129984,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123192,6 +130007,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123214,6 +130030,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123236,6 +130053,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123258,6 +130076,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123280,6 +130099,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123302,6 +130122,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123324,6 +130145,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123346,6 +130168,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123368,6 +130191,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123390,6 +130214,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123412,6 +130237,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123434,6 +130260,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123456,6 +130283,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123478,6 +130306,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123500,6 +130329,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123522,6 +130352,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123544,6 +130375,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123566,6 +130398,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123588,6 +130421,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123610,6 +130444,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123632,6 +130467,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123654,6 +130490,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123676,6 +130513,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123698,6 +130536,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123720,6 +130559,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123742,6 +130582,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123764,6 +130605,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123786,6 +130628,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123808,6 +130651,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123830,6 +130674,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123852,6 +130697,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123874,6 +130720,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123896,6 +130743,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123918,6 +130766,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123940,6 +130789,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123962,6 +130812,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -123984,6 +130835,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124006,6 +130858,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124028,6 +130881,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124050,6 +130904,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124072,6 +130927,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124094,6 +130950,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124116,6 +130973,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124138,6 +130996,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124160,6 +131019,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124182,6 +131042,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124204,6 +131065,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124226,6 +131088,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124248,6 +131111,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124270,6 +131134,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124292,6 +131157,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124314,6 +131180,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124336,6 +131203,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124358,6 +131226,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124380,6 +131249,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124402,6 +131272,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124424,6 +131295,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124446,6 +131318,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124468,6 +131341,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124490,6 +131364,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124512,6 +131387,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124534,6 +131410,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124556,6 +131433,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124578,6 +131456,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124600,6 +131479,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124622,6 +131502,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124644,6 +131525,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124666,6 +131548,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124688,6 +131571,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124710,6 +131594,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124732,6 +131617,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124754,6 +131640,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124776,6 +131663,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124798,6 +131686,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124820,6 +131709,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124842,6 +131732,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124864,6 +131755,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124886,6 +131778,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124908,6 +131801,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124930,6 +131824,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124952,6 +131847,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124974,6 +131870,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -124996,6 +131893,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125018,6 +131916,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125040,6 +131939,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125062,6 +131962,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125084,6 +131985,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125106,6 +132008,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125128,6 +132031,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125150,6 +132054,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125172,6 +132077,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125194,6 +132100,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125216,6 +132123,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125238,6 +132146,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125260,6 +132169,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125282,6 +132192,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125304,6 +132215,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125326,6 +132238,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125348,6 +132261,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125370,6 +132284,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125392,6 +132307,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125414,6 +132330,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125436,6 +132353,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125458,6 +132376,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125480,6 +132399,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125502,6 +132422,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125524,6 +132445,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125546,6 +132468,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125568,6 +132491,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125590,6 +132514,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125612,6 +132537,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125634,6 +132560,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125656,6 +132583,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125678,6 +132606,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125700,6 +132629,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125722,6 +132652,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125744,6 +132675,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125766,6 +132698,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125788,6 +132721,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125810,6 +132744,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125832,6 +132767,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125854,6 +132790,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125876,6 +132813,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125898,6 +132836,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125920,6 +132859,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125942,6 +132882,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125964,6 +132905,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -125986,6 +132928,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126008,6 +132951,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126030,6 +132974,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126052,6 +132997,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126074,6 +133020,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126096,6 +133043,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126118,6 +133066,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126140,6 +133089,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126162,6 +133112,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126184,6 +133135,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126206,6 +133158,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126228,6 +133181,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126250,6 +133204,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126272,6 +133227,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126294,6 +133250,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126316,6 +133273,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126338,6 +133296,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126360,6 +133319,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126382,6 +133342,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126404,6 +133365,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126426,6 +133388,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126448,6 +133411,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126470,6 +133434,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126492,6 +133457,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126514,6 +133480,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126536,6 +133503,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126558,6 +133526,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126580,6 +133549,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126602,6 +133572,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126624,6 +133595,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126646,6 +133618,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126668,6 +133641,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126690,6 +133664,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126712,6 +133687,7 @@
     "language": "c", 
     "name": "json_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126734,6 +133710,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126756,6 +133733,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126778,6 +133756,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126800,6 +133779,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126822,6 +133802,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126844,6 +133825,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126866,6 +133848,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126888,6 +133871,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126910,6 +133894,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126932,6 +133917,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126954,6 +133940,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126976,6 +133963,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -126998,6 +133986,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127020,6 +134009,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127042,6 +134032,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127064,6 +134055,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127086,6 +134078,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127108,6 +134101,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127130,6 +134124,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127152,6 +134147,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127174,6 +134170,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127196,6 +134193,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127218,6 +134216,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127240,6 +134239,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127262,6 +134262,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127284,6 +134285,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127306,6 +134308,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127328,6 +134331,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127350,6 +134354,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127372,6 +134377,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127394,6 +134400,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127416,6 +134423,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127438,6 +134446,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127460,6 +134469,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127482,6 +134492,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127504,6 +134515,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127526,6 +134538,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127548,6 +134561,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127570,6 +134584,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127592,6 +134607,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127614,6 +134630,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127636,6 +134653,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127658,6 +134676,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127680,6 +134699,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127702,6 +134722,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127724,6 +134745,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127746,6 +134768,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127768,6 +134791,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127790,6 +134814,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127812,6 +134837,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127834,6 +134860,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127856,6 +134883,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127878,6 +134906,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127900,6 +134929,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127922,6 +134952,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127944,6 +134975,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127966,6 +134998,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -127988,6 +135021,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128010,6 +135044,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128032,6 +135067,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128054,6 +135090,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128076,6 +135113,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128098,6 +135136,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128120,6 +135159,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128142,6 +135182,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128164,6 +135205,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128186,6 +135228,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128208,6 +135251,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128230,6 +135274,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128252,6 +135297,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128274,6 +135320,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128296,6 +135343,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128318,6 +135366,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128340,6 +135389,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128362,6 +135412,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128384,6 +135435,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128406,6 +135458,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128428,6 +135481,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128450,6 +135504,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128472,6 +135527,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128494,6 +135550,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128516,6 +135573,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128538,6 +135596,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128560,6 +135619,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128582,6 +135642,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_response_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128604,6 +135665,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128626,6 +135688,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128648,6 +135711,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128670,6 +135734,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128692,6 +135757,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128714,6 +135780,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128736,6 +135803,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128758,6 +135826,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128780,6 +135849,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128802,6 +135872,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128824,6 +135895,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128846,6 +135918,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128868,6 +135941,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128890,6 +135964,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128912,6 +135987,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128934,6 +136010,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128956,6 +136033,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -128978,6 +136056,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129000,6 +136079,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129022,6 +136102,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129044,6 +136125,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129066,6 +136148,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129088,6 +136171,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129110,6 +136194,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129132,6 +136217,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129154,6 +136240,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129176,6 +136263,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129198,6 +136286,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129220,6 +136309,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129242,6 +136332,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129264,6 +136355,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129286,6 +136378,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129308,6 +136401,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129330,6 +136424,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129352,6 +136447,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129374,6 +136470,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129396,6 +136493,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129418,6 +136516,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129440,6 +136539,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129462,6 +136562,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129484,6 +136585,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129506,6 +136608,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129528,6 +136631,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129550,6 +136654,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129572,6 +136677,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129594,6 +136700,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129616,6 +136723,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129638,6 +136746,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129660,6 +136769,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129682,6 +136792,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129704,6 +136815,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129726,6 +136838,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129748,6 +136861,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129770,6 +136884,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129792,6 +136907,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129814,6 +136930,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129836,6 +136953,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129858,6 +136976,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129880,6 +136999,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129902,6 +137022,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129924,6 +137045,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129946,6 +137068,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129968,6 +137091,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -129990,6 +137114,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130012,6 +137137,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130034,6 +137160,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130056,6 +137183,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130078,6 +137206,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130100,6 +137229,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130122,6 +137252,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130144,6 +137275,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130166,6 +137298,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130188,6 +137321,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130210,6 +137344,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130232,6 +137367,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130254,6 +137390,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130276,6 +137413,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130298,6 +137436,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130320,6 +137459,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130342,6 +137482,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130364,6 +137505,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130386,6 +137528,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130408,6 +137551,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130430,6 +137574,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130452,6 +137597,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130474,6 +137620,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130496,6 +137643,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130518,6 +137666,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130540,6 +137689,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130562,6 +137712,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130584,6 +137735,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130606,6 +137758,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130628,6 +137781,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130650,6 +137804,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130672,6 +137827,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130694,6 +137850,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130716,6 +137873,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130738,6 +137896,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130760,6 +137919,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130782,6 +137942,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130804,6 +137965,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130826,6 +137988,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130848,6 +138011,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130870,6 +138034,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130892,6 +138057,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130914,6 +138080,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130936,6 +138103,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130958,6 +138126,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -130980,6 +138149,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131002,6 +138172,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131024,6 +138195,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131046,6 +138218,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131068,6 +138241,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131090,6 +138264,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131112,6 +138287,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131134,6 +138310,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131156,6 +138333,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131178,6 +138356,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131200,6 +138379,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131222,6 +138402,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131244,6 +138425,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131266,6 +138448,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131288,6 +138471,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131310,6 +138494,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131332,6 +138517,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131354,6 +138540,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131376,6 +138563,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131398,6 +138586,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131420,6 +138609,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131442,6 +138632,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131464,6 +138655,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131486,6 +138678,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131508,6 +138701,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131530,6 +138724,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131552,6 +138747,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131574,6 +138770,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131596,6 +138793,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131618,6 +138816,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131640,6 +138839,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131662,6 +138862,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131684,6 +138885,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131706,6 +138908,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131728,6 +138931,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131750,6 +138954,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131772,6 +138977,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131794,6 +139000,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131816,6 +139023,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131838,6 +139046,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131860,6 +139069,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131882,6 +139092,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131904,6 +139115,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131926,6 +139138,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131948,6 +139161,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131970,6 +139184,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -131992,6 +139207,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132014,6 +139230,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132036,6 +139253,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132058,6 +139276,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132080,6 +139299,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132102,6 +139322,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132124,6 +139345,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132146,6 +139368,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132168,6 +139391,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132190,6 +139414,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132212,6 +139437,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132234,6 +139460,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132256,6 +139483,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132278,6 +139506,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132300,6 +139529,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132322,6 +139552,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132344,6 +139575,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132366,6 +139598,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132388,6 +139621,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132410,6 +139644,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132432,6 +139667,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132454,6 +139690,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132476,6 +139713,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132498,6 +139736,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132520,6 +139759,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132542,6 +139782,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132564,6 +139805,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132586,6 +139828,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132608,6 +139851,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132630,6 +139874,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132652,6 +139897,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132674,6 +139920,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132696,6 +139943,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132718,6 +139966,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132740,6 +139989,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132762,6 +140012,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132784,6 +140035,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132806,6 +140058,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132828,6 +140081,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132850,6 +140104,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132872,6 +140127,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132894,6 +140150,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132916,6 +140173,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132938,6 +140196,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132960,6 +140219,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -132982,6 +140242,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133004,6 +140265,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133026,6 +140288,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133048,6 +140311,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133070,6 +140334,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133092,6 +140357,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133114,6 +140380,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133136,6 +140403,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133158,6 +140426,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133180,6 +140449,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133202,6 +140472,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133224,6 +140495,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133246,6 +140518,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133268,6 +140541,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133290,6 +140564,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133312,6 +140587,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133334,6 +140610,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133356,6 +140633,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133378,6 +140656,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133400,6 +140679,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133422,6 +140702,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133444,6 +140725,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133466,6 +140748,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133488,6 +140771,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133510,6 +140794,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133532,6 +140817,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133554,6 +140840,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133576,6 +140863,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133598,6 +140886,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133620,6 +140909,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133642,6 +140932,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133664,6 +140955,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133686,6 +140978,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133708,6 +141001,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133730,6 +141024,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133752,6 +141047,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133774,6 +141070,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133796,6 +141093,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133818,6 +141116,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133840,6 +141139,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133862,6 +141162,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133884,6 +141185,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133906,6 +141208,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133928,6 +141231,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133950,6 +141254,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133972,6 +141277,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -133994,6 +141300,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134016,6 +141323,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134038,6 +141346,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134060,6 +141369,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134082,6 +141392,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134104,6 +141415,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134126,6 +141438,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134148,6 +141461,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134170,6 +141484,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134192,6 +141507,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134214,6 +141530,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134236,6 +141553,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134258,6 +141576,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134280,6 +141599,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134302,6 +141622,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134324,6 +141645,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134346,6 +141668,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134368,6 +141691,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134390,6 +141714,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134412,6 +141737,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134434,6 +141760,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134456,6 +141783,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134478,6 +141806,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134500,6 +141829,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134522,6 +141852,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134544,6 +141875,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134566,6 +141898,7 @@
     "language": "c", 
     "name": "nanopb_fuzzer_serverlist_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134588,6 +141921,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134610,6 +141944,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134632,6 +141967,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134654,6 +141990,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134676,6 +142013,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134698,6 +142036,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134720,6 +142059,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134742,6 +142082,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134764,6 +142105,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134786,6 +142128,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134808,6 +142151,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134830,6 +142174,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134852,6 +142197,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134874,6 +142220,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134896,6 +142243,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134918,6 +142266,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134940,6 +142289,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134962,6 +142312,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -134984,6 +142335,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135006,6 +142358,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135028,6 +142381,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135050,6 +142404,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135072,6 +142427,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135094,6 +142450,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135116,6 +142473,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135138,6 +142496,7 @@
     "language": "c", 
     "name": "percent_decode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135160,6 +142519,7 @@
     "language": "c", 
     "name": "percent_encode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135182,6 +142542,7 @@
     "language": "c", 
     "name": "percent_encode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135204,6 +142565,7 @@
     "language": "c", 
     "name": "percent_encode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135226,6 +142588,7 @@
     "language": "c", 
     "name": "percent_encode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135248,6 +142611,7 @@
     "language": "c", 
     "name": "percent_encode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135270,6 +142634,7 @@
     "language": "c", 
     "name": "percent_encode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135292,6 +142657,7 @@
     "language": "c", 
     "name": "percent_encode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135314,6 +142680,7 @@
     "language": "c", 
     "name": "percent_encode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135336,6 +142703,7 @@
     "language": "c", 
     "name": "percent_encode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135358,6 +142726,7 @@
     "language": "c", 
     "name": "percent_encode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135380,6 +142749,7 @@
     "language": "c", 
     "name": "percent_encode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135402,6 +142772,7 @@
     "language": "c", 
     "name": "percent_encode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135424,6 +142795,7 @@
     "language": "c", 
     "name": "percent_encode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135446,6 +142818,7 @@
     "language": "c", 
     "name": "percent_encode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135468,6 +142841,7 @@
     "language": "c", 
     "name": "percent_encode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135490,6 +142864,7 @@
     "language": "c", 
     "name": "percent_encode_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135512,6 +142887,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135534,6 +142910,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135556,6 +142933,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135578,6 +142956,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135600,6 +142979,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135622,6 +143002,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135644,6 +143025,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135666,6 +143048,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135688,6 +143071,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135710,6 +143094,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135732,6 +143117,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135754,6 +143140,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135776,6 +143163,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135798,6 +143186,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135820,6 +143209,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135842,6 +143232,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135864,6 +143255,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135886,6 +143278,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135908,6 +143301,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135930,6 +143324,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135952,6 +143347,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135974,6 +143370,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -135996,6 +143393,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136018,6 +143416,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136040,6 +143439,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136062,6 +143462,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136084,6 +143485,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136106,6 +143508,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136128,6 +143531,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136150,6 +143554,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136172,6 +143577,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136194,6 +143600,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136216,6 +143623,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136238,6 +143646,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136260,6 +143669,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136282,6 +143692,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136304,6 +143715,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136326,6 +143738,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136348,6 +143761,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136370,6 +143784,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136392,6 +143807,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136414,6 +143830,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136436,6 +143853,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136458,6 +143876,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136480,6 +143899,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136502,6 +143922,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136524,6 +143945,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136546,6 +143968,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136568,6 +143991,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136590,6 +144014,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136612,6 +144037,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136634,6 +144060,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136656,6 +144083,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136678,6 +144106,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136700,6 +144129,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136722,6 +144152,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136744,6 +144175,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136766,6 +144198,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136788,6 +144221,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136810,6 +144244,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136832,6 +144267,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136854,6 +144290,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136876,6 +144313,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136898,6 +144336,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136920,6 +144359,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136942,6 +144382,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136964,6 +144405,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -136986,6 +144428,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137008,6 +144451,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137030,6 +144474,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137052,6 +144497,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137074,6 +144520,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137096,6 +144543,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137118,6 +144566,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137140,6 +144589,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137162,6 +144612,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137184,6 +144635,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137206,6 +144658,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137228,6 +144681,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137250,6 +144704,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137272,6 +144727,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137294,6 +144750,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137316,6 +144773,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137338,6 +144796,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137360,6 +144819,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137382,6 +144842,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137404,6 +144865,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137426,6 +144888,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137448,6 +144911,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137470,6 +144934,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137492,6 +144957,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137514,6 +144980,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137536,6 +145003,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137558,6 +145026,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137580,6 +145049,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137602,6 +145072,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137624,6 +145095,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137646,6 +145118,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137668,6 +145141,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137690,6 +145164,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137712,6 +145187,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137734,6 +145210,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137756,6 +145233,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137778,6 +145256,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137800,6 +145279,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137822,6 +145302,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137844,6 +145325,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137866,6 +145348,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137888,6 +145371,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137910,6 +145394,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137932,6 +145417,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137954,6 +145440,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137976,6 +145463,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -137998,6 +145486,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138020,6 +145509,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138042,6 +145532,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138064,6 +145555,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138086,6 +145578,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138108,6 +145601,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138130,6 +145624,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138152,6 +145647,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138174,6 +145670,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138196,6 +145693,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138218,6 +145716,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138240,6 +145739,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138262,6 +145762,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138284,6 +145785,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138306,6 +145808,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138328,6 +145831,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138350,6 +145854,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138372,6 +145877,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138394,6 +145900,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138416,6 +145923,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138438,6 +145946,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138460,6 +145969,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138482,6 +145992,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138504,6 +146015,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138526,6 +146038,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138548,6 +146061,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138570,6 +146084,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138592,6 +146107,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138614,6 +146130,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138636,6 +146153,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138658,6 +146176,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138680,6 +146199,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138702,6 +146222,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138724,6 +146245,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138746,6 +146268,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138768,6 +146291,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138790,6 +146314,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138812,6 +146337,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138834,6 +146360,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138856,6 +146383,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138878,6 +146406,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138900,6 +146429,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138922,6 +146452,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138944,6 +146475,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138966,6 +146498,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -138988,6 +146521,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139010,6 +146544,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139032,6 +146567,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139054,6 +146590,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139076,6 +146613,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139098,6 +146636,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139120,6 +146659,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139142,6 +146682,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139164,6 +146705,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139186,6 +146728,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139208,6 +146751,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139230,6 +146774,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139252,6 +146797,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139274,6 +146820,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139296,6 +146843,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139318,6 +146866,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139340,6 +146889,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139362,6 +146912,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139384,6 +146935,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139406,6 +146958,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139428,6 +146981,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139450,6 +147004,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139472,6 +147027,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139494,6 +147050,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139516,6 +147073,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139538,6 +147096,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139560,6 +147119,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139582,6 +147142,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139604,6 +147165,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139626,6 +147188,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139648,6 +147211,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139670,6 +147234,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139692,6 +147257,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139714,6 +147280,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139736,6 +147303,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139758,6 +147326,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139780,6 +147349,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139802,6 +147372,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139824,6 +147395,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139846,6 +147418,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139868,6 +147441,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139890,6 +147464,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139912,6 +147487,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139934,6 +147510,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139956,6 +147533,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -139978,6 +147556,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140000,6 +147579,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140022,6 +147602,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140044,6 +147625,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140066,6 +147648,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140088,6 +147671,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140110,6 +147694,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140132,6 +147717,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140154,6 +147740,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140176,6 +147763,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140198,6 +147786,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140220,6 +147809,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140242,6 +147832,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140264,6 +147855,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140286,6 +147878,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140308,6 +147901,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140330,6 +147924,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140352,6 +147947,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140374,6 +147970,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140396,6 +147993,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140418,6 +148016,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140440,6 +148039,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140462,6 +148062,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140484,6 +148085,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140506,6 +148108,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140528,6 +148131,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140550,6 +148154,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140572,6 +148177,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140594,6 +148200,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140616,6 +148223,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140638,6 +148246,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140660,6 +148269,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140682,6 +148292,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140704,6 +148315,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140726,6 +148338,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140748,6 +148361,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140770,6 +148384,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140792,6 +148407,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140814,6 +148430,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140836,6 +148453,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140858,6 +148476,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140880,6 +148499,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140902,6 +148522,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140924,6 +148545,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140946,6 +148568,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140968,6 +148591,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -140990,6 +148614,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141012,6 +148637,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141034,6 +148660,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141056,6 +148683,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141078,6 +148706,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141100,6 +148729,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141122,6 +148752,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141144,6 +148775,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141166,6 +148798,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141188,6 +148821,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141210,6 +148844,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141232,6 +148867,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141254,6 +148890,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141276,6 +148913,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141298,6 +148936,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141320,6 +148959,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141342,6 +148982,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141364,6 +149005,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141386,6 +149028,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141408,6 +149051,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141430,6 +149074,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141452,6 +149097,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141474,6 +149120,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141496,6 +149143,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141518,6 +149166,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141540,6 +149189,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141562,6 +149212,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141584,6 +149235,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141606,6 +149258,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141628,6 +149281,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141650,6 +149304,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141672,6 +149327,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141694,6 +149350,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141716,6 +149373,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141738,6 +149396,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141760,6 +149419,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141782,6 +149442,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141804,6 +149465,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141826,6 +149488,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141848,6 +149511,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141870,6 +149534,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141892,6 +149557,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141914,6 +149580,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141936,6 +149603,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141958,6 +149626,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -141980,6 +149649,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142002,6 +149672,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142024,6 +149695,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142046,6 +149718,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142068,6 +149741,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142090,6 +149764,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142112,6 +149787,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142134,6 +149810,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142156,6 +149833,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142178,6 +149856,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142200,6 +149879,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142222,6 +149902,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142244,6 +149925,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142266,6 +149948,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142288,6 +149971,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142310,6 +149994,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142332,6 +150017,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142354,6 +150040,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142376,6 +150063,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142398,6 +150086,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142420,6 +150109,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142442,6 +150132,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142464,6 +150155,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142486,6 +150178,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142508,6 +150201,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142530,6 +150224,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142552,6 +150247,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142574,6 +150270,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142596,6 +150293,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142618,6 +150316,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142640,6 +150339,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142662,6 +150362,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142684,6 +150385,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142706,6 +150408,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142728,6 +150431,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142750,6 +150454,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142772,6 +150477,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142794,6 +150500,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142816,6 +150523,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142838,6 +150546,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142860,6 +150569,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142882,6 +150592,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142904,6 +150615,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142926,6 +150638,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142948,6 +150661,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142970,6 +150684,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -142992,6 +150707,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143014,6 +150730,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143036,6 +150753,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143058,6 +150776,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143080,6 +150799,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143102,6 +150822,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143124,6 +150845,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143146,6 +150868,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143168,6 +150891,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143190,6 +150914,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143212,6 +150937,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143234,6 +150960,76 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/clusterfuzz-testcase-5417405008314368"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "mac", 
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/clusterfuzz-testcase-5595941564317696"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "mac", 
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/clusterfuzz-testcase-6312731374256128"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143256,6 +151052,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143278,6 +151075,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143300,6 +151098,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143322,6 +151121,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143344,6 +151144,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143366,6 +151167,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143388,6 +151190,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143410,6 +151213,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143432,6 +151236,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143454,6 +151259,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143476,6 +151282,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143498,6 +151305,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143520,6 +151328,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143542,6 +151351,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143564,6 +151374,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143586,6 +151397,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143608,6 +151420,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143630,6 +151443,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143652,6 +151466,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143674,6 +151489,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143696,6 +151512,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143718,6 +151535,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143740,6 +151558,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143762,6 +151581,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143784,6 +151604,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143806,6 +151627,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143828,6 +151650,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143850,6 +151673,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143872,6 +151696,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143894,6 +151719,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143916,6 +151742,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143938,6 +151765,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143960,6 +151788,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -143982,6 +151811,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144004,6 +151834,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144026,6 +151857,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144048,6 +151880,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144070,6 +151903,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144092,6 +151926,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144114,6 +151949,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144136,6 +151972,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144158,6 +151995,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144180,6 +152018,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144202,6 +152041,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144224,6 +152064,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144246,6 +152087,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144268,6 +152110,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144290,6 +152133,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144312,6 +152156,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144334,6 +152179,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144356,6 +152202,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144378,6 +152225,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144400,6 +152248,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144422,6 +152271,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144444,6 +152294,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144466,6 +152317,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144488,6 +152340,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144510,6 +152363,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144532,6 +152386,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144554,6 +152409,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144576,6 +152432,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144598,6 +152455,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144620,6 +152478,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144642,6 +152501,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144664,6 +152524,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144686,6 +152547,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144708,6 +152570,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144730,6 +152593,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144752,6 +152616,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144774,6 +152639,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144796,6 +152662,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144818,6 +152685,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144840,6 +152708,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144862,6 +152731,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144884,6 +152754,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144906,6 +152777,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144928,6 +152800,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144950,6 +152823,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144972,6 +152846,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -144994,6 +152869,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145016,6 +152892,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145038,6 +152915,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145060,6 +152938,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145082,6 +152961,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145104,6 +152984,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145126,6 +153007,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145148,6 +153030,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145170,6 +153053,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145192,6 +153076,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145214,6 +153099,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145236,6 +153122,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145258,6 +153145,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145280,6 +153168,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145302,6 +153191,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145324,6 +153214,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145346,6 +153237,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145368,6 +153260,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145390,6 +153283,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145412,6 +153306,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145434,6 +153329,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145456,6 +153352,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145478,6 +153375,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145500,6 +153398,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145522,6 +153421,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145544,6 +153444,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145566,6 +153467,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145588,6 +153490,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145610,6 +153513,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145632,6 +153536,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145654,6 +153559,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145676,6 +153582,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145698,6 +153605,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145720,6 +153628,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145742,6 +153651,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145764,6 +153674,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145786,6 +153697,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145808,6 +153720,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145830,6 +153743,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145852,6 +153766,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145874,6 +153789,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145896,6 +153812,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145918,6 +153835,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145940,6 +153858,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145962,6 +153881,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -145984,6 +153904,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146006,6 +153927,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146028,6 +153950,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146050,6 +153973,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146072,6 +153996,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146094,6 +154019,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146116,6 +154042,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146138,6 +154065,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146160,6 +154088,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146182,6 +154111,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146204,6 +154134,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146226,6 +154157,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146248,6 +154180,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146270,6 +154203,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146292,6 +154226,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146314,6 +154249,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146336,6 +154272,7 @@
     "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146358,6 +154295,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146380,6 +154318,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146402,6 +154341,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146424,6 +154364,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146446,6 +154387,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146468,6 +154410,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146490,6 +154433,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146512,6 +154456,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146534,6 +154479,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146556,6 +154502,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146578,6 +154525,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146600,6 +154548,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146622,6 +154571,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146644,6 +154594,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146666,6 +154617,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146688,6 +154640,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146710,6 +154663,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146732,6 +154686,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146754,6 +154709,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146776,6 +154732,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146798,6 +154755,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146820,6 +154778,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146842,6 +154801,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146864,6 +154824,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146886,6 +154847,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146908,6 +154870,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146930,6 +154893,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146952,6 +154916,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146974,6 +154939,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -146996,6 +154962,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147018,6 +154985,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147040,6 +155008,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147062,6 +155031,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147084,6 +155054,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147106,6 +155077,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147128,6 +155100,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147150,6 +155123,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147172,6 +155146,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147194,6 +155169,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147216,6 +155192,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147238,6 +155215,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147260,6 +155238,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147282,6 +155261,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147304,6 +155284,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147326,6 +155307,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147348,6 +155330,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147370,6 +155353,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147392,6 +155376,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147414,6 +155399,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147436,6 +155422,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147458,6 +155445,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147480,6 +155468,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147502,6 +155491,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147524,6 +155514,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147546,6 +155537,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147568,6 +155560,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147590,6 +155583,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147612,6 +155606,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147634,6 +155629,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147656,6 +155652,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147678,6 +155675,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147700,6 +155698,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147722,6 +155721,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147744,6 +155744,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147766,6 +155767,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147788,6 +155790,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147810,6 +155813,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147832,6 +155836,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147854,6 +155859,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147876,6 +155882,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147898,6 +155905,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147920,6 +155928,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147942,6 +155951,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147964,6 +155974,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -147986,6 +155997,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148008,6 +156020,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148030,6 +156043,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148052,6 +156066,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148074,6 +156089,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148096,6 +156112,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148118,6 +156135,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148140,6 +156158,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148162,6 +156181,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148184,6 +156204,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148206,6 +156227,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148228,6 +156250,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148250,6 +156273,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148272,6 +156296,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148294,6 +156319,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148316,6 +156342,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148338,6 +156365,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148360,6 +156388,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148382,6 +156411,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148404,6 +156434,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148426,6 +156457,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148448,6 +156480,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148470,6 +156503,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148492,6 +156526,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148514,6 +156549,7 @@
     "language": "c", 
     "name": "ssl_server_fuzzer_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148536,6 +156572,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148558,6 +156595,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148580,6 +156618,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148602,6 +156641,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148624,6 +156664,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148646,6 +156687,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148668,6 +156710,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148690,6 +156733,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148712,6 +156756,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148734,6 +156779,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148756,6 +156802,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148778,6 +156825,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148800,6 +156848,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148822,6 +156871,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148844,6 +156894,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148866,6 +156917,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148888,6 +156940,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148910,6 +156963,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148932,6 +156986,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148954,6 +157009,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148976,6 +157032,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -148998,6 +157055,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149020,6 +157078,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149042,6 +157101,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149064,6 +157124,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149086,6 +157147,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149108,6 +157170,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149130,6 +157193,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149152,6 +157216,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149174,6 +157239,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149196,6 +157262,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149218,6 +157285,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149240,6 +157308,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149262,6 +157331,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149284,6 +157354,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149306,6 +157377,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149328,6 +157400,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149350,6 +157423,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149372,6 +157446,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149394,6 +157469,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149416,6 +157492,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149438,6 +157515,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149460,6 +157538,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149482,6 +157561,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149504,6 +157584,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149526,6 +157607,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149548,6 +157630,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149570,6 +157653,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149592,6 +157676,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149614,6 +157699,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149636,6 +157722,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149658,6 +157745,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149680,6 +157768,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149702,6 +157791,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149724,6 +157814,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149746,6 +157837,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149768,6 +157860,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149790,6 +157883,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149812,6 +157906,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149834,6 +157929,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149856,6 +157952,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149878,6 +157975,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
@@ -149900,6 +157998,7 @@
     "language": "c", 
     "name": "uri_fuzzer_test_one_entry", 
     "platforms": [
+      "mac", 
       "linux"
     ], 
     "uses_polling": false
diff --git a/tools/run_tests/helper_scripts/build_csharp_coreclr.bat b/tools/run_tests/helper_scripts/build_csharp.bat
similarity index 93%
rename from tools/run_tests/helper_scripts/build_csharp_coreclr.bat
rename to tools/run_tests/helper_scripts/build_csharp.bat
index 78e5f5998b810db19483d003618e2392bdf445c5..05ea78564c4d9ed02b24d893e11df2e8b3235c62 100644
--- a/tools/run_tests/helper_scripts/build_csharp_coreclr.bat
+++ b/tools/run_tests/helper_scripts/build_csharp.bat
@@ -31,9 +31,7 @@ setlocal
 
 cd /d %~dp0\..\..\..\src\csharp
 
-dotnet restore . || goto :error
-
-dotnet build --configuration %MSBUILD_CONFIG% "**/project.json" || goto :error
+dotnet build --configuration %MSBUILD_CONFIG% Grpc.sln || goto :error
 
 endlocal
 
diff --git a/tools/run_tests/helper_scripts/build_csharp.sh b/tools/run_tests/helper_scripts/build_csharp.sh
index 84c5b1c77786969fc9cf930613c6a35ffcda2eb2..a7562a7f4a374954ced9e7dc0ebd5444b3070393 100755
--- a/tools/run_tests/helper_scripts/build_csharp.sh
+++ b/tools/run_tests/helper_scripts/build_csharp.sh
@@ -32,5 +32,10 @@ set -ex
 
 cd $(dirname $0)/../../../src/csharp
 
-# overriding NativeDependenciesConfigurationUnix is needed to make gcov code coverage work.
-xbuild /p:Configuration=$MSBUILD_CONFIG /p:NativeDependenciesConfigurationUnix=$CONFIG Grpc.sln
+if [ "$CONFIG" == "gcov" ]
+then
+  # overriding NativeDependenciesConfigurationUnix makes C# project pick up the gcov flavor of grpc_csharp_ext
+  dotnet build --configuration $MSBUILD_CONFIG /p:NativeDependenciesConfigurationUnix=gcov Grpc.sln
+else
+  dotnet build --configuration $MSBUILD_CONFIG Grpc.sln
+fi
diff --git a/tools/run_tests/helper_scripts/build_node.sh b/tools/run_tests/helper_scripts/build_node.sh
index df3acdac2b4eb72989dd4aed642896ff56926d81..07ecf98396aa725b2bb886026e1e1933e7bbfbb1 100755
--- a/tools/run_tests/helper_scripts/build_node.sh
+++ b/tools/run_tests/helper_scripts/build_node.sh
@@ -41,10 +41,9 @@ CONFIG=${CONFIG:-opt}
 cd $(dirname $0)/../../..
 
 case "$CONFIG" in
-  'dbg') config_flag='--debug' ;;
+  'dbg') config_flags='--debug' ;;
+  'gcov') config_flags="--debug --grpc_gcov=true" ;;
   *) config_flag='--release' ;;
 esac
 
-uv_flag=$2
-
-npm install --unsafe-perm --build-from-source $uv_flag $config_flag
+npm install --unsafe-perm --build-from-source $config_flag
diff --git a/tools/run_tests/helper_scripts/build_python.sh b/tools/run_tests/helper_scripts/build_python.sh
index 5647d9c2fcb3569b1bab631b8c39bdffc8e52493..28397be13ef8ff5cbcfe9d95612758c6b3faa915 100755
--- a/tools/run_tests/helper_scripts/build_python.sh
+++ b/tools/run_tests/helper_scripts/build_python.sh
@@ -155,7 +155,7 @@ fi
 ($PYTHON -m virtualenv $VENV ||
  $HOST_PYTHON -m virtualenv -p $PYTHON $VENV ||
  true)
-VENV_PYTHON=`script_realpath -s "$VENV/$VENV_RELATIVE_PYTHON"`
+VENV_PYTHON=`script_realpath "$VENV/$VENV_RELATIVE_PYTHON"`
 
 # pip-installs the directory specified. Used because on MSYS the vanilla Windows
 # Python gets confused when parsing paths.
diff --git a/tools/run_tests/helper_scripts/post_tests_php.sh b/tools/run_tests/helper_scripts/post_tests_php.sh
index 23dc202322fdb4d2d8927b4893342fbeb9e04068..43b665e23ee207650ebb5405fcadf0bc2226ee02 100755
--- a/tools/run_tests/helper_scripts/post_tests_php.sh
+++ b/tools/run_tests/helper_scripts/post_tests_php.sh
@@ -43,4 +43,4 @@ genhtml $tmp2 --output-directory $out
 rm $tmp2
 rm $tmp1
 
-cp -rv $root/src/php/coverage $root/reports/php
+# todo(mattkwong): generate coverage report for php and copy to reports/php
diff --git a/tools/internal_ci/linux/grpc_fuzzer_uri.sh b/tools/run_tests/helper_scripts/post_tests_python.sh
similarity index 86%
rename from tools/internal_ci/linux/grpc_fuzzer_uri.sh
rename to tools/run_tests/helper_scripts/post_tests_python.sh
index 67039f38807ebc992edb4f4d6ba15bc77dfa6620..4f5986b3a1a0ecf9a11dca6e15c846c40a303a55 100755
--- a/tools/internal_ci/linux/grpc_fuzzer_uri.sh
+++ b/tools/run_tests/helper_scripts/post_tests_python.sh
@@ -30,11 +30,10 @@
 
 set -ex
 
-# change to grpc repo root
-cd $(dirname $0)/../../..
+if [ "$CONFIG" != "gcov" ] ; then exit ; fi
 
-git submodule update --init
+# change to directory of Python coverage files
+cd $(dirname $0)/../../../src/python/grpcio_tests/
 
-# download fuzzer docker image from dockerhub
-export DOCKERHUB_ORGANIZATION=grpctesting
-config=asan-trace-cmp tools/jenkins/run_fuzzer.sh uri_fuzzer_test
+coverage combine .
+coverage html -i -d ./../../../reports/python
diff --git a/tools/run_tests/helper_scripts/pre_build_cmake.bat b/tools/run_tests/helper_scripts/pre_build_cmake.bat
index c937b9e09f849203705694d32adbdb6a0b4ed066..c721e1624db33e98f93902f96ff07d063d758f28 100644
--- a/tools/run_tests/helper_scripts/pre_build_cmake.bat
+++ b/tools/run_tests/helper_scripts/pre_build_cmake.bat
@@ -37,7 +37,10 @@ mkdir build
 cd build
 
 @rem TODO(jtattermusch): Stop hardcoding path to yasm once Jenkins workers can locate yasm correctly
-cmake -G "Visual Studio 14 2015" -DgRPC_BUILD_TESTS=ON -DCMAKE_ASM_NASM_COMPILER="C:/Program Files (x86)/yasm/yasm.exe" ../.. || goto :error
+@rem If yasm is not on the path, use hardcoded path instead.
+yasm --version || set USE_HARDCODED_YASM_PATH_MAYBE=-DCMAKE_ASM_NASM_COMPILER="C:/Program Files (x86)/yasm/yasm.exe"
+
+cmake -G "Visual Studio 14 2015" -DgRPC_BUILD_TESTS=ON %USE_HARDCODED_YASM_PATH_MAYBE% ../.. || goto :error
 
 endlocal
 
diff --git a/tools/run_tests/helper_scripts/pre_build_csharp.bat b/tools/run_tests/helper_scripts/pre_build_csharp.bat
index f37f63b58404556e5ad2fe6df066ec081e79745f..47ebd8bee3f8b9f5a975d5b80abd41d1d917afbd 100644
--- a/tools/run_tests/helper_scripts/pre_build_csharp.bat
+++ b/tools/run_tests/helper_scripts/pre_build_csharp.bat
@@ -42,70 +42,16 @@ mkdir build
 cd build
 mkdir %ARCHITECTURE%
 cd %ARCHITECTURE%
-@rem TODO(jtattermusch): Stop hardcoding path to yasm once Jenkins workers can locate yasm correctly
-cmake -G "Visual Studio 14 2015" -A %ARCHITECTURE% -DgRPC_BUILD_TESTS=OFF -DCMAKE_ASM_NASM_COMPILER="C:/Program Files (x86)/yasm/yasm.exe" ../../.. || goto :error
-cd ..\..\..
-
-@rem Location of nuget.exe
-set NUGET=C:\nuget\nuget.exe
-
-if exist %NUGET% (
-  @rem TODO(jtattermusch): Get rid of this hack. See #8034
-  @rem Restore Grpc packages by packages since Nuget client 3.4.4 doesnt support restore
-  @rem by solution
-  @rem Moving into each directory to let the restores work based on per-project packages.config files
-
-  cd src/csharp
-
-  cd Grpc.Auth || goto :error
-  %NUGET% restore -PackagesDirectory ../packages || goto :error
-  cd ..
-
-  cd Grpc.Core || goto :error
-  %NUGET% restore -PackagesDirectory ../packages || goto :error
-  cd ..
-
-  cd Grpc.Core.Tests || goto :error
-  %NUGET% restore -PackagesDirectory ../packages || goto :error
-  cd ..
 
-  cd Grpc.Examples.MathClient || goto :error
-  %NUGET% restore -PackagesDirectory ../packages || goto :error
-  cd ..
-
-  cd Grpc.Examples.MathServer || goto :error
-  %NUGET% restore -PackagesDirectory ../packages || goto :error
-  cd ..
-
-  cd Grpc.Examples || goto :error
-  %NUGET% restore -PackagesDirectory ../packages || goto :error
-  cd ..
-
-  cd Grpc.HealthCheck.Tests || goto :error
-  %NUGET% restore -PackagesDirectory ../packages || goto :error
-  cd ..
-
-  cd Grpc.HealthCheck || goto :error
-  %NUGET% restore -PackagesDirectory ../packages || goto :error
-  cd ..
-
-  cd Grpc.IntegrationTesting.Client || goto :error
-  %NUGET% restore -PackagesDirectory ../packages || goto :error
-  cd ..
-
-  cd Grpc.IntegrationTesting.QpsWorker || goto :error
-  %NUGET% restore -PackagesDirectory ../packages || goto :error
-  cd ..
+@rem TODO(jtattermusch): Stop hardcoding path to yasm once Jenkins workers can locate yasm correctly
+@rem If yasm is not on the path, use hardcoded path instead.
+yasm --version || set USE_HARDCODED_YASM_PATH_MAYBE=-DCMAKE_ASM_NASM_COMPILER="C:/Program Files (x86)/yasm/yasm.exe"
 
-  cd Grpc.IntegrationTesting.StressClient || goto :error
-  %NUGET% restore -PackagesDirectory ../packages || goto :error
-  cd ..
+cmake -G "Visual Studio 14 2015" -A %ARCHITECTURE% -DgRPC_BUILD_TESTS=OFF -DgRPC_MSVC_STATIC_RUNTIME=ON %USE_HARDCODED_YASM_PATH_MAYBE% ../../.. || goto :error
 
-  cd Grpc.IntegrationTesting || goto :error
-  %NUGET% restore -PackagesDirectory ../packages || goto :error
+cd ..\..\..\src\csharp
 
-  cd /d %~dp0\..\.. || goto :error
-)
+dotnet restore Grpc.sln || goto :error
 
 endlocal
 
diff --git a/tools/run_tests/helper_scripts/pre_build_csharp.sh b/tools/run_tests/helper_scripts/pre_build_csharp.sh
index 1f808556f48737d1f47dd928df6ff78fec6b6a31..40be1b6b64216130a11d519816591e0b990f9e7e 100755
--- a/tools/run_tests/helper_scripts/pre_build_csharp.sh
+++ b/tools/run_tests/helper_scripts/pre_build_csharp.sh
@@ -33,59 +33,4 @@ set -ex
 # cd to gRPC csharp directory
 cd $(dirname $0)/../../../src/csharp
 
-root=`pwd`
-
-if [ -x "$(command -v nuget)" ]
-then
-  # TODO(jtattermusch): Get rid of this hack. See #8034
-  # Restoring Nuget packages by packages rather than by solution because of
-  # inability to restore by solution with Nuget client 3.4.4
-  # Moving into each directory to let the restores work based on per-project packages.config files
-  cd Grpc.Auth
-  nuget restore -PackagesDirectory ../packages
-  cd ..
-
-  cd Grpc.Core.Tests
-  nuget restore -PackagesDirectory ../packages
-  cd ..
-
-  cd Grpc.Core
-  nuget restore -PackagesDirectory ../packages
-  cd ..
-
-  cd Grpc.Examples.MathClient
-  nuget restore -PackagesDirectory ../packages
-  cd ..
-
-  cd Grpc.Examples.MathServer
-  nuget restore -PackagesDirectory ../packages
-  cd ..
-
-  cd Grpc.Examples
-  nuget restore -PackagesDirectory ../packages
-  cd ..
-
-  cd Grpc.HealthCheck.Tests
-  nuget restore -PackagesDirectory ../packages
-  cd ..
-
-  cd Grpc.HealthCheck
-  nuget restore -PackagesDirectory ../packages
-  cd ..
-
-  cd Grpc.IntegrationTesting.Client
-  nuget restore -PackagesDirectory ../packages
-  cd ..
-
-  cd Grpc.IntegrationTesting.QpsWorker
-  nuget restore -PackagesDirectory ../packages
-  cd ..
-
-  cd Grpc.IntegrationTesting.StressClient
-  nuget restore -PackagesDirectory ../packages
-  cd ..
-
-  cd Grpc.IntegrationTesting
-  nuget restore -PackagesDirectory ../packages
-  cd ..
-fi
+dotnet restore Grpc.sln
diff --git a/tools/run_tests/helper_scripts/run_python.sh b/tools/run_tests/helper_scripts/run_python.sh
index 7be473428fba587cc3be66b55b7c7ca0afb45bd0..e510ef40154e2962f2471c37defb0071d915d8d5 100755
--- a/tools/run_tests/helper_scripts/run_python.sh
+++ b/tools/run_tests/helper_scripts/run_python.sh
@@ -33,7 +33,7 @@ set -ex
 # change to grpc repo root
 cd $(dirname $0)/../../..
 
-PYTHON=`realpath -s "${1:-py27/bin/python}"`
+PYTHON=`realpath "${1:-py27/bin/python}"`
 
 ROOT=`pwd`
 
diff --git a/tools/internal_ci/linux/grpc_fuzzer_client.sh b/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh
similarity index 75%
rename from tools/internal_ci/linux/grpc_fuzzer_client.sh
rename to tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh
index c03f92559c0f8e09f733b38d6a78878d3999a92c..6688025260ff0db6e3bcc2378495992b96786788 100755
--- a/tools/internal_ci/linux/grpc_fuzzer_client.sh
+++ b/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2017, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -33,9 +33,12 @@ set -ex
 # change to grpc repo root
 cd $(dirname $0)/../../..
 
-git submodule update --init
-
-# download fuzzer docker image from dockerhub
-export DOCKERHUB_ORGANIZATION=grpctesting
-# runtime 23 * 60 mins
-config=asan-trace-cmp runtime=82800 tools/jenkins/run_fuzzer.sh client_fuzzer
+EXIT_CODE=0
+ruby src/ruby/end2end/sig_handling_driver.rb || EXIT_CODE=1
+ruby src/ruby/end2end/channel_state_driver.rb || EXIT_CODE=1
+ruby src/ruby/end2end/channel_closing_driver.rb || EXIT_CODE=1
+ruby src/ruby/end2end/sig_int_during_channel_watch_driver.rb || EXIT_CODE=1
+ruby src/ruby/end2end/killed_client_thread_driver.rb || EXIT_CODE=1
+ruby src/ruby/end2end/forking_client_driver.rb || EXIT_CODE=1
+ruby src/ruby/end2end/grpc_class_init_driver.rb || EXIT_CODE=1
+exit $EXIT_CODE
diff --git a/tools/run_tests/interop/interop_html_report.template b/tools/run_tests/interop/interop_html_report.template
index 88ecd4e4db16fe25cc29658226ddba569b6de8e5..6d9de5c62e89e8e6726b470ecbcba495c4415701 100644
--- a/tools/run_tests/interop/interop_html_report.template
+++ b/tools/run_tests/interop/interop_html_report.template
@@ -106,19 +106,19 @@
   % endfor
 % endif
 
-% if http2_badserver_cases:
-  <h2>HTTP/2 Bad Server Tests</h2>
+% if http2_server_cases:
+  <h2>HTTP/2 Server Tests</h2>
   ## Each column header is the client language.
   <table style="width:100%" border="1">
   <tr bgcolor="#00BFFF">
   <th>Client languages &#9658;<br/>Test Cases &#9660;</th>
-  % for client_lang in client_langs_http2_badserver_cases:
+  % for client_lang in client_langs:
     <th>${client_lang}</th>
   % endfor
   </tr>
-  % for test_case in http2_badserver_cases:
+  % for test_case in http2_server_cases:
     <tr><td><b>${test_case}</b></td>
-    % for client_lang in client_langs_http2_badserver_cases:
+    % for client_lang in client_langs:
       <% 
         shortname = 'cloud_to_cloud:%s:http2_server:%s' % (client_lang, 
                                                            test_case)
diff --git a/tools/run_tests/performance/README.md b/tools/run_tests/performance/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..5fd64f6ee911f5791babb866deef9f9a32ded8e7
--- /dev/null
+++ b/tools/run_tests/performance/README.md
@@ -0,0 +1,106 @@
+# Overview of performance test suite, with steps for manual runs:
+
+For design of the tests, see
+http://www.grpc.io/docs/guides/benchmarking.html.
+
+## Pre-reqs for running these manually:
+In general the benchmark workers and driver build scripts expect
+[linux_performance_worker_init.sh](../../gce/linux_performance_worker_init.sh) to have been ran already.
+
+### To run benchmarks locally:
+* From the grpc repo root, start the
+[run_performance_tests.py](../run_performance_tests.py) runner script.
+
+### On remote machines, to start the driver and workers manually:
+The [run_performance_test.py](../run_performance_tests.py) top-level runner script can also
+be used with remote machines, but for e.g., profiling the server,
+it might be useful to run workers manually.
+
+1. You'll need a "driver" and separate "worker" machines.
+For example, you might use one GCE "driver" machine and 3 other
+GCE "worker" machines that are in the same zone.
+
+2. Connect to each worker machine and start up a benchmark worker with a "driver_port".
+  * For example, to start the grpc-go benchmark worker:
+  [grpc-go worker main.go](https://github.com/grpc/grpc-go/blob/master/benchmark/worker/main.go) --driver_port <driver_port>
+
+#### Comands to start workers in different languages:
+ * Note that these commands are what the top-level
+   [run_performance_test.py](../run_performance_tests.py) script uses to
+   build and run different workers through the
+   [build_performance.sh](./build_performance.sh) script and "run worker"
+   scripts (such as the [run_worker_java.sh](./run_worker_java.sh)).
+
+##### Running benchmark workers for C-core wrapped languages (C++, Python, C#, Node, Ruby):
+   * These are more simple since they all live in the main grpc repo.
+
+```
+$ cd <grpc_repo_root>
+$ tools/run_tests/performance/build_performance.sh
+$ tools/run_tests/performance/run_worker_<language>.sh
+```
+
+   * Note that there is one "run_worker" script per language, e.g.,
+     [run_worker_csharp.sh](./run_worker_csharp.sh) for c#.
+
+##### Running benchmark workers for gRPC-Java:
+   * You'll need the [grpc-java](https://github.com/grpc/grpc-java) repo.
+
+```
+$ cd <grpc-java-repo>
+$ ./gradlew -PskipCodegen=true :grpc-benchmarks:installDist
+$ benchmarks/build/install/grpc-benchmarks/bin/benchmark_worker --driver_port <driver_port>
+```
+
+##### Running benchmark workers for gRPC-Go:
+   * You'll need the [grpc-go repo](https://github.com/grpc/grpc-go)
+
+```
+$ cd <grpc-go-repo>/benchmark/worker && go install
+$ # if profiling, it might be helpful to turn off inlining by building with "-gcflags=-l"
+$ $GOPATH/bin/worker --driver_port <driver_port>
+```
+
+#### Build the driver:
+* Connect to the driver machine (if using a remote driver) and from the grpc repo root:
+```
+$ tools/run_tests/performance/build_performance.sh
+```
+
+#### Run the driver:
+1. Get the 'scenario_json' relevant for the scenario to run. Note that "scenario
+  json" configs are generated from [scenario_config.py](./scenario_config.py).
+  The [driver](../../../test/cpp/qps/qps_json_driver.cc) takes a list of these configs as a json string of the form: `{scenario: <json_list_of_scenarios> }`
+  in its `--scenarios_json` command argument.
+  One quick way to get a valid json string to pass to the driver is by running
+  the [run_performance_tests.py](./run_performance_tests.py) locally and copying the logged scenario json command arg.
+
+2. From the grpc repo root:
+
+* Set `QPS_WORKERS` environment variable to a comma separated list of worker
+machines. Note that the driver will start the "benchmark server" on the first
+entry in the list, and the rest will be told to run as clients against the
+benchmark server.
+
+Example running and profiling of go benchmark server:
+```
+$ export QPS_WORKERS=<host1>:<10000>,<host2>,10000,<host3>:10000
+$ bins/opt/qps_json_driver --scenario_json='<scenario_json_scenario_config_string>'
+```
+
+### Example profiling commands
+
+While running the benchmark, a profiler can be attached to the server.
+
+Example to count syscalls in grpc-go server during a benchmark:
+* Connect to server machine and run:
+```
+$ netstat -tulpn | grep <driver_port> # to get pid of worker
+$ perf stat -p <worker_pid> -e syscalls:sys_enter_write # stop after test complete
+```
+
+Example memory profile of grpc-go server, with `go tools pprof`:
+* After a run is done on the server, see its alloc profile with:
+```
+$ go tool pprof --text --alloc_space http://localhost:<pprof_port>/debug/heap
+```
diff --git a/tools/run_tests/performance/bq_upload_result.py b/tools/run_tests/performance/bq_upload_result.py
index 89d2a9b320fde3b83914593b5e025b1ca3be3a34..3bac1199a7bee21815410a89a650c162299d7a49 100755
--- a/tools/run_tests/performance/bq_upload_result.py
+++ b/tools/run_tests/performance/bq_upload_result.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #
@@ -30,6 +30,8 @@
 
 # Uploads performance benchmark result file to bigquery.
 
+from __future__ import print_function
+
 import argparse
 import calendar
 import json
@@ -70,7 +72,7 @@ def _upload_netperf_latency_csv_to_bigquery(dataset_id, table_id, result_file):
   _create_results_table(bq, dataset_id, table_id)
 
   if not _insert_result(bq, dataset_id, table_id, scenario_result, flatten=False):
-    print 'Error uploading result to bigquery.'
+    print('Error uploading result to bigquery.')
     sys.exit(1)
 
 
@@ -82,7 +84,7 @@ def _upload_scenario_result_to_bigquery(dataset_id, table_id, result_file):
   _create_results_table(bq, dataset_id, table_id)
 
   if not _insert_result(bq, dataset_id, table_id, scenario_result):
-    print 'Error uploading result to bigquery.'
+    print('Error uploading result to bigquery.')
     sys.exit(1)
 
 
@@ -179,4 +181,4 @@ if args.file_format == 'netperf_latency_csv':
   _upload_netperf_latency_csv_to_bigquery(dataset_id, table_id, args.file_to_upload)
 else:
   _upload_scenario_result_to_bigquery(dataset_id, table_id, args.file_to_upload)
-print 'Successfully uploaded %s to BigQuery.\n' % args.file_to_upload
+print('Successfully uploaded %s to BigQuery.\n' % args.file_to_upload)
diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py
index 865125fcd783478cc69cc48912a76040fbdf47a5..08411bf9a4e2871ba576aed3ad221c25c43c267e 100644
--- a/tools/run_tests/performance/scenario_config.py
+++ b/tools/run_tests/performance/scenario_config.py
@@ -112,6 +112,7 @@ def _ping_pong_scenario(name, rpc_type,
                         channels=None,
                         outstanding=None,
                         resource_quota_size=None,
+                        messages_per_stream=None,
                         excluded_poll_engines=[]):
   """Creates a basic ping pong scenario."""
   scenario = {
@@ -165,6 +166,8 @@ def _ping_pong_scenario(name, rpc_type,
     scenario['client_config']['client_channels'] = 1
     scenario['client_config']['async_client_threads'] = 1
 
+  if messages_per_stream:
+    scenario['client_config']['messages_per_stream'] = messages_per_stream
   if client_language:
     # the CLIENT_LANGUAGE field is recognized by run_performance_tests.py
     scenario['CLIENT_LANGUAGE'] = client_language
@@ -214,6 +217,49 @@ class CXXLanguage:
           secure=secure,
           categories=smoketest_categories+[SCALABLE])
 
+      for mps in geometric_progression(1, 20, 10):
+        yield _ping_pong_scenario(
+            'cpp_generic_async_streaming_qps_unconstrained_%smps_%s' % (mps, secstr),
+            rpc_type='STREAMING',
+            client_type='ASYNC_CLIENT',
+            server_type='ASYNC_GENERIC_SERVER',
+            unconstrained_client='async', use_generic_payload=True,
+            secure=secure, messages_per_stream=mps,
+            categories=smoketest_categories+[SCALABLE])
+
+      for mps in geometric_progression(1, 200, math.sqrt(10)):
+        yield _ping_pong_scenario(
+            'cpp_generic_async_streaming_qps_unconstrained_%smps_%s' % (mps, secstr),
+            rpc_type='STREAMING',
+            client_type='ASYNC_CLIENT',
+            server_type='ASYNC_GENERIC_SERVER',
+            unconstrained_client='async', use_generic_payload=True,
+            secure=secure, messages_per_stream=mps,
+            categories=[SWEEP])
+
+      yield _ping_pong_scenario(
+          'cpp_generic_async_streaming_qps_1channel_1MBmsg_%s' % secstr,
+          rpc_type='STREAMING',
+          req_size=1024*1024,
+          resp_size=1024*1024,
+          client_type='ASYNC_CLIENT',
+          server_type='ASYNC_GENERIC_SERVER',
+          unconstrained_client='async', use_generic_payload=True,
+          secure=secure,
+          categories=smoketest_categories+[SCALABLE],
+          channels=1, outstanding=100)
+
+      yield _ping_pong_scenario(
+          'cpp_generic_async_streaming_qps_unconstrained_64KBmsg_%s' % secstr,
+          rpc_type='STREAMING',
+          req_size=64*1024,
+          resp_size=64*1024,
+          client_type='ASYNC_CLIENT',
+          server_type='ASYNC_GENERIC_SERVER',
+          unconstrained_client='async', use_generic_payload=True,
+          secure=secure,
+          categories=smoketest_categories+[SCALABLE])
+
       yield _ping_pong_scenario(
           'cpp_generic_async_streaming_qps_one_server_core_%s' % secstr,
           rpc_type='STREAMING',
@@ -234,6 +280,19 @@ class CXXLanguage:
           categories=smoketest_categories + [SCALABLE],
           excluded_poll_engines = ['poll-cv'])
 
+      yield _ping_pong_scenario(
+          'cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_%s' %
+          (secstr),
+          rpc_type='UNARY',
+          client_type='ASYNC_CLIENT',
+          server_type='ASYNC_SERVER',
+          channels=1,
+          outstanding=64,
+          req_size=128,
+          resp_size=8*1024*1024,
+          secure=secure,
+          categories=smoketest_categories + [SCALABLE])
+
       yield _ping_pong_scenario(
           'cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_%s' % secstr,
           rpc_type='STREAMING',
@@ -244,6 +303,13 @@ class CXXLanguage:
           categories=smoketest_categories+[SCALABLE],
           excluded_poll_engines = ['poll-cv'])
 
+      yield _ping_pong_scenario(
+        'cpp_protobuf_async_unary_ping_pong_%s_1MB' % secstr, rpc_type='UNARY',
+        client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
+        req_size=1024*1024, resp_size=1024*1024,
+        secure=secure,
+        categories=smoketest_categories + [SCALABLE])
+
       for rpc_type in ['unary', 'streaming']:
         for synchronicity in ['sync', 'async']:
           yield _ping_pong_scenario(
@@ -275,15 +341,39 @@ class CXXLanguage:
               secure=secure,
               categories=smoketest_categories+[SCALABLE])
 
-          yield _ping_pong_scenario(
-              'cpp_protobuf_%s_%s_qps_unconstrained_%s_500kib_resource_quota' % (synchronicity, rpc_type, secstr),
-              rpc_type=rpc_type.upper(),
-              client_type='%s_CLIENT' % synchronicity.upper(),
-              server_type='%s_SERVER' % synchronicity.upper(),
-              unconstrained_client=synchronicity,
-              secure=secure,
-              categories=smoketest_categories+[SCALABLE],
-              resource_quota_size=500*1024)
+          # TODO(vjpai): Re-enable this test. It has a lot of timeouts
+          # and hasn't yet been conclusively identified as a test failure
+          # or race in the library
+          # yield _ping_pong_scenario(
+          #     'cpp_protobuf_%s_%s_qps_unconstrained_%s_500kib_resource_quota' % (synchronicity, rpc_type, secstr),
+          #     rpc_type=rpc_type.upper(),
+          #     client_type='%s_CLIENT' % synchronicity.upper(),
+          #     server_type='%s_SERVER' % synchronicity.upper(),
+          #     unconstrained_client=synchronicity,
+          #     secure=secure,
+          #     categories=smoketest_categories+[SCALABLE],
+          #     resource_quota_size=500*1024)
+
+          if rpc_type == 'streaming':
+            for mps in geometric_progression(1, 20, 10):
+              yield _ping_pong_scenario(
+                  'cpp_protobuf_%s_%s_qps_unconstrained_%smps_%s' % (synchronicity, rpc_type, mps, secstr),
+                  rpc_type=rpc_type.upper(),
+                  client_type='%s_CLIENT' % synchronicity.upper(),
+                  server_type='%s_SERVER' % synchronicity.upper(),
+                  unconstrained_client=synchronicity,
+                  secure=secure, messages_per_stream=mps,
+                  categories=smoketest_categories+[SCALABLE])
+
+            for mps in geometric_progression(1, 200, math.sqrt(10)):
+              yield _ping_pong_scenario(
+                  'cpp_protobuf_%s_%s_qps_unconstrained_%smps_%s' % (synchronicity, rpc_type, mps, secstr),
+                  rpc_type=rpc_type.upper(),
+                  client_type='%s_CLIENT' % synchronicity.upper(),
+                  server_type='%s_SERVER' % synchronicity.upper(),
+                  unconstrained_client=synchronicity,
+                  secure=secure, messages_per_stream=mps,
+                  categories=[SWEEP])
 
           for channels in geometric_progression(1, 20000, math.sqrt(10)):
             for outstanding in geometric_progression(1, 200000, math.sqrt(10)):
@@ -319,6 +409,21 @@ class CSharpLanguage:
         use_generic_payload=True,
         categories=[SMOKETEST, SCALABLE])
 
+    yield _ping_pong_scenario(
+        'csharp_generic_async_streaming_ping_pong_insecure_1MB', rpc_type='STREAMING',
+        client_type='ASYNC_CLIENT', server_type='ASYNC_GENERIC_SERVER',
+        req_size=1024*1024, resp_size=1024*1024,
+        use_generic_payload=True,
+        secure=False,
+        categories=[SMOKETEST, SCALABLE])
+
+    yield _ping_pong_scenario(
+        'csharp_generic_async_streaming_qps_unconstrained_insecure', rpc_type='STREAMING',
+        client_type='ASYNC_CLIENT', server_type='ASYNC_GENERIC_SERVER',
+        unconstrained_client='async', use_generic_payload=True,
+        secure=False,
+        categories=[SMOKETEST, SCALABLE])
+
     yield _ping_pong_scenario(
         'csharp_protobuf_async_streaming_ping_pong', rpc_type='STREAMING',
         client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER')
@@ -373,6 +478,11 @@ class CSharpLanguage:
         unconstrained_client='async', client_language='c++',
         categories=[SCALABLE])
 
+    yield _ping_pong_scenario(
+        'csharp_protobuf_async_unary_ping_pong_1MB', rpc_type='UNARY',
+        client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
+        req_size=1024*1024, resp_size=1024*1024,
+        categories=[SMOKETEST, SCALABLE])
 
   def __str__(self):
     return 'csharp'
@@ -410,14 +520,36 @@ class NodeLanguage:
 
     yield _ping_pong_scenario(
         'cpp_to_node_unary_ping_pong', rpc_type='UNARY',
-        client_type='ASYNC_CLIENT', server_type='async_server',
+        client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
         client_language='c++')
 
     yield _ping_pong_scenario(
-        'node_protobuf_async_unary_qps_unconstrained', rpc_type='UNARY',
+        'node_protobuf_unary_ping_pong_1MB', rpc_type='UNARY',
         client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
-        unconstrained_client='async',
-        categories=[SCALABLE, SMOKETEST])
+        req_size=1024*1024, resp_size=1024*1024,
+        categories=[SCALABLE])
+
+    sizes = [('1B', 1), ('1KB', 1024), ('10KB', 10 * 1024),
+             ('1MB', 1024 * 1024), ('10MB', 10 * 1024 * 1024),
+             ('100MB', 100 * 1024 * 1024)]
+
+    for size_name, size in sizes:
+      for secure in (True, False):
+        yield _ping_pong_scenario(
+            'node_protobuf_unary_ping_pong_%s_resp_%s' %
+            (size_name, 'secure' if secure else 'insecure'),
+            rpc_type='UNARY',
+            client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
+            req_size=0, resp_size=size,
+            secure=secure,
+            categories=[SCALABLE])
+
+    # TODO(murgatroid99): fix bugs with this scenario and re-enable it
+    # yield _ping_pong_scenario(
+    #     'node_protobuf_async_unary_qps_unconstrained', rpc_type='UNARY',
+    #     client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
+    #     unconstrained_client='async',
+    #     categories=[SCALABLE, SMOKETEST])
 
     # TODO(jtattermusch): make this scenario work
     #yield _ping_pong_scenario(
@@ -425,11 +557,10 @@ class NodeLanguage:
     #    client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
     #    unconstrained_client='async')
 
-    # TODO(jtattermusch): make this scenario work
-    #yield _ping_pong_scenario(
-    #    'node_to_cpp_protobuf_async_unary_ping_pong', rpc_type='UNARY',
-    #    client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
-    #    server_language='c++', async_server_threads=1)
+    yield _ping_pong_scenario(
+        'node_to_cpp_protobuf_async_unary_ping_pong', rpc_type='UNARY',
+        client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
+        server_language='c++', async_server_threads=1)
 
     # TODO(jtattermusch): make this scenario work
     #yield _ping_pong_scenario(
@@ -492,6 +623,12 @@ class PythonLanguage:
         client_type='SYNC_CLIENT', server_type='ASYNC_SERVER',
         server_language='c++', async_server_threads=1)
 
+    yield _ping_pong_scenario(
+        'python_protobuf_sync_unary_ping_pong_1MB', rpc_type='UNARY',
+        client_type='SYNC_CLIENT', server_type='ASYNC_SERVER',
+        req_size=1024*1024, resp_size=1024*1024,
+        categories=[SMOKETEST, SCALABLE])
+
   def __str__(self):
     return 'python'
 
@@ -538,6 +675,12 @@ class RubyLanguage:
         client_type='SYNC_CLIENT', server_type='SYNC_SERVER',
         server_language='c++', async_server_threads=1)
 
+    yield _ping_pong_scenario(
+        'ruby_protobuf_unary_ping_pong_1MB', rpc_type='UNARY',
+        client_type='SYNC_CLIENT', server_type='SYNC_SERVER',
+        req_size=1024*1024, resp_size=1024*1024,
+        categories=[SMOKETEST, SCALABLE])
+
   def __str__(self):
     return 'ruby'
 
@@ -714,6 +857,21 @@ class NodeExpressLanguage:
         unconstrained_client='async',
         categories=[SCALABLE, SMOKETEST])
 
+    sizes = [('1B', 1), ('1KB', 1024), ('10KB', 10 * 1024),
+             ('1MB', 1024 * 1024), ('10MB', 10 * 1024 * 1024),
+             ('100MB', 100 * 1024 * 1024)]
+
+    for size_name, size in sizes:
+      for secure in (True, False):
+        yield _ping_pong_scenario(
+            'node_express_json_unary_ping_pong_%s_resp_%s' %
+            (size_name, 'secure' if secure else 'insecure'),
+            rpc_type='UNARY',
+            client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
+            req_size=0, resp_size=size,
+            secure=secure,
+            categories=[SCALABLE])
+
   def __str__(self):
     return 'node_express'
 
diff --git a/tools/run_tests/python_utils/antagonist.py b/tools/run_tests/python_utils/antagonist.py
index 857addfb38658a80f344a75d7526f8c5a1cc5ba0..111839ccf932073e78b7e9af99acd3d08521cf96 100755
--- a/tools/run_tests/python_utils/antagonist.py
+++ b/tools/run_tests/python_utils/antagonist.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
diff --git a/tools/run_tests/python_utils/comment_on_pr.py b/tools/run_tests/python_utils/comment_on_pr.py
new file mode 100644
index 0000000000000000000000000000000000000000..9708d0ffb4982ad59ca118af060bda14806d2554
--- /dev/null
+++ b/tools/run_tests/python_utils/comment_on_pr.py
@@ -0,0 +1,49 @@
+# Copyright 2017, 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 os
+import json
+import urllib2
+
+def comment_on_pr(text):
+  if 'JENKINS_OAUTH_TOKEN' not in os.environ:
+    print 'Missing JENKINS_OAUTH_TOKEN env var: not commenting'
+    return
+  if 'ghprbPullId' not in os.environ:
+    print 'Missing ghprbPullId env var: not commenting'
+    return
+  req = urllib2.Request(
+      url = 'https://api.github.com/repos/grpc/grpc/issues/%s/comments' %
+          os.environ['ghprbPullId'],
+      data = json.dumps({'body': text}),
+      headers = {
+        'Authorization': 'token %s' % os.environ['JENKINS_OAUTH_TOKEN'],
+        'Content-Type': 'application/json',
+      })
+  print urllib2.urlopen(req).read()
diff --git a/tools/run_tests/python_utils/dockerjob.py b/tools/run_tests/python_utils/dockerjob.py
index 0869c5cee9bf932c3502168e737ab249f711f103..709fc121a9b1bb4b30661eab4949cd25c0e4a09f 100755
--- a/tools/run_tests/python_utils/dockerjob.py
+++ b/tools/run_tests/python_utils/dockerjob.py
@@ -70,6 +70,23 @@ def docker_mapped_port(cid, port, timeout_seconds=15):
                   (port, cid))
 
 
+def wait_for_healthy(cid, shortname, timeout_seconds):
+  """Wait timeout_seconds for the container to become healthy"""
+  started = time.time()
+  while time.time() - started < timeout_seconds:
+    try:
+      output = subprocess.check_output(
+          ['docker', 'inspect', '--format="{{.State.Health.Status}}"', cid],
+          stderr=_DEVNULL)
+      if output.strip('\n') == 'healthy':
+        return
+    except subprocess.CalledProcessError as e:
+      pass
+    time.sleep(1)
+  raise Exception('Timed out waiting for %s (%s) to pass health check' %
+                  (shortname, cid))
+
+
 def finish_jobs(jobs):
   """Kills given docker containers and waits for corresponding jobs to finish"""
   for job in jobs:
@@ -113,6 +130,9 @@ class DockerJob:
   def mapped_port(self, port):
     return docker_mapped_port(self._container_name, port)
 
+  def wait_for_healthy(self, timeout_seconds):
+    wait_for_healthy(self._container_name, self._spec.shortname, timeout_seconds)
+
   def kill(self, suppress_failure=False):
     """Sends kill signal to the container."""
     if suppress_failure:
diff --git a/tools/run_tests/python_utils/filter_pull_request_tests.py b/tools/run_tests/python_utils/filter_pull_request_tests.py
index 3734f025d5f9408d4b3a00fe1d8d2668a85a1753..958eb569e014df35809d175651fb0b31270872f6 100644
--- a/tools/run_tests/python_utils/filter_pull_request_tests.py
+++ b/tools/run_tests/python_utils/filter_pull_request_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -30,7 +30,10 @@
 
 """Filter out tests based on file differences compared to merge target branch"""
 
+from __future__ import print_function
+
 import re
+import six
 from subprocess import check_output
 
 
@@ -124,8 +127,11 @@ _WHITELIST_DICT = {
   'setup\.py$': [_PYTHON_TEST_SUITE]
 }
 
+# Regex that combines all keys in _WHITELIST_DICT
+_ALL_TRIGGERS = "(" + ")|(".join(_WHITELIST_DICT.keys()) + ")"
+
 # Add all triggers to their respective test suites
-for trigger, test_suites in _WHITELIST_DICT.iteritems():
+for trigger, test_suites in six.iteritems(_WHITELIST_DICT):
   for test_suite in test_suites:
     test_suite.add_trigger(trigger)
 
@@ -166,6 +172,21 @@ def _remove_irrelevant_tests(tests, skippable_labels):
           test.labels[2] not in skippable_labels]
 
 
+def affects_c_cpp(base_branch):
+  """
+  Determines if a pull request's changes affect C/C++. This function exists because
+  there are pull request tests that only test C/C++ code
+  :param base_branch: branch that a pull request is requesting to merge into
+  :return: boolean indicating whether C/C++ changes are made in pull request
+  """
+  changed_files = _get_changed_files(base_branch)
+  # Run all tests if any changed file is not in the whitelist dictionary
+  for changed_file in changed_files:
+    if not re.match(_ALL_TRIGGERS, changed_file):
+      return True
+  return not _can_skip_tests(changed_files, _CPP_TEST_SUITE.triggers + _CORE_TEST_SUITE.triggers)
+
+
 def filter_tests(tests, base_branch):
   """
   Filters out tests that are safe to ignore
@@ -178,11 +199,9 @@ def filter_tests(tests, base_branch):
     print('  %s' % changed_file)
   print('')
 
-  # Regex that combines all keys in _WHITELIST_DICT
-  all_triggers = "(" + ")|(".join(_WHITELIST_DICT.keys()) + ")"
-  # Check if all tests have to be run
+  # Run all tests if any changed file is not in the whitelist dictionary
   for changed_file in changed_files:
-    if not re.match(all_triggers, changed_file):
+    if not re.match(_ALL_TRIGGERS, changed_file):
       return(tests)
   # Figure out which language and platform tests to run
   skippable_labels = []
@@ -193,4 +212,3 @@ def filter_tests(tests, base_branch):
         skippable_labels.append(label)
   tests = _remove_irrelevant_tests(tests, skippable_labels)
   return tests
-
diff --git a/tools/run_tests/python_utils/jobset.py b/tools/run_tests/python_utils/jobset.py
index f3047431e2a554cf5cbf0c84d5ec9af1535ed4b4..d01e82a76b18ea7587af7844838cf56b7eba3166 100755
--- a/tools/run_tests/python_utils/jobset.py
+++ b/tools/run_tests/python_utils/jobset.py
@@ -208,6 +208,11 @@ class JobSpec(object):
   def __repr__(self):
     return 'JobSpec(shortname=%s, cmdline=%s)' % (self.shortname, self.cmdline)
 
+  def __str__(self):
+    return '%s: %s %s' % (self.shortname,
+                          ' '.join('%s=%s' % kv for kv in self.environ.items()),
+                          ' '.join(self.cmdline))
+
 
 class JobResult(object):
   def __init__(self):
@@ -348,7 +353,7 @@ class Jobset(object):
   """Manages one run of jobs."""
 
   def __init__(self, check_cancelled, maxjobs, newline_on_success, travis,
-               stop_on_failure, add_env, quiet_success):
+               stop_on_failure, add_env, quiet_success, max_time):
     self._running = set()
     self._check_cancelled = check_cancelled
     self._cancelled = False
@@ -360,6 +365,7 @@ class Jobset(object):
     self._stop_on_failure = stop_on_failure
     self._add_env = add_env
     self._quiet_success = quiet_success
+    self._max_time = max_time
     self.resultset = {}
     self._remaining = None
     self._start_time = time.time()
@@ -379,6 +385,12 @@ class Jobset(object):
   def start(self, spec):
     """Start a job. Return True on success, False on failure."""
     while True:
+      if self._max_time > 0 and time.time() - self._start_time > self._max_time:
+        skipped_job_result = JobResult()
+        skipped_job_result.state = 'SKIPPED'
+        message('SKIPPED', spec.shortname, do_newline=True)
+        self.resultset[spec.shortname] = [skipped_job_result]
+        return True
       if self.cancelled(): return False
       current_cpu_cost = self.cpu_cost()
       if current_cpu_cost == 0: break
@@ -474,19 +486,20 @@ def run(cmdlines,
         stop_on_failure=False,
         add_env={},
         skip_jobs=False,
-        quiet_success=False):
+        quiet_success=False,
+        max_time=-1):
   if skip_jobs:
-    results = {}
+    resultset = {}
     skipped_job_result = JobResult()
     skipped_job_result.state = 'SKIPPED'
     for job in cmdlines:
       message('SKIPPED', job.shortname, do_newline=True)
-      results[job.shortname] = [skipped_job_result]
-    return results
+      resultset[job.shortname] = [skipped_job_result]
+    return 0, resultset
   js = Jobset(check_cancelled,
               maxjobs if maxjobs is not None else _DEFAULT_MAX_JOBS,
               newline_on_success, travis, stop_on_failure, add_env,
-              quiet_success)
+              quiet_success, max_time)
   for cmdline, remaining in tag_remaining(cmdlines):
     if not js.start(cmdline):
       break
diff --git a/tools/run_tests/python_utils/port_server.py b/tools/run_tests/python_utils/port_server.py
index e9b3f7ff7957c4fdfbea8d1be2dbbbc96ba55176..079ed70fbf3152c2a859cf44d60cc2088f94ded8 100755
--- a/tools/run_tests/python_utils/port_server.py
+++ b/tools/run_tests/python_utils/port_server.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -33,18 +33,21 @@
 from __future__ import print_function
 
 import argparse
-from six.moves import BaseHTTPServer
+from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
 import hashlib
 import os
 import socket
 import sys
 import time
+import random
+from SocketServer import ThreadingMixIn
+import threading
 
 
 # increment this number whenever making a change to ensure that
 # the changes are picked up by running CI servers
 # note that all changes must be backwards compatible
-_MY_VERSION = 9
+_MY_VERSION = 19
 
 
 if len(sys.argv) == 2 and sys.argv[1] == 'dump_version':
@@ -68,11 +71,35 @@ print('port server running on port %d' % args.port)
 
 pool = []
 in_use = {}
+mu = threading.Lock()
+
+def can_connect(port):
+  s = socket.socket()
+  try:
+    s.connect(('localhost', port))
+    return True
+  except socket.error, e:
+    return False
+  finally:
+    s.close()
+
+def can_bind(port, proto):
+  s = socket.socket(proto, socket.SOCK_STREAM)
+  s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+  try:
+    s.bind(('localhost', port))
+    return True
+  except socket.error, e:
+    return False
+  finally:
+    s.close()
 
 
 def refill_pool(max_timeout, req):
   """Scan for ports not marked for being in use"""
-  for i in range(1025, 32766):
+  chk = list(range(1025, 32766))
+  random.shuffle(chk)
+  for i in chk:
     if len(pool) > 100: break
     if i in in_use:
       age = time.time() - in_use[i]
@@ -80,46 +107,45 @@ def refill_pool(max_timeout, req):
         continue
       req.log_message("kill old request %d" % i)
       del in_use[i]
-    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-    try:
-      s.bind(('localhost', i))
+    if can_bind(i, socket.AF_INET) and can_bind(i, socket.AF_INET6) and not can_connect(i):
       req.log_message("found available port %d" % i)
       pool.append(i)
-    except:
-      pass # we really don't care about failures
-    finally:
-      s.close()
 
 
 def allocate_port(req):
   global pool
   global in_use
+  global mu
+  mu.acquire()
   max_timeout = 600
   while not pool:
     refill_pool(max_timeout, req)
     if not pool:
       req.log_message("failed to find ports: retrying soon")
+      mu.release()
       time.sleep(1)
+      mu.acquire()
       max_timeout /= 2
   port = pool[0]
   pool = pool[1:]
   in_use[port] = time.time()
+  mu.release()
   return port
 
 
 keep_running = True
 
 
-class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
+class Handler(BaseHTTPRequestHandler):
   
   def setup(self):
     # If the client is unreachable for 5 seconds, close the connection
     self.timeout = 5
-    BaseHTTPServer.BaseHTTPRequestHandler.setup(self)
+    BaseHTTPRequestHandler.setup(self)
 
   def do_GET(self):
     global keep_running
+    global mu
     if self.path == '/get':
       # allocate a new port, it will stay bound for ten minutes and until
       # it's unused
@@ -134,12 +160,15 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
       self.send_header('Content-Type', 'text/plain')
       self.end_headers()
       p = int(self.path[6:])
+      mu.acquire()
       if p in in_use:
         del in_use[p]
         pool.append(p)
-        self.log_message('drop known port %d' % p)
+        k = 'known'
       else:
-        self.log_message('drop unknown port %d' % p)
+        k = 'unknown'
+      mu.release()
+      self.log_message('drop %s port %d' % (k, p))
     elif self.path == '/version_number':
       # fetch a version string and the current process pid
       self.send_response(200)
@@ -153,17 +182,19 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
       self.send_response(200)
       self.send_header('Content-Type', 'text/plain')
       self.end_headers()
+      mu.acquire()
       now = time.time()
-      self.wfile.write(yaml.dump({'pool': pool, 'in_use': dict((k, now - v) for k, v in in_use.items())}))
+      out = yaml.dump({'pool': pool, 'in_use': dict((k, now - v) for k, v in in_use.items())})
+      mu.release()
+      self.wfile.write(out)
     elif self.path == '/quitquitquit':
       self.send_response(200)
       self.end_headers()
-      keep_running = False
+      self.server.shutdown()
 
+class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
+  """Handle requests in a separate thread"""
 
-httpd = BaseHTTPServer.HTTPServer(('', args.port), Handler)
-while keep_running:
-  httpd.handle_request()
-  sys.stderr.flush()
 
-print('done')
+ThreadedHTTPServer(('', args.port), Handler).serve_forever()
+
diff --git a/tools/run_tests/python_utils/report_utils.py b/tools/run_tests/python_utils/report_utils.py
index 9dad60408f293b8eee552b314d6ba4abe724a5ab..c7c0ceea92d77cb45a72c6b24dc61e94e18b5bfe 100644
--- a/tools/run_tests/python_utils/report_utils.py
+++ b/tools/run_tests/python_utils/report_utils.py
@@ -40,6 +40,7 @@ except (ImportError):
 import os
 import string
 import xml.etree.cElementTree as ET
+import six
 
 
 def _filter_msg(msg, output_format):
@@ -63,7 +64,7 @@ def render_junit_xml_report(resultset, xml_report, suite_package='grpc',
   root = ET.Element('testsuites')
   testsuite = ET.SubElement(root, 'testsuite', id='1', package=suite_package,
                             name=suite_name)
-  for shortname, results in resultset.iteritems():
+  for shortname, results in six.iteritems(resultset):
     for result in results:
       xml_test = ET.SubElement(testsuite, 'testcase', name=shortname)
       if result.elapsed_time:
@@ -76,13 +77,16 @@ def render_junit_xml_report(resultset, xml_report, suite_package='grpc',
         ET.SubElement(xml_test, 'error', message='Timeout')
       elif result.state == 'SKIPPED':
         ET.SubElement(xml_test, 'skipped', message='Skipped')
+  # ensure the report directory exists
+  report_dir = os.path.dirname(os.path.abspath(xml_report))
+  if not os.path.exists(report_dir):
+    os.makedirs(report_dir)
   tree = ET.ElementTree(root)
   tree.write(xml_report, encoding='UTF-8')
 
-
 def render_interop_html_report(
   client_langs, server_langs, test_cases, auth_test_cases, http2_cases,
-  http2_badserver_cases, client_langs_http2_badserver_cases, resultset, 
+  http2_server_cases, resultset,
   num_failures, cloud_to_prod, prod_servers, http2_interop):
   """Generate HTML report for interop tests."""
   template_file = 'tools/run_tests/interop/interop_html_report.template'
@@ -98,9 +102,7 @@ def render_interop_html_report(
   sorted_test_cases = sorted(test_cases)
   sorted_auth_test_cases = sorted(auth_test_cases)
   sorted_http2_cases = sorted(http2_cases)
-  sorted_http2_badserver_cases = sorted(http2_badserver_cases)
-  sorted_client_langs_http2_badserver_cases = sorted(
-      client_langs_http2_badserver_cases)
+  sorted_http2_server_cases = sorted(http2_server_cases)
   sorted_client_langs = sorted(client_langs)
   sorted_server_langs = sorted(server_langs)
   sorted_prod_servers = sorted(prod_servers)
@@ -110,9 +112,7 @@ def render_interop_html_report(
           'test_cases': sorted_test_cases,
           'auth_test_cases': sorted_auth_test_cases,
           'http2_cases': sorted_http2_cases,
-          'http2_badserver_cases': sorted_http2_badserver_cases,
-          'client_langs_http2_badserver_cases': (
-              sorted_client_langs_http2_badserver_cases),
+          'http2_server_cases': sorted_http2_server_cases,
           'resultset': resultset,
           'num_failures': num_failures,
           'cloud_to_prod': cloud_to_prod,
diff --git a/tools/run_tests/run_build_statistics.py b/tools/run_tests/run_build_statistics.py
index 654cf95a38c51a126035fca8eec69d4599066681..dd11a45e789b3d97a25c9b988e19bfdb4136bb25 100755
--- a/tools/run_tests/run_build_statistics.py
+++ b/tools/run_tests/run_build_statistics.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #
@@ -30,6 +30,8 @@
 
 """Tool to get build statistics from Jenkins and upload to BigQuery."""
 
+from __future__ import print_function
+
 import argparse
 import jenkinsapi
 from jenkinsapi.custom_exceptions import JenkinsAPIException
@@ -243,6 +245,6 @@ for build_name in _BUILDS.keys() if 'all' in args.builds else args.builds:
     rows = [big_query_utils.make_row(build_number, build_result)]
     if not big_query_utils.insert_rows(bq, _PROJECT_ID, _DATASET_ID, build_name, 
                                        rows):
-      print '====> Error uploading result to bigquery.'
+      print('====> Error uploading result to bigquery.')
       sys.exit(1)
 
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 0d5bec1d67f3b6f1292efc63d510e12ef95fbb48..867d9e6f7bf09af1857bd7e58be853925729177f 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -44,6 +44,8 @@ import sys
 import tempfile
 import time
 import uuid
+import six
+import traceback
 
 import python_utils.dockerjob as dockerjob
 import python_utils.jobset as jobset
@@ -72,6 +74,10 @@ _SKIP_ADVANCED = ['status_code_and_message',
 
 _TEST_TIMEOUT = 3*60
 
+# disable this test on core-based languages,
+# see https://github.com/grpc/grpc/issues/9779
+_SKIP_DATA_FRAME_PADDING = ['data_frame_padding']
+
 class CXXLanguage:
 
   def __init__(self):
@@ -96,7 +102,7 @@ class CXXLanguage:
     return {}
 
   def unimplemented_test_cases(self):
-    return []
+    return _SKIP_DATA_FRAME_PADDING
 
   def unimplemented_test_cases_server(self):
     return []
@@ -108,8 +114,8 @@ class CXXLanguage:
 class CSharpLanguage:
 
   def __init__(self):
-    self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug'
-    self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug'
+    self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45'
+    self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug/net45'
     self.safename = str(self)
 
   def client_cmd(self, args):
@@ -125,7 +131,7 @@ class CSharpLanguage:
     return {}
 
   def unimplemented_test_cases(self):
-    return _SKIP_SERVER_COMPRESSION
+    return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING
 
   def unimplemented_test_cases_server(self):
     return _SKIP_COMPRESSION
@@ -154,7 +160,7 @@ class CSharpCoreCLRLanguage:
     return {}
 
   def unimplemented_test_cases(self):
-    return _SKIP_SERVER_COMPRESSION
+    return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING
 
   def unimplemented_test_cases_server(self):
     return _SKIP_COMPRESSION
@@ -249,7 +255,7 @@ class Http2Server:
     return {}
 
   def unimplemented_test_cases(self):
-    return _TEST_CASES
+    return _TEST_CASES + _SKIP_DATA_FRAME_PADDING
 
   def unimplemented_test_cases_server(self):
     return _TEST_CASES
@@ -280,7 +286,7 @@ class Http2Client:
     return _TEST_CASES
 
   def unimplemented_test_cases_server(self):
-    return []
+    return _TEST_CASES
 
   def __str__(self):
     return 'http2'
@@ -307,7 +313,7 @@ class NodeLanguage:
     return {}
 
   def unimplemented_test_cases(self):
-    return _SKIP_COMPRESSION
+    return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING
 
   def unimplemented_test_cases_server(self):
     return _SKIP_COMPRESSION
@@ -332,7 +338,7 @@ class PHPLanguage:
     return {}
 
   def unimplemented_test_cases(self):
-    return _SKIP_COMPRESSION
+    return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING
 
   def unimplemented_test_cases_server(self):
     return []
@@ -357,7 +363,7 @@ class PHP7Language:
     return {}
 
   def unimplemented_test_cases(self):
-    return _SKIP_COMPRESSION
+    return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING
 
   def unimplemented_test_cases_server(self):
     return []
@@ -365,6 +371,39 @@ class PHP7Language:
   def __str__(self):
     return 'php7'
 
+class ObjcLanguage:
+
+  def __init__(self):
+    self.client_cwd = 'src/objective-c/tests'
+    self.safename = str(self)
+
+  def client_cmd(self, args):
+    # from args, extract the server port and craft xcodebuild command out of it
+    for arg in args:
+      port = re.search('--server_port=(\d+)', arg)
+      if port:
+        portnum = port.group(1)
+        cmdline = 'pod install && xcodebuild -workspace Tests.xcworkspace -scheme InteropTestsLocalSSL -destination name="iPhone 6" HOST_PORT_LOCALSSL=localhost:%s test'%portnum
+        return [cmdline]
+
+  def cloud_to_prod_env(self):
+    return {}
+
+  def global_env(self):
+    return {}
+
+  def unimplemented_test_cases(self):
+    # ObjC test runs all cases with the same command. It ignores the testcase
+    # cmdline argument. Here we return all but one test cases as unimplemented,
+    # and depend upon ObjC test's behavior that it runs all cases even when
+    # we tell it to run just one.
+    return _TEST_CASES[1:] + _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING
+
+  def unimplemented_test_cases_server(self):
+    return _SKIP_COMPRESSION
+
+  def __str__(self):
+    return 'objc'
 
 class RubyLanguage:
 
@@ -388,7 +427,7 @@ class RubyLanguage:
     return {}
 
   def unimplemented_test_cases(self):
-    return _SKIP_SERVER_COMPRESSION
+    return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING
 
   def unimplemented_test_cases_server(self):
     return _SKIP_COMPRESSION
@@ -396,7 +435,6 @@ class RubyLanguage:
   def __str__(self):
     return 'ruby'
 
-
 class PythonLanguage:
 
   def __init__(self):
@@ -436,7 +474,7 @@ class PythonLanguage:
             'PYTHONPATH': '{}/src/python/gens'.format(DOCKER_WORKDIR_ROOT)}
 
   def unimplemented_test_cases(self):
-    return _SKIP_COMPRESSION
+    return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING
 
   def unimplemented_test_cases_server(self):
     return _SKIP_COMPRESSION
@@ -454,6 +492,7 @@ _LANGUAGES = {
     'node' : NodeLanguage(),
     'php' :  PHPLanguage(),
     'php7' :  PHP7Language(),
+    'objc' : ObjcLanguage(),
     'ruby' : RubyLanguage(),
     'python' : PythonLanguage(),
 }
@@ -475,10 +514,14 @@ _AUTH_TEST_CASES = ['compute_engine_creds', 'jwt_token_creds',
 
 _HTTP2_TEST_CASES = ['tls', 'framing']
 
-_HTTP2_BADSERVER_TEST_CASES = ['rst_after_header', 'rst_after_data', 'rst_during_data',
-                     'goaway', 'ping', 'max_streams']
+_HTTP2_SERVER_TEST_CASES = ['rst_after_header', 'rst_after_data', 'rst_during_data',
+                               'goaway', 'ping', 'max_streams', 'data_frame_padding', 'no_df_padding_sanity_test']
 
-_LANGUAGES_FOR_HTTP2_BADSERVER_TESTS = ['java', 'go', 'python', 'c++']
+_GRPC_CLIENT_TEST_CASES_FOR_HTTP2_SERVER_TEST_CASES = { 'data_frame_padding': 'large_unary', 'no_df_padding_sanity_test': 'large_unary' }
+
+_HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS = _GRPC_CLIENT_TEST_CASES_FOR_HTTP2_SERVER_TEST_CASES.keys()
+
+_LANGUAGES_WITH_HTTP2_CLIENTS_FOR_HTTP2_SERVER_TEST_CASES = ['java', 'go', 'python', 'c++']
 
 DOCKER_WORKDIR_ROOT = '/var/local/git/grpc'
 
@@ -501,6 +544,28 @@ def docker_run_cmdline(cmdline, image, docker_args=[], cwd=None, environ=None):
   return docker_cmdline
 
 
+def manual_cmdline(docker_cmdline):
+  """Returns docker cmdline adjusted for manual invocation."""
+  print_cmdline = []
+  for item in docker_cmdline:
+    if item.startswith('--name='):
+      continue
+    # add quotes when necessary
+    if any(character.isspace() for character in item):
+      item = "\"%s\"" % item
+    print_cmdline.append(item)
+  return ' '.join(print_cmdline)
+
+
+def write_cmdlog_maybe(cmdlog, filename):
+  """Returns docker cmdline adjusted for manual invocation."""
+  if cmdlog:
+    with open(filename, 'w') as logfile:
+      logfile.write('#!/bin/bash\n')
+      logfile.writelines("%s\n" % line for line in cmdlog)
+    print('Command log written to file %s' % filename)
+
+
 def bash_cmdline(cmdline):
   """Creates bash -c cmdline from args list."""
   # Use login shell:
@@ -551,7 +616,8 @@ def _job_kill_handler(job):
 
 
 def cloud_to_prod_jobspec(language, test_case, server_host_name,
-                          server_host_detail, docker_image=None, auth=False):
+                          server_host_detail, docker_image=None, auth=False,
+                          manual_cmd_log=None):
   """Creates jobspec for cloud-to-prod interop test"""
   container_name = None
   cmdargs = [
@@ -576,7 +642,9 @@ def cloud_to_prod_jobspec(language, test_case, server_host_name,
                                  cwd=cwd,
                                  environ=environ,
                                  docker_args=['--net=host',
-                                              '--name', container_name])
+                                              '--name=%s' % container_name])
+    if manual_cmd_log is not None:
+      manual_cmd_log.append(manual_cmdline(cmdline))
     cwd = None
     environ = None
 
@@ -597,38 +665,52 @@ def cloud_to_prod_jobspec(language, test_case, server_host_name,
 
 
 def cloud_to_cloud_jobspec(language, test_case, server_name, server_host,
-                           server_port, docker_image=None, insecure=False):
+                           server_port, docker_image=None, insecure=False,
+                           manual_cmd_log=None):
   """Creates jobspec for cloud-to-cloud interop test"""
   interop_only_options = [
       '--server_host_override=foo.test.google.fr',
       '--use_tls=%s' % ('false' if insecure else 'true'),
       '--use_test_ca=true',
   ]
+
+  client_test_case = test_case
+  if test_case in _HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS:
+    client_test_case = _GRPC_CLIENT_TEST_CASES_FOR_HTTP2_SERVER_TEST_CASES[test_case]
+  if client_test_case in language.unimplemented_test_cases():
+    print('asking client %s to run unimplemented test case %s' % (repr(language), client_test_case))
+    sys.exit(1)
+
   common_options = [
-      '--test_case=%s' % test_case,
+      '--test_case=%s' % client_test_case,
       '--server_host=%s' % server_host,
+      '--server_port=%s' % server_port,
   ]
-  if test_case in _HTTP2_BADSERVER_TEST_CASES:
-    # We are running the http2_badserver_interop test. Adjust command line accordingly.
-    offset = sorted(_HTTP2_BADSERVER_TEST_CASES).index(test_case)
-    client_options = common_options + ['--server_port=%s' %
-                                       (int(server_port)+offset)]
-    cmdline = bash_cmdline(language.client_cmd_http2interop(client_options))
-    cwd = language.http2_cwd
+
+  if test_case in _HTTP2_SERVER_TEST_CASES:
+    if test_case in _HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS:
+      client_options = interop_only_options + common_options
+      cmdline = bash_cmdline(language.client_cmd(client_options))
+      cwd = language.client_cwd
+    else:
+      cmdline = bash_cmdline(language.client_cmd_http2interop(common_options))
+      cwd = language.http2_cwd
   else:
-    client_options = interop_only_options + common_options + ['--server_port=%s' % server_port]
-    cmdline = bash_cmdline(language.client_cmd(client_options))
+    cmdline = bash_cmdline(language.client_cmd(common_options+interop_only_options))
     cwd = language.client_cwd
 
   environ = language.global_env()
-  if docker_image:
+  if docker_image and language.safename != 'objc':
+    # we can't run client in docker for objc.
     container_name = dockerjob.random_name('interop_client_%s' % language.safename)
     cmdline = docker_run_cmdline(cmdline,
                                  image=docker_image,
                                  environ=environ,
                                  cwd=cwd,
                                  docker_args=['--net=host',
-                                              '--name', container_name])
+                                              '--name=%s' % container_name])
+    if manual_cmd_log is not None:
+      manual_cmd_log.append(manual_cmdline(cmdline))
     cwd = None
 
   test_job = jobset.JobSpec(
@@ -646,37 +728,49 @@ def cloud_to_cloud_jobspec(language, test_case, server_name, server_host,
   return test_job
 
 
-def server_jobspec(language, docker_image, insecure=False):
+def server_jobspec(language, docker_image, insecure=False, manual_cmd_log=None):
   """Create jobspec for running a server"""
   container_name = dockerjob.random_name('interop_server_%s' % language.safename)
   cmdline = bash_cmdline(
       language.server_cmd(['--port=%s' % _DEFAULT_SERVER_PORT,
                            '--use_tls=%s' % ('false' if insecure else 'true')]))
   environ = language.global_env()
+  docker_args = ['--name=%s' % container_name]
   if language.safename == 'http2':
     # we are running the http2 interop server. Open next N ports beginning
     # with the server port. These ports are used for http2 interop test
-    # (one test case per port). We also attach the docker container running
-    # the server to local network, so we don't have to mess with port mapping
-    port_args = [
-      '-p', str(_DEFAULT_SERVER_PORT+0),
-      '-p', str(_DEFAULT_SERVER_PORT+1),
-      '-p', str(_DEFAULT_SERVER_PORT+2),
-      '-p', str(_DEFAULT_SERVER_PORT+3),
-      '-p', str(_DEFAULT_SERVER_PORT+4),
-      '-p', str(_DEFAULT_SERVER_PORT+5),
-      '-p', str(_DEFAULT_SERVER_PORT+6),
-      '--net=host',
+    # (one test case per port).
+    docker_args += list(
+        itertools.chain.from_iterable(('-p', str(_DEFAULT_SERVER_PORT + i))
+                                      for i in range(
+                                          len(_HTTP2_SERVER_TEST_CASES))))
+    # Enable docker's healthcheck mechanism.
+    # This runs a Python script inside the container every second. The script
+    # pings the http2 server to verify it is ready. The 'health-retries' flag
+    # specifies the number of consecutive failures before docker will report
+    # the container's status as 'unhealthy'. Prior to the first 'health_retries'
+    # failures or the first success, the status will be 'starting'. 'docker ps'
+    # or 'docker inspect' can be used to see the health of the container on the
+    # command line.
+    docker_args += [
+        '--health-cmd=python test/http2_test/http2_server_health_check.py '
+        '--server_host=%s --server_port=%d'
+        % ('localhost', _DEFAULT_SERVER_PORT),
+        '--health-interval=1s',
+        '--health-retries=5',
+        '--health-timeout=10s',
     ]
+
   else:
-    port_args = ['-p', str(_DEFAULT_SERVER_PORT)]
+    docker_args += ['-p', str(_DEFAULT_SERVER_PORT)]
 
   docker_cmdline = docker_run_cmdline(cmdline,
                                       image=docker_image,
                                       cwd=language.server_cwd,
                                       environ=environ,
-                                      docker_args=port_args +
-                                        ['--name', container_name])
+                                      docker_args=docker_args)
+  if manual_cmd_log is not None:
+      manual_cmd_log.append(manual_cmdline(docker_cmdline))
   server_job = jobset.JobSpec(
           cmdline=docker_cmdline,
           environ=environ,
@@ -760,7 +854,7 @@ argp.add_argument('-l', '--language',
                   choices=['all'] + sorted(_LANGUAGES),
                   nargs='+',
                   default=['all'],
-                  help='Clients to run.')
+                  help='Clients to run. Objc client can be only run on OSX.')
 argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int)
 argp.add_argument('--cloud_to_prod',
                   default=False,
@@ -794,6 +888,10 @@ argp.add_argument('-t', '--travis',
                   default=False,
                   action='store_const',
                   const=True)
+argp.add_argument('-v', '--verbose',
+                  default=False,
+                  action='store_const',
+                  const=True)
 argp.add_argument('--use_docker',
                   default=False,
                   action='store_const',
@@ -806,16 +904,24 @@ argp.add_argument('--allow_flakes',
                   action='store_const',
                   const=True,
                   help='Allow flaky tests to show as passing (re-runs failed tests up to five times)')
+argp.add_argument('--manual_run',
+                  default=False,
+                  action='store_const',
+                  const=True,
+                  help='Prepare things for running interop tests manually. ' +
+                  'Preserve docker images after building them and skip '
+                  'actually running the tests. Only print commands to run by ' +
+                  'hand.')
 argp.add_argument('--http2_interop',
                   default=False,
                   action='store_const',
                   const=True,
                   help='Enable HTTP/2 client edge case testing. (Bad client, good server)')
-argp.add_argument('--http2_badserver_interop',
+argp.add_argument('--http2_server_interop',
                   default=False,
                   action='store_const',
                   const=True,
-                  help='Enable HTTP/2 server edge case testing. (Good client, bad server)')
+                  help='Enable HTTP/2 server edge case testing. (Includes positive and negative tests')
 argp.add_argument('--insecure',
                   default=False,
                   action='store_const',
@@ -837,44 +943,59 @@ if args.use_docker:
     print('copied to the docker environment.')
     time.sleep(5)
 
+if args.manual_run and not args.use_docker:
+  print('--manual_run is only supported with --use_docker option enabled.')
+  sys.exit(1)
+
 if not args.use_docker and servers:
   print('Running interop servers is only supported with --use_docker option enabled.')
   sys.exit(1)
 
+
+# we want to include everything but objc in 'all'
+# because objc won't run on non-mac platforms
+all_but_objc = set(six.iterkeys(_LANGUAGES)) - set(['objc'])
 languages = set(_LANGUAGES[l]
                 for l in itertools.chain.from_iterable(
-                    _LANGUAGES.iterkeys() if x == 'all' else [x]
+                    all_but_objc if x == 'all' else [x]
                     for x in args.language))
 
-languages_http2_badserver_interop = set()
-if args.http2_badserver_interop:
-  languages_http2_badserver_interop = set(
-      _LANGUAGES[l] for l in _LANGUAGES_FOR_HTTP2_BADSERVER_TESTS)
+languages_http2_clients_for_http2_server_interop = set()
+if args.http2_server_interop:
+  languages_http2_clients_for_http2_server_interop = set(
+      _LANGUAGES[l] for l in _LANGUAGES_WITH_HTTP2_CLIENTS_FOR_HTTP2_SERVER_TEST_CASES
+      if 'all' in args.language or l in args.language)
 
 http2Interop = Http2Client() if args.http2_interop else None
-http2InteropServer = Http2Server() if args.http2_badserver_interop else None
+http2InteropServer = Http2Server() if args.http2_server_interop else None
 
 docker_images={}
 if args.use_docker:
   # languages for which to build docker images
   languages_to_build = set(
       _LANGUAGES[k] for k in set([str(l) for l in languages] + [s for s in servers]))
-  languages_to_build = languages_to_build | languages_http2_badserver_interop
+  languages_to_build = languages_to_build | languages_http2_clients_for_http2_server_interop
 
   if args.http2_interop:
     languages_to_build.add(http2Interop)
 
-  if args.http2_badserver_interop:
+  if args.http2_server_interop:
     languages_to_build.add(http2InteropServer)
 
   build_jobs = []
   for l in languages_to_build:
+    if str(l) == 'objc':
+      # we don't need to build a docker image for objc
+      continue
     job = build_interop_image_jobspec(l)
     docker_images[str(l)] = job.tag
     build_jobs.append(job)
 
   if build_jobs:
     jobset.message('START', 'Building interop docker images.', do_newline=True)
+    if args.verbose:
+      print('Jobs to run: \n%s\n' % '\n'.join(str(j) for j in build_jobs))
+
     num_failures, _ = jobset.run(
         build_jobs, newline_on_success=True, maxjobs=args.jobs)
     if num_failures == 0:
@@ -883,28 +1004,41 @@ if args.use_docker:
     else:
       jobset.message('FAILED', 'Failed to build interop docker images.',
                      do_newline=True)
-      for image in docker_images.itervalues():
+      for image in six.itervalues(docker_images):
         dockerjob.remove_image(image, skip_nonexistent=True)
       sys.exit(1)
 
+server_manual_cmd_log = [] if args.manual_run else None
+client_manual_cmd_log = [] if args.manual_run else None
+
 # Start interop servers.
-server_jobs={}
-server_addresses={}
+server_jobs = {}
+server_addresses = {}
 try:
   for s in servers:
     lang = str(s)
     spec = server_jobspec(_LANGUAGES[lang], docker_images.get(lang),
-                          args.insecure)
-    job = dockerjob.DockerJob(spec)
-    server_jobs[lang] = job
-    server_addresses[lang] = ('localhost', job.mapped_port(_DEFAULT_SERVER_PORT))
+                          args.insecure, manual_cmd_log=server_manual_cmd_log)
+    if not args.manual_run:
+      job = dockerjob.DockerJob(spec)
+      server_jobs[lang] = job
+      server_addresses[lang] = ('localhost', job.mapped_port(_DEFAULT_SERVER_PORT))
+    else:
+      # don't run the server, set server port to a placeholder value
+      server_addresses[lang] = ('localhost', '${SERVER_PORT}')
 
-  if args.http2_badserver_interop:
+  http2_server_job = None
+  if args.http2_server_interop:
     # launch a HTTP2 server emulator that creates edge cases
     lang = str(http2InteropServer)
-    spec = server_jobspec(http2InteropServer, docker_images.get(lang))
-    job = dockerjob.DockerJob(spec)
-    server_jobs[lang] = job
+    spec = server_jobspec(http2InteropServer, docker_images.get(lang),
+                          manual_cmd_log=server_manual_cmd_log)
+    if not args.manual_run:
+      http2_server_job = dockerjob.DockerJob(spec)
+      server_jobs[lang] = http2_server_job
+    else:
+      # don't run the server, set server port to a placeholder value
+      server_addresses[lang] = ('localhost', '${SERVER_PORT}')
 
   jobs = []
   if args.cloud_to_prod:
@@ -918,7 +1052,8 @@ try:
               test_job = cloud_to_prod_jobspec(
                   language, test_case, server_host_name,
                   prod_servers[server_host_name],
-                  docker_image=docker_images.get(str(language)))
+                  docker_image=docker_images.get(str(language)),
+                  manual_cmd_log=client_manual_cmd_log)
               jobs.append(test_job)
 
       if args.http2_interop:
@@ -926,7 +1061,8 @@ try:
           test_job = cloud_to_prod_jobspec(
               http2Interop, test_case, server_host_name,
               prod_servers[server_host_name],
-              docker_image=docker_images.get(str(http2Interop)))
+              docker_image=docker_images.get(str(http2Interop)),
+              manual_cmd_log=client_manual_cmd_log)
           jobs.append(test_job)
 
   if args.cloud_to_prod_auth:
@@ -939,7 +1075,8 @@ try:
             test_job = cloud_to_prod_jobspec(
                 language, test_case, server_host_name,
                 prod_servers[server_host_name],
-                docker_image=docker_images.get(str(language)), auth=True)
+                docker_image=docker_images.get(str(language)), auth=True,
+                manual_cmd_log=client_manual_cmd_log)
             jobs.append(test_job)
 
   for server in args.override_server:
@@ -963,7 +1100,8 @@ try:
                                               server_host,
                                               server_port,
                                               docker_image=docker_images.get(str(language)),
-                                              insecure=args.insecure)
+                                              insecure=args.insecure,
+                                              manual_cmd_log=client_manual_cmd_log)
             jobs.append(test_job)
 
     if args.http2_interop:
@@ -977,57 +1115,104 @@ try:
                                           server_host,
                                           server_port,
                                           docker_image=docker_images.get(str(http2Interop)),
-                                          insecure=args.insecure)
+                                          insecure=args.insecure,
+                                          manual_cmd_log=client_manual_cmd_log)
         jobs.append(test_job)
 
-  if args.http2_badserver_interop:
-    for language in languages_http2_badserver_interop:
-      for test_case in _HTTP2_BADSERVER_TEST_CASES:
+  if args.http2_server_interop:
+    if not args.manual_run:
+      http2_server_job.wait_for_healthy(timeout_seconds=600)
+    for language in languages_http2_clients_for_http2_server_interop:
+      for test_case in set(_HTTP2_SERVER_TEST_CASES) - set(_HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS):
+        offset = sorted(_HTTP2_SERVER_TEST_CASES).index(test_case)
+        server_port = _DEFAULT_SERVER_PORT+offset
+        if not args.manual_run:
+          server_port = http2_server_job.mapped_port(server_port)
         test_job = cloud_to_cloud_jobspec(language,
                                           test_case,
                                           str(http2InteropServer),
                                           'localhost',
-                                          _DEFAULT_SERVER_PORT,
-                                          docker_image=docker_images.get(str(language)))
+                                          server_port,
+                                          docker_image=docker_images.get(str(language)),
+                                          manual_cmd_log=client_manual_cmd_log)
         jobs.append(test_job)
+    for language in languages:
+      # HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS is a subset of
+      # HTTP_SERVER_TEST_CASES, in which clients use their gRPC interop clients rather
+      # than specialized http2 clients, reusing existing test implementations.
+      # For example, in the "data_frame_padding" test, use language's gRPC
+      # interop clients and make them think that theyre running "large_unary"
+      # test case. This avoids implementing a new test case in each language.
+      for test_case in _HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS:
+        if test_case not in language.unimplemented_test_cases():
+          offset = sorted(_HTTP2_SERVER_TEST_CASES).index(test_case)
+          server_port = _DEFAULT_SERVER_PORT+offset
+          if not args.manual_run:
+            server_port = http2_server_job.mapped_port(server_port)
+          if not args.insecure:
+            print(('Creating grpc cient to http2 server test case with insecure connection, even though'
+                   ' args.insecure is False. Http2 test server only supports insecure connections.'))
+          test_job = cloud_to_cloud_jobspec(language,
+                                            test_case,
+                                            str(http2InteropServer),
+                                            'localhost',
+                                            server_port,
+                                            docker_image=docker_images.get(str(language)),
+                                            insecure=True,
+                                            manual_cmd_log=client_manual_cmd_log)
+          jobs.append(test_job)
 
   if not jobs:
     print('No jobs to run.')
-    for image in docker_images.itervalues():
+    for image in six.itervalues(docker_images):
       dockerjob.remove_image(image, skip_nonexistent=True)
     sys.exit(1)
 
+  if args.manual_run:
+    print('All tests will skipped --manual_run option is active.')
+
+  if args.verbose:
+    print('Jobs to run: \n%s\n' % '\n'.join(str(job) for job in jobs))
+
   num_failures, resultset = jobset.run(jobs, newline_on_success=True,
-                                       maxjobs=args.jobs)
+                                       maxjobs=args.jobs,
+                                       skip_jobs=args.manual_run)
   if num_failures:
     jobset.message('FAILED', 'Some tests failed', do_newline=True)
   else:
     jobset.message('SUCCESS', 'All tests passed', do_newline=True)
 
+  write_cmdlog_maybe(server_manual_cmd_log, 'interop_server_cmds.sh')
+  write_cmdlog_maybe(client_manual_cmd_log, 'interop_client_cmds.sh')
+
   report_utils.render_junit_xml_report(resultset, 'report.xml')
 
   for name, job in resultset.items():
     if "http2" in name:
       job[0].http2results = aggregate_http2_results(job[0].message)
 
-  http2_badserver_test_cases = (
-      _HTTP2_BADSERVER_TEST_CASES if args.http2_badserver_interop else [])
+  http2_server_test_cases = (
+      _HTTP2_SERVER_TEST_CASES if args.http2_server_interop else [])
 
   report_utils.render_interop_html_report(
       set([str(l) for l in languages]), servers, _TEST_CASES, _AUTH_TEST_CASES,
-      _HTTP2_TEST_CASES, http2_badserver_test_cases,
-      _LANGUAGES_FOR_HTTP2_BADSERVER_TESTS, resultset, num_failures,
+      _HTTP2_TEST_CASES, http2_server_test_cases, resultset, num_failures,
       args.cloud_to_prod_auth or args.cloud_to_prod, args.prod_servers,
       args.http2_interop)
-
+except Exception as e:
+  print('exception occurred:')
+  traceback.print_exc(file=sys.stdout)
 finally:
   # Check if servers are still running.
   for server, job in server_jobs.items():
     if not job.is_running():
       print('Server "%s" has exited prematurely.' % server)
 
-  dockerjob.finish_jobs([j for j in server_jobs.itervalues()])
+  dockerjob.finish_jobs([j for j in six.itervalues(server_jobs)])
 
-  for image in docker_images.itervalues():
-    print('Removing docker image %s' % image)
-    dockerjob.remove_image(image)
+  for image in six.itervalues(docker_images):
+    if not args.manual_run:
+      print('Removing docker image %s' % image)
+      dockerjob.remove_image(image)
+    else:
+      print('Preserving docker image: %s' % image)
diff --git a/tools/run_tests/run_microbenchmark.py b/tools/run_tests/run_microbenchmark.py
index 3a9461ecd3bef532460fe77af673c4932a3544e2..17b156c78f9828625441757eda92801d5c72de74 100755
--- a/tools/run_tests/run_microbenchmark.py
+++ b/tools/run_tests/run_microbenchmark.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2017, Google Inc.
 # All rights reserved.
 #
@@ -38,6 +38,19 @@ import argparse
 import python_utils.jobset as jobset
 import python_utils.start_port_server as start_port_server
 
+_AVAILABLE_BENCHMARK_TESTS = ['bm_fullstack_unary_ping_pong',
+                              'bm_fullstack_streaming_ping_pong',
+                              'bm_fullstack_streaming_pump',
+                              'bm_closure',
+                              'bm_cq',
+                              'bm_call_create',
+                              'bm_error',
+                              'bm_chttp2_hpack',
+                              'bm_chttp2_transport',
+                              'bm_pollset',
+                              'bm_metadata',
+                              'bm_fullstack_trickle']
+
 flamegraph_dir = os.path.join(os.path.expanduser('~'), 'FlameGraph')
 
 os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
@@ -178,13 +191,15 @@ def run_summary(bm_name, cfg, base_json_name):
 
 def collect_summary(bm_name, args):
   heading('Summary: %s [no counters]' % bm_name)
-  text(run_summary(bm_name, 'opt', 'out'))
+  text(run_summary(bm_name, 'opt', bm_name))
   heading('Summary: %s [with counters]' % bm_name)
-  text(run_summary(bm_name, 'counters', 'out'))
+  text(run_summary(bm_name, 'counters', bm_name))
   if args.bigquery_upload:
-    with open('out.csv', 'w') as f:
-      f.write(subprocess.check_output(['tools/profiling/microbenchmarks/bm2bq.py', 'out.counters.json', 'out.opt.json']))
-    subprocess.check_call(['bq', 'load', 'microbenchmarks.microbenchmarks', 'out.csv'])
+    with open('%s.csv' % bm_name, 'w') as f:
+      f.write(subprocess.check_output(['tools/profiling/microbenchmarks/bm2bq.py',
+                                       '%s.counters.json' % bm_name,
+                                       '%s.opt.json' % bm_name]))
+    subprocess.check_call(['bq', 'load', 'microbenchmarks.microbenchmarks', '%s.csv' % bm_name])
 
 collectors = {
   'latency': collect_latency,
@@ -199,20 +214,11 @@ argp.add_argument('-c', '--collect',
                   default=sorted(collectors.keys()),
                   help='Which collectors should be run against each benchmark')
 argp.add_argument('-b', '--benchmarks',
-                  default=['bm_fullstack',
-                           'bm_closure',
-                           'bm_cq',
-                           'bm_call_create',
-                           'bm_error',
-                           'bm_chttp2_hpack',
-                           'bm_metadata'],
+                  choices=_AVAILABLE_BENCHMARK_TESTS,
+                  default=_AVAILABLE_BENCHMARK_TESTS,
                   nargs='+',
                   type=str,
                   help='Which microbenchmarks should be run')
-argp.add_argument('--diff_perf',
-                  default=None,
-                  type=str,
-                  help='Diff microbenchmarks against this git revision')
 argp.add_argument('--bigquery_upload',
                   default=False,
                   action='store_const',
@@ -224,30 +230,13 @@ argp.add_argument('--summary_time',
                   help='Minimum time to run benchmarks for the summary collection')
 args = argp.parse_args()
 
-for bm_name in args.benchmarks:
+try:
   for collect in args.collect:
-    collectors[collect](bm_name, args)
-if args.diff_perf:
-  for bm_name in args.benchmarks:
-    run_summary(bm_name, 'opt', '%s.new' % bm_name)
-  where_am_i = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip()
-  subprocess.check_call(['git', 'checkout', args.diff_perf])
-  comparables = []
-  subprocess.check_call(['make', 'clean'])
-  try:
     for bm_name in args.benchmarks:
-      try:
-        run_summary(bm_name, 'opt', '%s.old' % bm_name)
-        comparables.append(bm_name)
-      except subprocess.CalledProcessError, e:
-        pass
-  finally:
-    subprocess.check_call(['git', 'checkout', where_am_i])
-  for bm_name in comparables:
-    subprocess.check_call(['third_party/benchmark/tools/compare_bench.py',
-                          '%s.new.opt.json' % bm_name,
-                          '%s.old.opt.json' % bm_name])
-
-index_html += "</body>\n</html>\n"
-with open('reports/index.html', 'w') as f:
-  f.write(index_html)
+      collectors[collect](bm_name, args)
+finally:
+  if not os.path.exists('reports'):
+    os.makedirs('reports')
+  index_html += "</body>\n</html>\n"
+  with open('reports/index.html', 'w') as f:
+    f.write(index_html)
diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py
index 7c04d228ba3cd14ad88a4fc5750f10b57f2e6679..35d20be5b75d2abf58b37ed55316cf930fcbfd90 100755
--- a/tools/run_tests/run_performance_tests.py
+++ b/tools/run_tests/run_performance_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #
@@ -46,6 +46,7 @@ import tempfile
 import time
 import traceback
 import uuid
+import six
 
 import performance.scenario_config as scenario_config
 import python_utils.jobset as jobset
@@ -101,7 +102,7 @@ def create_qpsworker_job(language, shortname=None, port=10000, remote_host=None,
     user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, remote_host)
     ssh_cmd = ['ssh']
     cmdline = ['timeout', '%s' % (worker_timeout + 30)] + cmdline
-    ssh_cmd.extend([str(user_at_host), 'cd ~/performance_workspace/grpc/ && %s' % ' '.join(cmdline)])
+    ssh_cmd.extend([str(user_at_host), 'cd ~/performance_workspace/grpc/ && tools/run_tests/start_port_server.py && %s' % ' '.join(cmdline)])
     cmdline = ssh_cmd
 
   jobspec = jobset.JobSpec(
@@ -502,8 +503,8 @@ args = argp.parse_args()
 
 languages = set(scenario_config.LANGUAGES[l]
                 for l in itertools.chain.from_iterable(
-                      scenario_config.LANGUAGES.iterkeys() if x == 'all' else [x]
-                      for x in args.language))
+                      six.iterkeys(scenario_config.LANGUAGES) if x == 'all'
+                      else [x] for x in args.language))
 
 
 # Put together set of remote hosts where to run and build
@@ -572,8 +573,8 @@ for scenario in scenarios:
         jobs.append(create_quit_jobspec(scenario.workers, remote_host=args.remote_driver_host))
       scenario_failures, resultset = jobset.run(jobs, newline_on_success=True, maxjobs=1)
       total_scenario_failures += scenario_failures
-      merged_resultset = dict(itertools.chain(merged_resultset.iteritems(),
-                                              resultset.iteritems()))
+      merged_resultset = dict(itertools.chain(six.iteritems(merged_resultset),
+                                              six.iteritems(resultset)))
     finally:
       # Consider qps workers that need to be killed as failures
       qps_workers_killed += finish_qps_workers(scenario.workers)
diff --git a/tools/run_tests/run_stress_tests.py b/tools/run_tests/run_stress_tests.py
index a94a615b8863aea920bb943acaed1b77972766a1..4eea02118e54682f5c6e26b36f53c7fdaa11966f 100755
--- a/tools/run_tests/run_stress_tests.py
+++ b/tools/run_tests/run_stress_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -43,6 +43,7 @@ import sys
 import tempfile
 import time
 import uuid
+import six
 
 import python_utils.dockerjob as dockerjob
 import python_utils.jobset as jobset
@@ -239,9 +240,8 @@ servers = set(
     for s in itertools.chain.from_iterable(_SERVERS if x == 'all' else [x]
                                            for x in args.server))
 
-languages = set(_LANGUAGES[l]
-                for l in itertools.chain.from_iterable(_LANGUAGES.iterkeys(
-                ) if x == 'all' else [x] for x in args.language))
+languages = set(_LANGUAGES[l] for l in itertools.chain.from_iterable(
+  six.iterkeys(_LANGUAGES) if x == 'all' else [x] for x in args.language))
 
 docker_images = {}
 # languages for which to build docker images
@@ -267,7 +267,7 @@ if build_jobs:
     jobset.message('FAILED',
                    'Failed to build interop docker images.',
                    do_newline=True)
-    for image in docker_images.itervalues():
+    for image in six.itervalues(docker_images):
       dockerjob.remove_image(image, skip_nonexistent=True)
     sys.exit(1)
 
@@ -306,7 +306,7 @@ try:
 
   if not jobs:
     print('No jobs to run.')
-    for image in docker_images.itervalues():
+    for image in six.itervalues(docker_images):
       dockerjob.remove_image(image, skip_nonexistent=True)
     sys.exit(1)
 
@@ -324,8 +324,8 @@ finally:
     if not job.is_running():
       print('Server "%s" has exited prematurely.' % server)
 
-  dockerjob.finish_jobs([j for j in server_jobs.itervalues()])
+  dockerjob.finish_jobs([j for j in six.itervalues(server_jobs)])
 
-  for image in docker_images.itervalues():
+  for image in six.itervalues(docker_images):
     print('Removing docker image %s' % image)
     dockerjob.remove_image(image)
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index d4983403cc039bb8ebc68ca430d0f137719b4584..62e92c3d1dd0df8deda3696a6fc502642e347db1 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -54,6 +54,7 @@ import traceback
 import time
 from six.moves import urllib
 import uuid
+import six
 
 import python_utils.jobset as jobset
 import python_utils.report_utils as report_utils
@@ -246,9 +247,12 @@ class CLanguage(object):
         polling_strategies = ['all']
       for polling_strategy in polling_strategies:
         env={'GRPC_DEFAULT_SSL_ROOTS_FILE_PATH':
-                 _ROOT + '/src/core/lib/tsi/test_creds/ca.pem',
+                 _ROOT + '/src/core/tsi/test_creds/ca.pem',
              'GRPC_POLL_STRATEGY': polling_strategy,
              'GRPC_VERBOSITY': 'DEBUG'}
+        resolver = os.environ.get('GRPC_DNS_RESOLVER', None);
+        if resolver:
+          env['GRPC_DNS_RESOLVER'] = resolver
         shortname_ext = '' if polling_strategy=='all' else ' GRPC_POLL_STRATEGY=%s' % polling_strategy
         timeout_scaling = 1
         if polling_strategy == 'poll-cv':
@@ -391,6 +395,8 @@ class CLanguage(object):
       return ('jessie', self._gcc_make_options(version_suffix='-4.8'))
     elif compiler == 'gcc5.3':
       return ('ubuntu1604', [])
+    elif compiler == 'gcc_musl':
+      return ('alpine', [])
     elif compiler == 'clang3.4':
       # on ubuntu1404, clang-3.4 alias doesn't exist, just use 'clang'
       return ('ubuntu1404', self._clang_make_options())
@@ -423,11 +429,7 @@ class NodeLanguage(object):
     # we should specify in the compiler argument
     _check_compiler(self.args.compiler, ['default', 'node0.12',
                                          'node4', 'node5', 'node6',
-                                         'node7', 'electron1.3'])
-    if args.iomgr_platform == "uv":
-      self.use_uv = True
-    else:
-      self.use_uv = False
+                                         'node7', 'electron1.3', 'electron1.6'])
     if self.args.compiler == 'default':
       self.runtime = 'node'
       self.node_version = '7'
@@ -475,7 +477,6 @@ class NodeLanguage(object):
       else:
         config_flag = '--release'
       return [['tools\\run_tests\\helper_scripts\\build_node.bat',
-               '--grpc_uv={}'.format('true' if self.use_uv else 'false'),
                config_flag]]
     else:
       build_script = 'build_node'
@@ -484,8 +485,7 @@ class NodeLanguage(object):
         # building for electron requires a patch version
         self.node_version += '.0'
       return [['tools/run_tests/helper_scripts/{}.sh'.format(build_script),
-               self.node_version,
-               '--grpc_uv={}'.format('true' if self.use_uv else 'false')]]
+               self.node_version]]
 
   def post_tests_steps(self):
     return []
@@ -610,7 +610,10 @@ class PythonLanguage(object):
     return [config.build for config in self.pythons]
 
   def post_tests_steps(self):
-    return []
+    if self.config != 'gcov':
+      return []
+    else:
+      return [['tools/run_tests/helper_scripts/post_tests_python.sh']]
 
   def makefile_name(self):
     return 'Makefile'
@@ -619,7 +622,12 @@ class PythonLanguage(object):
     return 'tools/dockerfile/test/python_%s_%s' % (self.python_manager_name(), _docker_arch_suffix(self.args.arch))
 
   def python_manager_name(self):
-    return 'pyenv' if self.args.compiler in ['python3.5', 'python3.6'] else 'jessie'
+    if self.args.compiler in ['python3.5', 'python3.6']:
+      return 'pyenv'
+    elif self.args.compiler == 'python_alpine':
+      return 'alpine'
+    else:
+      return 'jessie'
 
   def _get_pythons(self, args):
     if args.arch == 'x86':
@@ -677,6 +685,8 @@ class PythonLanguage(object):
       return (pypy27_config,)
     elif args.compiler == 'pypy3':
       return (pypy32_config,)
+    elif args.compiler == 'python_alpine':
+      return (python27_config,)
     else:
       raise Exception('Compiler %s not supported.' % args.compiler)
 
@@ -692,9 +702,13 @@ class RubyLanguage(object):
     _check_compiler(self.args.compiler, ['default'])
 
   def test_specs(self):
-    return [self.config.job_spec(['tools/run_tests/helper_scripts/run_ruby.sh'],
-                                 timeout_seconds=10*60,
-                                 environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
+    tests = [self.config.job_spec(['tools/run_tests/helper_scripts/run_ruby.sh'],
+                                  timeout_seconds=10*60,
+                                  environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
+    tests.append(self.config.job_spec(['tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh'],
+                 timeout_seconds=10*60,
+                 environ=_FORCE_ENVIRON_FOR_WRAPPERS))
+    return tests
 
   def pre_build_steps(self):
     return [['tools/run_tests/helper_scripts/pre_build_ruby.sh']]
@@ -732,21 +746,18 @@ class CSharpLanguage(object):
     if self.platform == 'windows':
       _check_compiler(self.args.compiler, ['coreclr', 'default'])
       _check_arch(self.args.arch, ['default'])
-      self._cmake_arch_option = 'x64' if self.args.compiler == 'coreclr' else 'Win32'
+      self._cmake_arch_option = 'x64'
       self._make_options = []
     else:
       _check_compiler(self.args.compiler, ['default', 'coreclr'])
-      if self.platform == 'linux' and self.args.compiler == 'coreclr':
-        self._docker_distro = 'coreclr'
-      else:
-        self._docker_distro = 'jessie'
+      self._docker_distro = 'jessie'
 
       if self.platform == 'mac':
         # TODO(jtattermusch): EMBED_ZLIB=true currently breaks the mac build
         self._make_options = ['EMBED_OPENSSL=true']
         if self.args.compiler != 'coreclr':
           # On Mac, official distribution of mono is 32bit.
-          self._make_options += ['CFLAGS=-m32', 'LDFLAGS=-m32']
+          self._make_options += ['ARCH_FLAGS=-m32', 'LDFLAGS=-m32']
       else:
         self._make_options = ['EMBED_OPENSSL=true', 'EMBED_ZLIB=true']
 
@@ -755,7 +766,7 @@ class CSharpLanguage(object):
       tests_by_assembly = json.load(f)
 
     msbuild_config = _MSBUILD_CONFIG[self.config.build_config]
-    nunit_args = ['--labels=All']
+    nunit_args = ['--labels=All', '--noresult', '--workers=1']
     assembly_subdir = 'bin/%s' % msbuild_config
     assembly_extension = '.exe'
 
@@ -764,14 +775,14 @@ class CSharpLanguage(object):
       runtime_cmd = ['dotnet', 'exec']
       assembly_extension = '.dll'
     else:
-      nunit_args += ['--noresult', '--workers=1']
+      assembly_subdir += '/net45'
       if self.platform == 'windows':
         runtime_cmd = []
       else:
         runtime_cmd = ['mono']
 
     specs = []
-    for assembly in tests_by_assembly.iterkeys():
+    for assembly in six.iterkeys(tests_by_assembly):
       assembly_file = 'src/csharp/%s/%s/%s%s' % (assembly,
                                                  assembly_subdir,
                                                  assembly,
@@ -816,18 +827,10 @@ class CSharpLanguage(object):
     return self._make_options;
 
   def build_steps(self):
-    if self.args.compiler == 'coreclr':
-      if self.platform == 'windows':
-        return [['tools\\run_tests\\helper_scripts\\build_csharp_coreclr.bat']]
-      else:
-        return [['tools/run_tests/helper_scripts/build_csharp_coreclr.sh']]
+    if self.platform == 'windows':
+      return [['tools\\run_tests\\helper_scripts\\build_csharp.bat']]
     else:
-      if self.platform == 'windows':
-        return [['vsprojects\\build_vs2015.bat',
-                 'src/csharp/Grpc.sln',
-                 '/p:Configuration=%s' % _MSBUILD_CONFIG[self.config.build_config]]]
-      else:
-        return [['tools/run_tests/helper_scripts/build_csharp.sh']]
+      return [['tools/run_tests/helper_scripts/build_csharp.sh']]
 
   def post_tests_steps(self):
     if self.platform == 'windows':
@@ -1164,12 +1167,12 @@ argp.add_argument('--arch',
                   help='Selects architecture to target. For some platforms "default" is the only supported choice.')
 argp.add_argument('--compiler',
                   choices=['default',
-                           'gcc4.4', 'gcc4.6', 'gcc4.8', 'gcc4.9', 'gcc5.3',
+                           'gcc4.4', 'gcc4.6', 'gcc4.8', 'gcc4.9', 'gcc5.3', 'gcc_musl',
                            'clang3.4', 'clang3.5', 'clang3.6', 'clang3.7',
                            'vs2013', 'vs2015',
-                           'python2.7', 'python3.4', 'python3.5', 'python3.6', 'pypy', 'pypy3',
+                           'python2.7', 'python3.4', 'python3.5', 'python3.6', 'pypy', 'pypy3', 'python_alpine',
                            'node0.12', 'node4', 'node5', 'node6', 'node7',
-                           'electron1.3',
+                           'electron1.3', 'electron1.6',
                            'coreclr',
                            'cmake'],
                   default='default',
@@ -1201,6 +1204,7 @@ argp.add_argument('--quiet_success',
                        'Useful when running many iterations of each test (argument -n).')
 argp.add_argument('--force_default_poller', default=False, action='store_const', const=True,
                   help='Dont try to iterate over many polling strategies when they exist')
+argp.add_argument('--max_time', default=-1, type=int, help='Maximum test runtime in seconds')
 args = argp.parse_args()
 
 if args.force_default_poller:
@@ -1262,7 +1266,9 @@ if any(language.make_options() for language in languages):
     print('languages with custom make options cannot be built simultaneously with other languages')
     sys.exit(1)
   else:
-    language_make_options = next(iter(languages)).make_options()
+    # Combining make options is not clean and just happens to work. It allows C/C++ and C# to build
+    # together, and is only used under gcov. All other configs should build languages individually.
+    language_make_options = list(set([make_option for lang in languages for make_option in lang.make_options()]))
 
 if args.use_docker:
   if not args.travis:
@@ -1298,7 +1304,9 @@ if args.use_docker:
   if not args.travis:
     env['TTY_FLAG'] = '-t'  # enables Ctrl-C when not on Jenkins.
 
-  run_shell_command('tools/run_tests/dockerize/build_docker_and_run_tests.sh', env=env)
+  subprocess.check_call('tools/run_tests/dockerize/build_docker_and_run_tests.sh',
+                        shell=True,
+                        env=env)
   sys.exit(0)
 
 _check_arch_option(args.arch)
@@ -1339,7 +1347,8 @@ def make_jobspec(cfg, targets, makefile='Makefile'):
                               '-f', makefile,
                               '-j', '%d' % args.jobs,
                               'EXTRA_DEFINES=GRPC_TEST_SLOWDOWN_MACHINE_FACTOR=%f' % args.slowdown,
-                              'CONFIG=%s' % cfg] +
+                              'CONFIG=%s' % cfg,
+                              'Q='] +
                               language_make_options +
                              ([] if not args.travis else ['JENKINS_BUILD=1']) +
                              targets,
@@ -1452,7 +1461,7 @@ def _build_and_run(
            not re.search(args.regex_exclude, spec.shortname))))
     # When running on travis, we want out test runs to be as similar as possible
     # for reproducibility purposes.
-    if args.travis:
+    if args.travis and args.max_time <= 0:
       massaged_one_run = sorted(one_run, key=lambda x: x.shortname)
     else:
       # whereas otherwise, we want to shuffle things up to give all tests a
@@ -1465,10 +1474,9 @@ def _build_and_run(
       sample_size = int(num_jobs * args.sample_percent/100.0)
       massaged_one_run = random.sample(massaged_one_run, sample_size)
       if not isclose(args.sample_percent, 100.0):
+        assert args.runs_per_test == 1, "Can't do sampling (-p) over multiple runs (-n)."
         print("Running %d tests out of %d (~%d%%)" %
               (sample_size, num_jobs, args.sample_percent))
-      else:
-        assert args.runs_per_test == 1, "Can't do sampling (-p) over multiple runs (-n)."
     if infinite_runs:
       assert len(massaged_one_run) > 0, 'Must have at least one test for a -n inf run'
     runs_sequence = (itertools.repeat(massaged_one_run) if infinite_runs
@@ -1481,7 +1489,7 @@ def _build_and_run(
         all_runs, check_cancelled, newline_on_success=newline_on_success,
         travis=args.travis, maxjobs=args.jobs,
         stop_on_failure=args.stop_on_failure,
-        quiet_success=args.quiet_success)
+        quiet_success=args.quiet_success, max_time=args.max_time)
     if resultset:
       for k, v in sorted(resultset.items()):
         num_runs, num_failures = _calculate_num_runs_failures(v)
diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index 5f5df70d1da4a125300be1ed44fbf22a79ecf944..474b56b5de5f6dc5735226ab4285ae6dce2fa04f 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -30,6 +30,8 @@
 
 """Run test matrix."""
 
+from __future__ import print_function
+
 import argparse
 import multiprocessing
 import os
@@ -49,32 +51,49 @@ _RUNTESTS_TIMEOUT = 4*60*60
 # Number of jobs assigned to each run_tests.py instance
 _DEFAULT_INNER_JOBS = 2
 
+# report suffix is important for reports to get picked up by internal CI
+_REPORT_SUFFIX = 'sponge_log.xml'
+
+
+def _report_filename(name):
+  """Generates report file name"""
+  return 'report_%s_%s' % (name, _REPORT_SUFFIX)
+
+
+def _report_filename_internal_ci(name):
+  """Generates report file name that leads to better presentation by internal CI"""
+  return '%s/%s' % (name, _REPORT_SUFFIX)
+
 
-def _docker_jobspec(name, runtests_args=[], inner_jobs=_DEFAULT_INNER_JOBS):
+def _docker_jobspec(name, runtests_args=[], runtests_envs={},
+                    inner_jobs=_DEFAULT_INNER_JOBS):
   """Run a single instance of run_tests.py in a docker container"""
   test_job = jobset.JobSpec(
           cmdline=['python', 'tools/run_tests/run_tests.py',
                    '--use_docker',
                    '-t',
                    '-j', str(inner_jobs),
-                   '-x', 'report_%s.xml' % name,
+                   '-x', _report_filename(name),
                    '--report_suite_name', '%s' % name] + runtests_args,
+          environ=runtests_envs,
           shortname='run_tests_%s' % name,
           timeout_seconds=_RUNTESTS_TIMEOUT)
   return test_job
 
 
-def _workspace_jobspec(name, runtests_args=[], workspace_name=None, inner_jobs=_DEFAULT_INNER_JOBS):
+def _workspace_jobspec(name, runtests_args=[], workspace_name=None,
+                       runtests_envs={}, inner_jobs=_DEFAULT_INNER_JOBS):
   """Run a single instance of run_tests.py in a separate workspace"""
   if not workspace_name:
     workspace_name = 'workspace_%s' % name
   env = {'WORKSPACE_NAME': workspace_name}
+  env.update(runtests_envs)
   test_job = jobset.JobSpec(
           cmdline=['bash',
                    'tools/run_tests/helper_scripts/run_tests_in_workspace.sh',
                    '-t',
                    '-j', str(inner_jobs),
-                   '-x', '../report_%s.xml' % name,
+                   '-x', '../%s' % _report_filename(name),
                    '--report_suite_name', '%s' % name] + runtests_args,
           environ=env,
           shortname='run_tests_%s' % name,
@@ -84,7 +103,7 @@ def _workspace_jobspec(name, runtests_args=[], workspace_name=None, inner_jobs=_
 
 def _generate_jobs(languages, configs, platforms, iomgr_platform = 'native',
                   arch=None, compiler=None,
-                  labels=[], extra_args=[],
+                  labels=[], extra_args=[], extra_envs={},
                   inner_jobs=_DEFAULT_INNER_JOBS):
   result = []
   for language in languages:
@@ -92,19 +111,24 @@ def _generate_jobs(languages, configs, platforms, iomgr_platform = 'native',
       for config in configs:
         name = '%s_%s_%s_%s' % (language, platform, config, iomgr_platform)
         runtests_args = ['-l', language,
-                         '-c', config]
+                         '-c', config,
+                         '--iomgr_platform', iomgr_platform]
         if arch or compiler:
           name += '_%s_%s' % (arch, compiler)
           runtests_args += ['--arch', arch,
                             '--compiler', compiler]
+        for extra_env in extra_envs:
+          name += '_%s_%s' % (extra_env, extra_envs[extra_env])
 
         runtests_args += extra_args
         if platform == 'linux':
-          job = _docker_jobspec(name=name, runtests_args=runtests_args, inner_jobs=inner_jobs)
+          job = _docker_jobspec(name=name, runtests_args=runtests_args,
+                                runtests_envs=extra_envs, inner_jobs=inner_jobs)
         else:
-          job = _workspace_jobspec(name=name, runtests_args=runtests_args, inner_jobs=inner_jobs)
+          job = _workspace_jobspec(name=name, runtests_args=runtests_args,
+                                   runtests_envs=extra_envs, inner_jobs=inner_jobs)
 
-        job.labels = [platform, config, language] + labels
+        job.labels = [platform, config, language, iomgr_platform] + labels
         result.append(job)
   return result
 
@@ -145,7 +169,7 @@ def _create_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS):
 
   # sanitizers
   test_jobs += _generate_jobs(languages=['c'],
-                              configs=['msan', 'asan', 'tsan'],
+                              configs=['msan', 'asan', 'tsan', 'ubsan'],
                               platforms=['linux'],
                               labels=['sanitizers'],
                               extra_args=extra_args,
@@ -173,7 +197,7 @@ def _create_portability_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS)
                               inner_jobs=inner_jobs)
 
   # portability C and C++ on x64
-  for compiler in ['gcc4.4', 'gcc4.6', 'gcc5.3',
+  for compiler in ['gcc4.4', 'gcc4.6', 'gcc5.3', 'gcc_musl',
                    'clang3.5', 'clang3.6', 'clang3.7']:
     test_jobs += _generate_jobs(languages=['c'],
                                 configs=['dbg'],
@@ -207,6 +231,21 @@ def _create_portability_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS)
                                   extra_args=extra_args,
                                   inner_jobs=inner_jobs)
 
+  # C and C++ with the c-ares DNS resolver on Linux
+  test_jobs += _generate_jobs(languages=['c', 'c++'],
+                              configs=['dbg'], platforms=['linux'],
+                              labels=['portability'],
+                              extra_args=extra_args,
+                              extra_envs={'GRPC_DNS_RESOLVER': 'ares'})
+
+  # TODO(zyc): Turn on this test after adding c-ares support on windows.
+  # C with the c-ares DNS resolver on Windonws
+  # test_jobs += _generate_jobs(languages=['c'],
+  #                             configs=['dbg'], platforms=['windows'],
+  #                             labels=['portability'],
+  #                             extra_args=extra_args,
+  #                             extra_envs={'GRPC_DNS_RESOLVER': 'ares'})
+
   # cmake build for C and C++
   # TODO(jtattermusch): some of the tests are failing, so we force --build_only
   # to make sure it's buildable at least.
@@ -249,15 +288,7 @@ def _create_portability_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS)
                               configs=['dbg'],
                               platforms=['linux'],
                               arch='default',
-                              compiler='electron1.3',
-                              labels=['portability'],
-                              extra_args=extra_args,
-                              inner_jobs=inner_jobs)
-
-  test_jobs += _generate_jobs(languages=['node'],
-                              configs=['dbg'],
-                              platforms=['linux'],
-                              iomgr_platform='uv',
+                              compiler='electron1.6',
                               labels=['portability'],
                               extra_args=extra_args,
                               inner_jobs=inner_jobs)
@@ -347,8 +378,20 @@ if __name__ == "__main__":
   argp.add_argument('-n', '--runs_per_test', default=1, type=_runs_per_test_type,
                     help='How many times to run each tests. >1 runs implies ' +
                     'omitting passing test from the output & reports.')
+  argp.add_argument('--max_time', default=-1, type=int,
+                    help='Maximum amount of time to run tests for' +
+                         '(other tests will be skipped)')
+  argp.add_argument('--internal_ci',
+                    default=False,
+                    action='store_const',
+                    const=True,
+                    help='Put reports into subdirectories to improve presentation of '
+                    'results by Internal CI.')
   args = argp.parse_args()
 
+  if args.internal_ci:
+    _report_filename = _report_filename_internal_ci  # override the function
+
   extra_args = []
   if args.build_only:
     extra_args.append('--build_only')
@@ -358,6 +401,8 @@ if __name__ == "__main__":
     extra_args.append('-n')
     extra_args.append('%s' % args.runs_per_test)
     extra_args.append('--quiet_success')
+  if args.max_time > 0:
+    extra_args.extend(('--max_time', '%d' % args.max_time))
 
   all_jobs = _create_test_jobs(extra_args=extra_args, inner_jobs=args.inner_jobs) + \
              _create_portability_test_jobs(extra_args=extra_args, inner_jobs=args.inner_jobs)
@@ -412,10 +457,10 @@ if __name__ == "__main__":
                                        maxjobs=args.jobs)
   # Merge skipped tests into results to show skipped tests on report.xml
   if skipped_jobs:
-    skipped_results = jobset.run(skipped_jobs,
-                                 skip_jobs=True)
+    ignored_num_skipped_failures, skipped_results = jobset.run(
+        skipped_jobs, skip_jobs=True)
     resultset.update(skipped_results)
-  report_utils.render_junit_xml_report(resultset, 'report.xml',
+  report_utils.render_junit_xml_report(resultset, _report_filename('aggregate_tests'),
                                        suite_name='aggregate_tests')
 
   if num_failures == 0:
diff --git a/tools/run_tests/sanity/check_sources_and_headers.py b/tools/run_tests/sanity/check_sources_and_headers.py
index a86db02b80bf7841a952c78538b3e4dba05d0f1f..42892ea69dd9cbabc42deeadf4432f53adf1ced2 100755
--- a/tools/run_tests/sanity/check_sources_and_headers.py
+++ b/tools/run_tests/sanity/check_sources_and_headers.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -28,6 +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.
 
+from __future__ import print_function
+
 import json
 import os
 import re
@@ -75,14 +77,14 @@ for target in js:
       for line in src:
         m = re_inc1.match(line)
         if m:
-          if not target_has_header(target, m.group(1)) and not target['is_filegroup']:
+          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)) and not target['is_filegroup']:
+          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)))
diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh
index cfe4e2731c04e0ec19d2177dfdfbbd5f60564850..6be7a39d070f62fc459f55cfb7922b45938ccdc3 100755
--- a/tools/run_tests/sanity/check_submodules.sh
+++ b/tools/run_tests/sanity/check_submodules.sh
@@ -45,10 +45,10 @@ cat << EOF | awk '{ print $1 }' | sort > $want_submodules
  78684e5b222645828ca302e56b40b9daff2b2d27 third_party/boringssl (78684e5)
  886e7d75368e3f4fab3f4d0d3584e4abfc557755 third_party/boringssl-with-bazel (version_for_cocoapods_7.0-857-g886e7d7)
  30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e third_party/gflags (v2.2.0)
- c99458533a9b4c743ed51537e25989ea55944908 third_party/googletest (release-1.7.0)
- a428e42072765993ff674fda72863c9f1aa2d268 third_party/protobuf (v3.1.0-alpha-1)
- bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c third_party/thrift (bcad917)
- 50893291621658f355bc5b4d450a8d06a563053d third_party/zlib (v1.2.8)
+ ec44c6c1675c25b9827aacd08c02433cccde7780 third_party/googletest (release-1.8.0)
+ 593e917c176b5bc5aafa57bf9f6030d749d91cd5 third_party/protobuf (v3.1.0-alpha-1-326-g593e917)
+ cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11)
+ 7691f773af79bf75a62d1863fd0f13ebf9dc51b1 third_party/cares/cares (1.12.0)
 EOF
 
 diff -u $submodules $want_submodules
diff --git a/tools/run_tests/sanity/check_test_filtering.py b/tools/run_tests/sanity/check_test_filtering.py
index 290a6e2ddf604bb63cd951489358bda72f516ab9..ba03f1120923e447d7509478a2850849fe5afc2d 100755
--- a/tools/run_tests/sanity/check_test_filtering.py
+++ b/tools/run_tests/sanity/check_test_filtering.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 
 # Copyright 2016, Google Inc.
 # All rights reserved.
@@ -62,7 +62,7 @@ class TestFilteringTest(unittest.TestCase):
     def _get_changed_files(foo):
       return changed_files
     filter_pull_request_tests._get_changed_files = _get_changed_files
-    print
+    print()
     filtered_jobs = filter_pull_request_tests.filter_tests(all_jobs, "test")
 
     # Make sure sanity tests aren't being filtered out
diff --git a/tools/run_tests/sanity/check_version.py b/tools/run_tests/sanity/check_version.py
index e62f39081850bb9311f0de96d87592a6a2baa197..d247260dbbbb1351dff5e1916f9e9fdeb3ae98d4 100755
--- a/tools/run_tests/sanity/check_version.py
+++ b/tools/run_tests/sanity/check_version.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 
 # Copyright 2016, Google Inc.
 # All rights reserved.
@@ -29,6 +29,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.
 
+from __future__ import print_function
+
 import sys
 import yaml
 import os
@@ -48,13 +50,13 @@ try:
     'git rev-parse --abbrev-ref HEAD',
     shell=True)
 except:
-  print 'WARNING: not a git repository'
+  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'
+    print('RELEASE branch')
     # version number should align with the branched version
     check_version = lambda version: (
       version.major == int(m.group(1)) and
@@ -78,7 +80,7 @@ settings = build_yaml['settings']
 top_version = Version(settings['version'])
 if not check_version(top_version):
   errors += 1
-  print warning % ('version', top_version)
+  print(warning % ('version', top_version))
 
 for tag, value in settings.iteritems():
   if re.match(r'^[a-z]+_version$', tag):
@@ -86,12 +88,14 @@ for tag, value in settings.iteritems():
     if tag != 'core_version':
       if value.major != top_version.major:
         errors += 1
-        print 'major version mismatch on %s: %d vs %d' % (tag, value.major, top_version.major)
+        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)
+        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)
+      print(warning % (tag, value))
 
 sys.exit(errors)
diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py
index afac10bf80e72b4a26f5e7ca9d2bd829b07c23c1..2387c5f1da0a414ee23fe10e6d24636f8c82875c 100755
--- a/tools/run_tests/sanity/core_banned_functions.py
+++ b/tools/run_tests/sanity/core_banned_functions.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 
 # Copyright 2016, Google Inc.
 # All rights reserved.
@@ -29,6 +29,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.
 
+from __future__ import print_function
+
 import os
 import sys
 
@@ -42,6 +44,13 @@ BANNED_EXCEPT = {
     'grpc_slice_buffer_reset_and_unref(': ['src/core/lib/slice/slice_buffer.c'],
     'grpc_slice_ref(': ['src/core/lib/slice/slice.c'],
     'grpc_slice_unref(': ['src/core/lib/slice/slice.c'],
+    'grpc_error_create(': ['src/core/lib/iomgr/error.c'],
+    'grpc_error_ref(': ['src/core/lib/iomgr/error.c'],
+    'grpc_error_unref(': ['src/core/lib/iomgr/error.c'],
+    'grpc_os_error(': ['src/core/lib/iomgr/error.c'],
+    'grpc_wsa_error(': ['src/core/lib/iomgr/error.c'],
+    'grpc_log_if_error(': ['src/core/lib/iomgr/error.c'],
+    'grpc_slice_malloc(': ['src/core/lib/slice/slice.c'],
 }
 
 errors = 0
@@ -54,7 +63,7 @@ for root, dirs, files in os.walk('src/core'):
     for banned, exceptions in BANNED_EXCEPT.items():
       if path in exceptions: continue
       if banned in text:
-        print 'Illegal use of "%s" in %s' % (banned, path)
+        print('Illegal use of "%s" in %s' % (banned, path))
         errors += 1
 
 assert errors == 0
diff --git a/tools/run_tests/start_port_server.py b/tools/run_tests/start_port_server.py
index e33ac12bd3bee5707967e71f7b35d11c29de44cc..bfd72222b660bf8c6708ab8e277ebe629b257d4d 100755
--- a/tools/run_tests/start_port_server.py
+++ b/tools/run_tests/start_port_server.py
@@ -39,8 +39,10 @@ The path to this file is called out in test/core/util/port.c, and printed as
 an error message to users.
 """
 
+from __future__ import print_function
+
 import python_utils.start_port_server as start_port_server
 
 start_port_server.start_port_server()
 
-print "Port server started successfully"
+print("Port server started successfully")
diff --git a/tools/run_tests/stress_test/print_summary.py b/tools/run_tests/stress_test/print_summary.py
index cb1a33961e45a5cb05895c3c232ddefaba2faa56..6f4ada2f4fd23a6e341323f25f2f2b198ae71dee 100755
--- a/tools/run_tests/stress_test/print_summary.py
+++ b/tools/run_tests/stress_test/print_summary.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #
diff --git a/tools/run_tests/stress_test/run_on_gke.py b/tools/run_tests/stress_test/run_on_gke.py
index e2be76e245ae9458c0ffdeac17818ced07ffd67a..b190ebde7a4f44d697b7eab4b23515755a6553d6 100755
--- a/tools/run_tests/stress_test/run_on_gke.py
+++ b/tools/run_tests/stress_test/run_on_gke.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
@@ -27,6 +27,9 @@
 # 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 __future__ import print_function
+
 import argparse
 import datetime
 import json
@@ -124,23 +127,24 @@ class DockerImage:
     return 'gcr.io/%s/%s' % (project_id, image_name)
 
   def build_image(self):
-    print 'Building docker image: %s (tag: %s)' % (self.image_name,
-                                                   self.tag_name)
+    print('Building docker image: %s (tag: %s)' % (self.image_name,
+                                                   self.tag_name))
     os.environ['INTEROP_IMAGE'] = self.image_name
     os.environ['INTEROP_IMAGE_REPOSITORY_TAG'] = self.tag_name
     os.environ['BASE_NAME'] = self.dockerfile_dir
     os.environ['BUILD_TYPE'] = self.build_type
-    print 'DEBUG: path: ', self.build_script_path
+    print('DEBUG: path: ', self.build_script_path)
     if subprocess.call(args=[self.build_script_path]) != 0:
-      print 'Error in building the Docker image'
+      print('Error in building the Docker image')
       return False
     return True
 
   def push_to_gke_registry(self):
     cmd = ['gcloud', 'docker', 'push', self.tag_name]
-    print 'Pushing %s to the GKE registry..' % self.tag_name
+    print('Pushing %s to the GKE registry..' % self.tag_name)
     if subprocess.call(args=cmd) != 0:
-      print 'Error in pushing the image %s to the GKE registry' % self.tag_name
+      print('Error in pushing the image %s to the GKE registry' %
+            self.tag_name)
       return False
     return True
 
@@ -199,11 +203,11 @@ class Gke:
       cmd = ['kubectl', 'proxy', '--port=%d' % port]
       self.p = subprocess.Popen(args=cmd)
       time.sleep(2)
-      print '\nStarted kubernetes proxy on port: %d' % port
+      print('\nStarted kubernetes proxy on port: %d' % port)
 
     def __del__(self):
       if self.p is not None:
-        print 'Shutting down Kubernetes proxy..'
+        print('Shutting down Kubernetes proxy..')
         self.p.kill()
 
   def __init__(self, project_id, run_id, dataset_id, summary_table_id,
@@ -253,7 +257,7 @@ class Gke:
 
     for pod_name in server_pod_spec.pod_names():
       server_env['POD_NAME'] = pod_name
-      print 'Creating server: %s' % pod_name
+      print('Creating server: %s' % pod_name)
       is_success = kubernetes_api.create_pod_and_service(
           'localhost',
           self.kubernetes_port,
@@ -267,11 +271,11 @@ class Gke:
           True  # Headless = True for server to that GKE creates a DNS record for pod_name
       )
       if not is_success:
-        print 'Error in launching server: %s' % pod_name
+        print('Error in launching server: %s' % pod_name)
         break
 
     if is_success:
-      print 'Successfully created server(s)'
+      print('Successfully created server(s)')
 
     return is_success
 
@@ -301,7 +305,7 @@ class Gke:
 
     for pod_name in client_pod_spec.pod_names():
       client_env['POD_NAME'] = pod_name
-      print 'Creating client: %s' % pod_name
+      print('Creating client: %s' % pod_name)
       is_success = kubernetes_api.create_pod_and_service(
           'localhost',
           self.kubernetes_port,
@@ -316,18 +320,18 @@ class Gke:
       )
 
       if not is_success:
-        print 'Error in launching client %s' % pod_name
+        print('Error in launching client %s' % pod_name)
         break
 
     if is_success:
-      print 'Successfully created all client(s)'
+      print('Successfully created all client(s)')
 
     return is_success
 
   def _delete_pods(self, pod_name_list):
     is_success = True
     for pod_name in pod_name_list:
-      print 'Deleting %s' % pod_name
+      print('Deleting %s' % pod_name)
       is_success = kubernetes_api.delete_pod_and_service(
           'localhost',
           self.kubernetes_port,
@@ -335,11 +339,11 @@ class Gke:
           pod_name)
 
       if not is_success:
-        print 'Error in deleting pod %s' % pod_name
+        print('Error in deleting pod %s' % pod_name)
         break
 
     if is_success:
-      print 'Successfully deleted all pods'
+      print('Successfully deleted all pods')
 
     return is_success
 
@@ -353,7 +357,7 @@ class Gke:
 class Config:
 
   def __init__(self, config_filename, gcp_project_id):
-    print 'Loading configuration...'
+    print('Loading configuration...')
     config_dict = self._load_config(config_filename)
 
     self.global_settings = self._parse_global_settings(config_dict,
@@ -367,7 +371,7 @@ class Config:
     self.client_pod_specs_dict = self._parse_client_pod_specs(
         config_dict, self.docker_images_dict, self.client_templates_dict,
         self.server_pod_specs_dict)
-    print 'Loaded Configuaration.'
+    print('Loaded Configuaration.')
 
   def _parse_global_settings(self, config_dict, gcp_project_id):
     global_settings_dict = config_dict['globalSettings']
@@ -540,8 +544,8 @@ def run_tests(config):
   # 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' % (config.global_settings.dataset_id_prefix, run_id)
-  print 'Run id:', run_id
-  print 'Dataset id:', dataset_id
+  print('Run id:', run_id)
+  print('Dataset id:', dataset_id)
 
   bq_helper = BigQueryHelper(run_id, '', '',
                              config.global_settings.gcp_project_id, dataset_id,
@@ -557,7 +561,7 @@ def run_tests(config):
   is_success = True
 
   try:
-    print 'Launching servers..'
+    print('Launching servers..')
     for name, server_pod_spec in config.server_pod_specs_dict.iteritems():
       if not gke.launch_servers(server_pod_spec):
         is_success = False  # is_success is checked in the 'finally' block
@@ -579,11 +583,12 @@ def run_tests(config):
     start_time = datetime.datetime.now()
     end_time = start_time + datetime.timedelta(
         seconds=config.global_settings.test_duration_secs)
-    print 'Running the test until %s' % end_time.isoformat()
+    print('Running the test until %s' % end_time.isoformat())
 
     while True:
       if datetime.datetime.now() > end_time:
-        print 'Test was run for %d seconds' % config.global_settings.test_duration_secs
+        print('Test was run for %d seconds' %
+              config.global_settings.test_duration_secs)
         break
 
       # Check if either stress server or clients have failed (btw, the bq_helper
@@ -591,11 +596,12 @@ def run_tests(config):
       # have a failure status)
       if bq_helper.check_if_any_tests_failed():
         is_success = False
-        print 'Some tests failed.'
+        print('Some tests failed.')
         break  # Don't 'return' here. We still want to call bq_helper to print qps/summary tables
 
       # Tests running fine. Wait until next poll time to check the status
-      print 'Sleeping for %d seconds..' % config.global_settings.test_poll_interval_secs
+      print('Sleeping for %d seconds..' %
+            config.global_settings.test_poll_interval_secs)
       time.sleep(config.global_settings.test_poll_interval_secs)
 
     # Print BiqQuery tables
diff --git a/tools/run_tests/task_runner.py b/tools/run_tests/task_runner.py
index fdc46682223fed735454c3bb585bc8e0550b2f5d..0ec7efbbee6493da9e3b4778b8fee3e27730d13b 100755
--- a/tools/run_tests/task_runner.py
+++ b/tools/run_tests/task_runner.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #
diff --git a/tools/tsan_suppressions.txt b/tools/tsan_suppressions.txt
index 765fa098f92c5e4b9d9438859e4a1188c43167f1..e0c79072288285c7898769e8117089e1da6e3698 100644
--- a/tools/tsan_suppressions.txt
+++ b/tools/tsan_suppressions.txt
@@ -6,6 +6,8 @@ race:cleanse_ctr
 race:ssleay_rand_add
 race:ssleay_rand_bytes
 race:__sleep_for
-# protobuf has an idempotent write race in ByteSize
+# protobuf has an idempotent write race in ByteSize/GetCachedSize
 # https://github.com/google/protobuf/issues/2169
 race:ByteSize
+race:ByteSizeLong
+race:GetCachedSize
diff --git a/tools/ubsan_suppressions.txt b/tools/ubsan_suppressions.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9869f98a22e6507e64bc0bd927f782290d064edb
--- /dev/null
+++ b/tools/ubsan_suppressions.txt
@@ -0,0 +1,7 @@
+# boringssl stuff
+nonnull-attribute:bn_wexpand
+nonnull-attribute:CBB_add_bytes
+nonnull-attribute:rsa_blinding_get
+nonnull-attribute:ssl_copy_key_material
+alignment:CRYPTO_cbc128_encrypt
+
diff --git a/vsprojects/README.md b/vsprojects/README.md
index f1663d254850707d657863b4d5a8d1bddb2f93a1..1f0cdc24ba709e763ed59a9212009fab9026ebbf 100644
--- a/vsprojects/README.md
+++ b/vsprojects/README.md
@@ -1,10 +1,10 @@
-#Pre-generated MS Visual Studio project & solution files
+# Pre-generated MS Visual Studio project & solution files
 
 Versions 2013 and 2015 are both supported. You can use [their respective
 community
 editions](https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx).
 
-#Building
+# Building
 We are using [NuGet](http://www.nuget.org) to pull zlib and openssl dependencies.
 If you don't have Visual Studio NuGet plugin installed, you'll need to
 download nuget.exe from the web and manually restore the NuGet packages.
@@ -19,7 +19,7 @@ After that, you can build the solution using one of these options:
   1. open `grpc.sln` with Visual Studio and hit "Build".
   2. build from commandline using `msbuild grpc.sln /p:Configuration=Debug`
 
-#C/C++ Test Dependencies
+# C/C++ Test Dependencies
    * gtest isn't available as a git repo like the other dependencies.  download it and add it to `/third_party/gtest/` (the folder will end up with `/build-aux/`, `/cmake/`, `/codegear/`, etc. folders in it).  
     * if using vs2013: open/import the gtest solution in `/msvc/`, and save over the first solution (you will have to change it from read-only).  change all projects to use `/MDd` (Property Pages - C/C++ - Code Generation - Runtime Library) and build. This is a "multithreaded debug" setting and it needs to match grpc.
     * build all
diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln
index 623de48d3e79bffa9d2ec49129a9b67cdb828bf4..539f474f9ec59a07ac358a2ef628f896b861d03a 100644
--- a/vsprojects/buildtests_c.sln
+++ b/vsprojects/buildtests_c.sln
@@ -45,6 +45,15 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "alpn_test", "vcxproj\test\a
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "arena_test", "vcxproj\test\arena_test\arena_test.vcxproj", "{D85AC722-A88F-4280-F62E-672F571787FF}"
+	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}") = "bad_client_test", "vcxproj\test/bad_client\bad_client_test\bad_client_test.vcxproj", "{BA67B418-B699-E41A-9CC4-0279C49481A5}"
 	ProjectSection(myProperties) = preProject
         	lib = "True"
@@ -297,6 +306,28 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "endpoint_pair_test", "vcxpr
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "error_test", "vcxproj\test\error_test\error_test.vcxproj", "{42720233-A6D4-66BC-CCA2-06B57261D0B3}"
+	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}") = "fake_resolver_test", "vcxproj\test\fake_resolver_test\fake_resolver_test.vcxproj", "{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}"
+	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}") = "fling_client", "vcxproj\test\fling_client\fling_client.vcxproj", "{0647D598-9611-F659-EA36-DF995C9F736B}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -1222,6 +1253,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "message_compress_test", "vc
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minimal_stack_is_minimal_test", "vcxproj\test\minimal_stack_is_minimal_test\minimal_stack_is_minimal_test.vcxproj", "{68A54124-DFA3-4FF3-081F-70356222C977}"
+	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}") = "mlog_test", "vcxproj\test\mlog_test\mlog_test.vcxproj", "{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -1264,6 +1306,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "no_server_test", "vcxproj\t
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "parse_address_test", "vcxproj\test\parse_address_test\parse_address_test.vcxproj", "{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}"
+	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}") = "percent_encoding_test", "vcxproj\test\percent_encoding_test\percent_encoding_test.vcxproj", "{CCFC6A58-623D-9013-BFEB-C809809E2429}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -1364,31 +1417,30 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server_test", "vcxproj\test
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "set_initial_connect_string_test", "vcxproj\test\set_initial_connect_string_test\set_initial_connect_string_test.vcxproj", "{4A48E5A5-2E69-ED6D-063C-C297180A54D0}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_request_bad_client_test", "vcxproj\test\simple_request_bad_client_test\simple_request_bad_client_test.vcxproj", "{63422647-93FA-46BB-4827-95473D9D503C}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{E3110C46-A148-FF65-08FD-3324829BE7FE} = {E3110C46-A148-FF65-08FD-3324829BE7FE}
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
 		{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}") = "simple_request_bad_client_test", "vcxproj\test\simple_request_bad_client_test\simple_request_bad_client_test.vcxproj", "{63422647-93FA-46BB-4827-95473D9D503C}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slice_buffer_test", "vcxproj\test\slice_buffer_test\slice_buffer_test.vcxproj", "{F0FA4A41-5695-580A-DCDA-EC719CB041B0}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{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}") = "slice_buffer_test", "vcxproj\test\slice_buffer_test\slice_buffer_test.vcxproj", "{F0FA4A41-5695-580A-DCDA-EC719CB041B0}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slice_hash_table_test", "vcxproj\test\slice_hash_table_test\slice_hash_table_test.vcxproj", "{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
 	EndProjectSection
@@ -1454,6 +1506,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "status_conversion_test", "v
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stream_owned_slice_test", "vcxproj\test\stream_owned_slice_test\stream_owned_slice_test.vcxproj", "{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}"
+	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}") = "tcp_client_uv_test", "vcxproj\test\tcp_client_uv_test\tcp_client_uv_test.vcxproj", "{9814D850-F3BB-8C7A-4C78-2751C1E272F4}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -1675,6 +1738,22 @@ Global
 		{5BAAE7EA-A972-DD80-F190-29B9E3110BB3}.Release-DLL|Win32.Build.0 = Release|Win32
 		{5BAAE7EA-A972-DD80-F190-29B9E3110BB3}.Release-DLL|x64.ActiveCfg = Release|x64
 		{5BAAE7EA-A972-DD80-F190-29B9E3110BB3}.Release-DLL|x64.Build.0 = Release|x64
+		{D85AC722-A88F-4280-F62E-672F571787FF}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D85AC722-A88F-4280-F62E-672F571787FF}.Debug|x64.ActiveCfg = Debug|x64
+		{D85AC722-A88F-4280-F62E-672F571787FF}.Release|Win32.ActiveCfg = Release|Win32
+		{D85AC722-A88F-4280-F62E-672F571787FF}.Release|x64.ActiveCfg = Release|x64
+		{D85AC722-A88F-4280-F62E-672F571787FF}.Debug|Win32.Build.0 = Debug|Win32
+		{D85AC722-A88F-4280-F62E-672F571787FF}.Debug|x64.Build.0 = Debug|x64
+		{D85AC722-A88F-4280-F62E-672F571787FF}.Release|Win32.Build.0 = Release|Win32
+		{D85AC722-A88F-4280-F62E-672F571787FF}.Release|x64.Build.0 = Release|x64
+		{D85AC722-A88F-4280-F62E-672F571787FF}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{D85AC722-A88F-4280-F62E-672F571787FF}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{D85AC722-A88F-4280-F62E-672F571787FF}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{D85AC722-A88F-4280-F62E-672F571787FF}.Debug-DLL|x64.Build.0 = Debug|x64
+		{D85AC722-A88F-4280-F62E-672F571787FF}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{D85AC722-A88F-4280-F62E-672F571787FF}.Release-DLL|Win32.Build.0 = Release|Win32
+		{D85AC722-A88F-4280-F62E-672F571787FF}.Release-DLL|x64.ActiveCfg = Release|x64
+		{D85AC722-A88F-4280-F62E-672F571787FF}.Release-DLL|x64.Build.0 = Release|x64
 		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug|Win32.ActiveCfg = Debug|Win32
 		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug|x64.ActiveCfg = Debug|x64
 		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release|Win32.ActiveCfg = Release|Win32
@@ -2043,6 +2122,38 @@ Global
 		{37166D50-3AAA-1156-19F6-5901DFA55172}.Release-DLL|Win32.Build.0 = Release|Win32
 		{37166D50-3AAA-1156-19F6-5901DFA55172}.Release-DLL|x64.ActiveCfg = Release|x64
 		{37166D50-3AAA-1156-19F6-5901DFA55172}.Release-DLL|x64.Build.0 = Release|x64
+		{42720233-A6D4-66BC-CCA2-06B57261D0B3}.Debug|Win32.ActiveCfg = Debug|Win32
+		{42720233-A6D4-66BC-CCA2-06B57261D0B3}.Debug|x64.ActiveCfg = Debug|x64
+		{42720233-A6D4-66BC-CCA2-06B57261D0B3}.Release|Win32.ActiveCfg = Release|Win32
+		{42720233-A6D4-66BC-CCA2-06B57261D0B3}.Release|x64.ActiveCfg = Release|x64
+		{42720233-A6D4-66BC-CCA2-06B57261D0B3}.Debug|Win32.Build.0 = Debug|Win32
+		{42720233-A6D4-66BC-CCA2-06B57261D0B3}.Debug|x64.Build.0 = Debug|x64
+		{42720233-A6D4-66BC-CCA2-06B57261D0B3}.Release|Win32.Build.0 = Release|Win32
+		{42720233-A6D4-66BC-CCA2-06B57261D0B3}.Release|x64.Build.0 = Release|x64
+		{42720233-A6D4-66BC-CCA2-06B57261D0B3}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{42720233-A6D4-66BC-CCA2-06B57261D0B3}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{42720233-A6D4-66BC-CCA2-06B57261D0B3}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{42720233-A6D4-66BC-CCA2-06B57261D0B3}.Debug-DLL|x64.Build.0 = Debug|x64
+		{42720233-A6D4-66BC-CCA2-06B57261D0B3}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{42720233-A6D4-66BC-CCA2-06B57261D0B3}.Release-DLL|Win32.Build.0 = Release|Win32
+		{42720233-A6D4-66BC-CCA2-06B57261D0B3}.Release-DLL|x64.ActiveCfg = Release|x64
+		{42720233-A6D4-66BC-CCA2-06B57261D0B3}.Release-DLL|x64.Build.0 = Release|x64
+		{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}.Debug|Win32.ActiveCfg = Debug|Win32
+		{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}.Debug|x64.ActiveCfg = Debug|x64
+		{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}.Release|Win32.ActiveCfg = Release|Win32
+		{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}.Release|x64.ActiveCfg = Release|x64
+		{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}.Debug|Win32.Build.0 = Debug|Win32
+		{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}.Debug|x64.Build.0 = Debug|x64
+		{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}.Release|Win32.Build.0 = Release|Win32
+		{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}.Release|x64.Build.0 = Release|x64
+		{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}.Debug-DLL|x64.Build.0 = Debug|x64
+		{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}.Release-DLL|Win32.Build.0 = Release|Win32
+		{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}.Release-DLL|x64.ActiveCfg = Release|x64
+		{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}.Release-DLL|x64.Build.0 = Release|x64
 		{0647D598-9611-F659-EA36-DF995C9F736B}.Debug|Win32.ActiveCfg = Debug|Win32
 		{0647D598-9611-F659-EA36-DF995C9F736B}.Debug|x64.ActiveCfg = Debug|x64
 		{0647D598-9611-F659-EA36-DF995C9F736B}.Release|Win32.ActiveCfg = Release|Win32
@@ -3451,6 +3562,22 @@ Global
 		{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
+		{68A54124-DFA3-4FF3-081F-70356222C977}.Debug|Win32.ActiveCfg = Debug|Win32
+		{68A54124-DFA3-4FF3-081F-70356222C977}.Debug|x64.ActiveCfg = Debug|x64
+		{68A54124-DFA3-4FF3-081F-70356222C977}.Release|Win32.ActiveCfg = Release|Win32
+		{68A54124-DFA3-4FF3-081F-70356222C977}.Release|x64.ActiveCfg = Release|x64
+		{68A54124-DFA3-4FF3-081F-70356222C977}.Debug|Win32.Build.0 = Debug|Win32
+		{68A54124-DFA3-4FF3-081F-70356222C977}.Debug|x64.Build.0 = Debug|x64
+		{68A54124-DFA3-4FF3-081F-70356222C977}.Release|Win32.Build.0 = Release|Win32
+		{68A54124-DFA3-4FF3-081F-70356222C977}.Release|x64.Build.0 = Release|x64
+		{68A54124-DFA3-4FF3-081F-70356222C977}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{68A54124-DFA3-4FF3-081F-70356222C977}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{68A54124-DFA3-4FF3-081F-70356222C977}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{68A54124-DFA3-4FF3-081F-70356222C977}.Debug-DLL|x64.Build.0 = Debug|x64
+		{68A54124-DFA3-4FF3-081F-70356222C977}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{68A54124-DFA3-4FF3-081F-70356222C977}.Release-DLL|Win32.Build.0 = Release|Win32
+		{68A54124-DFA3-4FF3-081F-70356222C977}.Release-DLL|x64.ActiveCfg = Release|x64
+		{68A54124-DFA3-4FF3-081F-70356222C977}.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
@@ -3515,6 +3642,22 @@ Global
 		{A66AC548-E2B9-74CD-293C-43526EE51DCE}.Release-DLL|Win32.Build.0 = Release|Win32
 		{A66AC548-E2B9-74CD-293C-43526EE51DCE}.Release-DLL|x64.ActiveCfg = Release|x64
 		{A66AC548-E2B9-74CD-293C-43526EE51DCE}.Release-DLL|x64.Build.0 = Release|x64
+		{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Debug|Win32.ActiveCfg = Debug|Win32
+		{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Debug|x64.ActiveCfg = Debug|x64
+		{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Release|Win32.ActiveCfg = Release|Win32
+		{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Release|x64.ActiveCfg = Release|x64
+		{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Debug|Win32.Build.0 = Debug|Win32
+		{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Debug|x64.Build.0 = Debug|x64
+		{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Release|Win32.Build.0 = Release|Win32
+		{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Release|x64.Build.0 = Release|x64
+		{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Debug-DLL|x64.Build.0 = Debug|x64
+		{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Release-DLL|Win32.Build.0 = Release|Win32
+		{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Release-DLL|x64.ActiveCfg = Release|x64
+		{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Release-DLL|x64.Build.0 = Release|x64
 		{CCFC6A58-623D-9013-BFEB-C809809E2429}.Debug|Win32.ActiveCfg = Debug|Win32
 		{CCFC6A58-623D-9013-BFEB-C809809E2429}.Debug|x64.ActiveCfg = Debug|x64
 		{CCFC6A58-623D-9013-BFEB-C809809E2429}.Release|Win32.ActiveCfg = Release|Win32
@@ -3659,22 +3802,6 @@ Global
 		{E765AC67-E4E5-C350-59A1-C6CA2BD9F64B}.Release-DLL|Win32.Build.0 = Release|Win32
 		{E765AC67-E4E5-C350-59A1-C6CA2BD9F64B}.Release-DLL|x64.ActiveCfg = Release|x64
 		{E765AC67-E4E5-C350-59A1-C6CA2BD9F64B}.Release-DLL|x64.Build.0 = Release|x64
-		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Debug|Win32.ActiveCfg = Debug|Win32
-		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Debug|x64.ActiveCfg = Debug|x64
-		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Release|Win32.ActiveCfg = Release|Win32
-		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Release|x64.ActiveCfg = Release|x64
-		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Debug|Win32.Build.0 = Debug|Win32
-		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Debug|x64.Build.0 = Debug|x64
-		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Release|Win32.Build.0 = Release|Win32
-		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Release|x64.Build.0 = Release|x64
-		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Debug-DLL|x64.Build.0 = Debug|x64
-		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Release-DLL|Win32.Build.0 = Release|Win32
-		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Release-DLL|x64.ActiveCfg = Release|x64
-		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Release-DLL|x64.Build.0 = Release|x64
 		{63422647-93FA-46BB-4827-95473D9D503C}.Debug|Win32.ActiveCfg = Debug|Win32
 		{63422647-93FA-46BB-4827-95473D9D503C}.Debug|x64.ActiveCfg = Debug|x64
 		{63422647-93FA-46BB-4827-95473D9D503C}.Release|Win32.ActiveCfg = Release|Win32
@@ -3707,6 +3834,22 @@ Global
 		{F0FA4A41-5695-580A-DCDA-EC719CB041B0}.Release-DLL|Win32.Build.0 = Release|Win32
 		{F0FA4A41-5695-580A-DCDA-EC719CB041B0}.Release-DLL|x64.ActiveCfg = Release|x64
 		{F0FA4A41-5695-580A-DCDA-EC719CB041B0}.Release-DLL|x64.Build.0 = Release|x64
+		{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Debug|x64.ActiveCfg = Debug|x64
+		{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Release|Win32.ActiveCfg = Release|Win32
+		{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Release|x64.ActiveCfg = Release|x64
+		{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Debug|Win32.Build.0 = Debug|Win32
+		{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Debug|x64.Build.0 = Debug|x64
+		{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Release|Win32.Build.0 = Release|Win32
+		{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Release|x64.Build.0 = Release|x64
+		{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Debug-DLL|x64.Build.0 = Debug|x64
+		{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Release-DLL|Win32.Build.0 = Release|Win32
+		{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Release-DLL|x64.ActiveCfg = Release|x64
+		{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Release-DLL|x64.Build.0 = Release|x64
 		{419167BB-C3F5-DDEA-403A-394D1902DE65}.Debug|Win32.ActiveCfg = Debug|Win32
 		{419167BB-C3F5-DDEA-403A-394D1902DE65}.Debug|x64.ActiveCfg = Debug|x64
 		{419167BB-C3F5-DDEA-403A-394D1902DE65}.Release|Win32.ActiveCfg = Release|Win32
@@ -3787,6 +3930,22 @@ Global
 		{21E2A241-9D48-02CD-92E4-4EEC98424CF5}.Release-DLL|Win32.Build.0 = Release|Win32
 		{21E2A241-9D48-02CD-92E4-4EEC98424CF5}.Release-DLL|x64.ActiveCfg = Release|x64
 		{21E2A241-9D48-02CD-92E4-4EEC98424CF5}.Release-DLL|x64.Build.0 = Release|x64
+		{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Debug|x64.ActiveCfg = Debug|x64
+		{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Release|Win32.ActiveCfg = Release|Win32
+		{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Release|x64.ActiveCfg = Release|x64
+		{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Debug|Win32.Build.0 = Debug|Win32
+		{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Debug|x64.Build.0 = Debug|x64
+		{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Release|Win32.Build.0 = Release|Win32
+		{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Release|x64.Build.0 = Release|x64
+		{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Debug-DLL|x64.Build.0 = Debug|x64
+		{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Release-DLL|Win32.Build.0 = Release|Win32
+		{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Release-DLL|x64.ActiveCfg = Release|x64
+		{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Release-DLL|x64.Build.0 = Release|x64
 		{9814D850-F3BB-8C7A-4C78-2751C1E272F4}.Debug|Win32.ActiveCfg = Debug|Win32
 		{9814D850-F3BB-8C7A-4C78-2751C1E272F4}.Debug|x64.ActiveCfg = Debug|x64
 		{9814D850-F3BB-8C7A-4C78-2751C1E272F4}.Release|Win32.ActiveCfg = Release|Win32
diff --git a/vsprojects/grpc.sln b/vsprojects/grpc.sln
index 591d3b5edb244fd4c4676415d74bd2348ead6b43..97378e0a0f85984fc6f4a02fd91f4cbac3e5bc86 100644
--- a/vsprojects/grpc.sln
+++ b/vsprojects/grpc.sln
@@ -3,6 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 2013
 VisualStudioVersion = 12.0.21005.1
 MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "vcxproj\.\ares\ares.vcxproj", "{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gen_hpack_tables", "vcxproj\.\gen_hpack_tables\gen_hpack_tables.vcxproj", "{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -49,6 +54,15 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++", "vcxproj\.\grpc++\
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++_error_details", "vcxproj\.\grpc++_error_details\grpc++_error_details.vcxproj", "{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB} = {C187A093-A0FE-489D-A40A-6E33DE0F9FEB}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++_unsecure", "vcxproj\.\grpc++_unsecure\grpc++_unsecure.vcxproj", "{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}"
@@ -160,6 +174,22 @@ Global
 		Release-DLL|x64 = Release-DLL|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}.Debug|x64.ActiveCfg = Debug|x64
+		{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}.Release|Win32.ActiveCfg = Release|Win32
+		{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}.Release|x64.ActiveCfg = Release|x64
+		{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}.Debug|Win32.Build.0 = Debug|Win32
+		{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}.Debug|x64.Build.0 = Debug|x64
+		{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}.Release|Win32.Build.0 = Release|Win32
+		{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}.Release|x64.Build.0 = Release|x64
+		{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}.Debug-DLL|x64.Build.0 = Debug|x64
+		{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}.Release-DLL|Win32.Build.0 = Release|Win32
+		{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}.Release-DLL|x64.ActiveCfg = Release|x64
+		{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}.Release-DLL|x64.Build.0 = Release|x64
 		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug|Win32.ActiveCfg = Debug|Win32
 		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug|x64.ActiveCfg = Debug|x64
 		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release|Win32.ActiveCfg = Release|Win32
@@ -272,6 +302,22 @@ Global
 		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|Win32.Build.0 = Release-DLL|Win32
 		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|x64.ActiveCfg = Release-DLL|x64
 		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|x64.Build.0 = Release-DLL|x64
+		{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Debug|x64.ActiveCfg = Debug|x64
+		{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Release|Win32.ActiveCfg = Release|Win32
+		{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Release|x64.ActiveCfg = Release|x64
+		{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Debug|Win32.Build.0 = Debug|Win32
+		{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Debug|x64.Build.0 = Debug|x64
+		{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Release|Win32.Build.0 = Release|Win32
+		{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Release|x64.Build.0 = Release|x64
+		{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Debug-DLL|x64.Build.0 = Debug|x64
+		{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Release-DLL|Win32.Build.0 = Release|Win32
+		{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Release-DLL|x64.ActiveCfg = Release|x64
+		{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Release-DLL|x64.Build.0 = Release|x64
 		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug|Win32.ActiveCfg = Debug|Win32
 		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug|x64.ActiveCfg = Debug|x64
 		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release|Win32.ActiveCfg = Release|Win32
diff --git a/vsprojects/vcxproj/ares/ares.vcxproj b/vsprojects/vcxproj/ares/ares.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..811f7c72c3e0461c085e361e9ddd82438c857cd3
--- /dev/null
+++ b/vsprojects/vcxproj/ares/ares.vcxproj
@@ -0,0 +1,284 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <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>{1769D06D-F18C-B4C2-B019-31D7F83F3C9A}</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>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</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\winsock.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>ares</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>ares</TargetName>
+  </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>Windows</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>Windows</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>Windows</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>Windows</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_data.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_dns.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_getenv.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_getopt.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_inet_net_pton.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_iphlpapi.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_ipv6.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_library_init.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_llist.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_nowarn.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_platform.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_private.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_rules.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_setup.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_strcasecmp.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_strdup.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_version.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\bitncmp.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\config-win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\setup_once.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\ares_build.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\config_linux\ares_config.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\config_darwin\ares_config.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares__close_sockets.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares__get_hostent.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares__read_line.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares__timeval.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_cancel.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_create_query.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_data.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_destroy.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_expand_name.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_expand_string.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_fds.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_free_hostent.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_free_string.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_getenv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_gethostbyaddr.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_gethostbyname.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_getnameinfo.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_getopt.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_getsock.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_init.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_library_init.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_llist.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_mkquery.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_nowarn.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_options.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_a_reply.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_aaaa_reply.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_mx_reply.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_naptr_reply.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_ns_reply.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_ptr_reply.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_soa_reply.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_srv_reply.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_txt_reply.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_platform.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_process.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_query.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_search.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_send.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_strcasecmp.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_strdup.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_strerror.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_timeout.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_version.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_writev.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\bitncmp.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\inet_net_pton.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\inet_ntop.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\windows_port.c">
+    </ClCompile>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </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>
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/ares/ares.vcxproj.filters b/vsprojects/vcxproj/ares/ares.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..282a404868b6488dfdaecc7327bc0ae3a1e9e080
--- /dev/null
+++ b/vsprojects/vcxproj/ares/ares.vcxproj.filters
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares__close_sockets.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares__get_hostent.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares__read_line.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares__timeval.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_cancel.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_create_query.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_data.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_destroy.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_expand_name.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_expand_string.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_fds.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_free_hostent.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_free_string.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_getenv.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_gethostbyaddr.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_gethostbyname.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_getnameinfo.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_getopt.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_getsock.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_init.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_library_init.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_llist.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_mkquery.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_nowarn.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_options.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_a_reply.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_aaaa_reply.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_mx_reply.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_naptr_reply.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_ns_reply.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_ptr_reply.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_soa_reply.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_srv_reply.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_parse_txt_reply.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_platform.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_process.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_query.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_search.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_send.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_strcasecmp.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_strdup.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_strerror.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_timeout.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_version.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\ares_writev.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\bitncmp.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\inet_net_pton.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\inet_ntop.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\cares\cares\windows_port.c">
+      <Filter>third_party\cares\cares</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_data.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_dns.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_getenv.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_getopt.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_inet_net_pton.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_iphlpapi.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_ipv6.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_library_init.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_llist.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_nowarn.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_platform.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_private.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_rules.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_setup.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_strcasecmp.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_strdup.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\ares_version.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\bitncmp.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\config-win32.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\cares\setup_once.h">
+      <Filter>third_party\cares\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\ares_build.h">
+      <Filter>third_party\cares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\config_linux\ares_config.h">
+      <Filter>third_party\cares\config_linux</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\cares\config_darwin\ares_config.h">
+      <Filter>third_party\cares\config_darwin</Filter>
+    </ClInclude>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="third_party">
+      <UniqueIdentifier>{6463a17d-379b-4a21-51a9-c729ed28c9c1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\cares">
+      <UniqueIdentifier>{f5276ab6-c78a-eea3-7ce9-54d2081b3d6a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\cares\cares">
+      <UniqueIdentifier>{390f10a8-7730-6295-681d-6fbd990ad488}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\cares\config_darwin">
+      <UniqueIdentifier>{02918eea-69d3-f65c-08aa-6c6c3dd50c7a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\cares\config_linux">
+      <UniqueIdentifier>{8b1c2965-c2f3-d13b-2c35-9e2c298acda5}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj b/vsprojects/vcxproj/gpr/gpr.vcxproj
index 44c21ddeb318106e03277fe68b027130afb6c458..7fb81a7fbcaab8c684f884abff5a8d18df8f5aa5 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj
@@ -180,7 +180,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
@@ -188,9 +187,14 @@
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\profiling\timers.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\arena.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\atomic.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\atomic_with_atm.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\atomic_with_std.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\backoff.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\block_annotate.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\env.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\memory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\mpscq.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\murmur_hash.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\spinlock.h" />
@@ -208,6 +212,10 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\alloc.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\arena.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\atm.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\avl.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\backoff.c">
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
index a5924a624a8a9e6541f93dfcfe502eb91bea918b..27d9d2f38f41be0e34d7614de2ec7a215a44c47c 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
@@ -10,6 +10,12 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\alloc.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\arena.c">
+      <Filter>src\core\lib\support</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\atm.c">
+      <Filter>src\core\lib\support</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\avl.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
@@ -234,9 +240,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -254,6 +257,18 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\profiling\timers.h">
       <Filter>src\core\lib\profiling</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\arena.h">
+      <Filter>src\core\lib\support</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\atomic.h">
+      <Filter>src\core\lib\support</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\atomic_with_atm.h">
+      <Filter>src\core\lib\support</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\atomic_with_std.h">
+      <Filter>src\core\lib\support</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\backoff.h">
       <Filter>src\core\lib\support</Filter>
     </ClInclude>
@@ -263,6 +278,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\env.h">
       <Filter>src\core\lib\support</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\memory.h">
+      <Filter>src\core\lib\support</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\mpscq.h">
       <Filter>src\core\lib\support</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index 45f3037e8ab88ddebc63c70049eb7812549fce96..32d2e09a588e90c45cc377a2ac902222c0dbde21 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -270,6 +270,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\grpc++.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\health_check_service_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\channel_argument_option.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h" />
@@ -327,7 +328,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_helper.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\stub_options.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h" />
@@ -338,6 +338,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
@@ -346,11 +347,20 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer_reader.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\compression.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\load_reporting.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\slice.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\slice_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
   </ItemGroup>
@@ -366,6 +376,116 @@
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\health\health.pb.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\thread_pool_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\thread_manager\thread_manager.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\format_request.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\httpcli.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\parser.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\closure.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\combiner.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\error.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\error_internal.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_epoll_linux.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_internal.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_uv.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\port.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\resource_quota.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_uv.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_generic.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_cv.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_pipe.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_uv.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_common.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\b64.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call_test_only.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\event_string.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\init.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\server.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\validate_metadata.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\bdp_estimator.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\error_utils.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\http2_errors.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\service_config.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\status_conversion.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport_impl.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\cpp\client\insecure_credentials.cc">
@@ -414,6 +534,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\async_generic_service.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\channel_argument_option.cc">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\create_default_thread_pool.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.cc">
@@ -448,6 +570,252 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time_cc.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\debug\trace.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\format_request.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\httpcli.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\parser.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\closure.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\combiner.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\error.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_epoll_linux.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resource_quota.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_linux.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_common.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_ifaddrs.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_noifaddrs.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_generic.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix_noop.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_cv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_eventfd.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_nospecial.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_pipe.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_reader.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_string.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\b64.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_buffer.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_intern.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\alarm.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\byte_buffer.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\byte_buffer_reader.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call_details.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call_log_batch.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_ping.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\event_string.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\metadata_array.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\server.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\validate_metadata.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\version.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\bdp_estimator.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\error_utils.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\service_config.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\status_conversion.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\transport.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\transport_op_string.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>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
     </ClCompile>
   </ItemGroup>
@@ -455,6 +823,9 @@
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
       <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
     </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index 95cdb7434c157f2c3bc6cd78fdccd05047cd4625..a3346bc29795ffe2ef945823aa86e1acae1aa14e 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -70,6 +70,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\async_generic_service.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\channel_argument_option.cc">
+      <Filter>src\cpp\server</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\create_default_thread_pool.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
@@ -121,6 +124,375 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time_cc.cc">
       <Filter>src\cpp\util</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
+      <Filter>src\core\lib\compression</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
+      <Filter>src\core\lib\compression</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\debug\trace.c">
+      <Filter>src\core\lib\debug</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\format_request.c">
+      <Filter>src\core\lib\http</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\httpcli.c">
+      <Filter>src\core\lib\http</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\parser.c">
+      <Filter>src\core\lib\http</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\closure.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\combiner.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\error.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_epoll_linux.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resource_quota.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_linux.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_common.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_ifaddrs.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_noifaddrs.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_generic.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix_noop.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_cv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_eventfd.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_nospecial.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_pipe.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json.c">
+      <Filter>src\core\lib\json</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_reader.c">
+      <Filter>src\core\lib\json</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_string.c">
+      <Filter>src\core\lib\json</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c">
+      <Filter>src\core\lib\json</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\b64.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_buffer.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_intern.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\alarm.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\byte_buffer.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\byte_buffer_reader.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call_details.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call_log_batch.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_ping.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\event_string.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.cc">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\metadata_array.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\server.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\validate_metadata.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\version.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\bdp_estimator.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\error_utils.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\service_config.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\status_conversion.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\transport.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\transport_op_string.c">
+      <Filter>src\core\lib\transport</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>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
       <Filter>src\cpp\codegen</Filter>
     </ClCompile>
@@ -162,6 +534,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\channel_argument_option.h">
+      <Filter>include\grpc++\impl</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
@@ -333,9 +708,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_helper.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -366,6 +738,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -390,9 +765,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -405,6 +777,36 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer_reader.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\compression.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\load_reporting.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\slice.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\slice_buffer.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -446,6 +848,336 @@
     <ClInclude Include="$(SolutionDir)\..\src\cpp\thread_manager\thread_manager.h">
       <Filter>src\cpp\thread_manager</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h">
+      <Filter>src\core\lib\compression</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h">
+      <Filter>src\core\lib\compression</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h">
+      <Filter>src\core\lib\debug</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\format_request.h">
+      <Filter>src\core\lib\http</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\httpcli.h">
+      <Filter>src\core\lib\http</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\parser.h">
+      <Filter>src\core\lib\http</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\closure.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\combiner.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\error.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\error_internal.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_epoll_linux.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_internal.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_uv.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\port.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\resource_quota.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_uv.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_generic.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_cv.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_pipe.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_uv.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json.h">
+      <Filter>src\core\lib\json</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_common.h">
+      <Filter>src\core\lib\json</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h">
+      <Filter>src\core\lib\json</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h">
+      <Filter>src\core\lib\json</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\b64.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call_test_only.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\event_string.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\init.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\server.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\validate_metadata.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\bdp_estimator.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\error_utils.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\http2_errors.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\service_config.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\status_conversion.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport_impl.h">
+      <Filter>src\core\lib\transport</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>
@@ -488,6 +1220,39 @@
     <Filter Include="src">
       <UniqueIdentifier>{328ff211-2886-406e-56f9-18ba1686f363}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\core">
+      <UniqueIdentifier>{d02f1155-7e7e-3736-3c69-dc9146dc523d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib">
+      <UniqueIdentifier>{80567a8f-622f-a3ce-c12d-aebb63984b07}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\channel">
+      <UniqueIdentifier>{e769265c-8abd-cd64-2cc2-a52da484fe7b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\compression">
+      <UniqueIdentifier>{701b2d46-11c6-3640-b189-45287f00bee3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\debug">
+      <UniqueIdentifier>{ada68fd5-8e51-98cb-71a7-baf7989d8ffa}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\http">
+      <UniqueIdentifier>{e770844e-61d4-555e-59be-81288e21a35f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\iomgr">
+      <UniqueIdentifier>{04dfa1c8-7ffe-4f06-4a7c-37441dc75764}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\json">
+      <UniqueIdentifier>{a5d5bddf-6f19-b655-a03a-f30ff5c253a5}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\slice">
+      <UniqueIdentifier>{afe126ba-52c9-1daa-d174-8ee8aade08c2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\surface">
+      <UniqueIdentifier>{fb2276d7-5a11-f1d9-82c3-e7c7f1155523}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\transport">
+      <UniqueIdentifier>{4bd7971a-68f7-0d5a-f502-6dea3099caaa}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\cpp">
       <UniqueIdentifier>{2420a905-e4f1-a5aa-a364-6a112878a39e}</UniqueIdentifier>
     </Filter>
@@ -512,6 +1277,12 @@
     <Filter Include="src\cpp\util">
       <UniqueIdentifier>{f842537a-2bf1-1ec3-b495-7d62c64a1c06}</UniqueIdentifier>
     </Filter>
+    <Filter Include="third_party">
+      <UniqueIdentifier>{0cfc99f5-c633-356e-6810-754c93b15658}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\nanopb">
+      <UniqueIdentifier>{abc9bbec-57f7-141f-8616-e2d3aa8b2e6d}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
 </Project>
 
diff --git a/vsprojects/vcxproj/grpc++_error_details/grpc++_error_details.vcxproj b/vsprojects/vcxproj/grpc++_error_details/grpc++_error_details.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..6bb3d4783a6e67b41b1bca5d8b54607511e5c1ef
--- /dev/null
+++ b/vsprojects/vcxproj/grpc++_error_details/grpc++_error_details.vcxproj
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <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>{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}</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>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</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\winsock.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>grpc++_error_details</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>grpc++_error_details</TargetName>
+  </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>Windows</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>Windows</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>Windows</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>Windows</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\error_details.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\status\status.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\status\status.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\status\status.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\status\status.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\error_details.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
+      <Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </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>
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/grpc++_error_details/grpc++_error_details.vcxproj.filters b/vsprojects/vcxproj/grpc++_error_details/grpc++_error_details.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..e1814eeceac6e421e49bbb030ee5f4fd6c7cf470
--- /dev/null
+++ b/vsprojects/vcxproj/grpc++_error_details/grpc++_error_details.vcxproj.filters
@@ -0,0 +1,47 @@
+<?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\status\status.proto">
+      <Filter>src\proto\grpc\status</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\error_details.cc">
+      <Filter>src\cpp\util</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\error_details.h">
+      <Filter>include\grpc++\support</Filter>
+    </ClInclude>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="include">
+      <UniqueIdentifier>{013272b5-4742-ba38-7cb6-25ff3484ac1d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++">
+      <UniqueIdentifier>{f589296d-1ee4-913f-0345-7d8bf51f657b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++\support">
+      <UniqueIdentifier>{3455fa30-ad44-8790-9dc2-ff4ac7dd9e6c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src">
+      <UniqueIdentifier>{cf07aafe-1d45-af88-81fb-0bbd5afd247f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\cpp">
+      <UniqueIdentifier>{00726556-da02-06d8-bb32-902f55133c6b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\cpp\util">
+      <UniqueIdentifier>{fd90d13e-cc1f-e8cc-56ee-650231b08f56}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto">
+      <UniqueIdentifier>{ec6be373-4683-335e-03d9-dc636e34d7ef}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc">
+      <UniqueIdentifier>{8200edf2-9498-6cd9-d8f3-81ad881ca82c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc\status">
+      <UniqueIdentifier>{79c5c1ea-19a8-bf5a-5e0a-3de6ad3a0465}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
index 13d80ec4dad1e28b08aa0cd0277dd45583afb629..49582188216f008d1cd847f56496c038ee3fd4f5 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
@@ -172,7 +172,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_helper.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\stub_options.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h" />
@@ -183,6 +182,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
@@ -191,15 +191,12 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\thrift_serializer.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\thrift_utils.h" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\test\cpp\end2end\test_service_impl.h" />
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 7981feb4de9b7400865770ddc07c25eff7189219..1e2a2eb97c123e08d301e12118b42433ea18bdec 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
@@ -111,9 +111,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_helper.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -144,6 +141,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -168,9 +168,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -189,12 +186,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\thrift_serializer.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\thrift_utils.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\test\cpp\end2end\test_service_impl.h">
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index 22ea361a02e7e5875c8cbd07521840c50945b5da..28ccefc651c817bedd83e604ad0492dbd73f5111 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -270,6 +270,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\grpc++.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\health_check_service_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\channel_argument_option.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h" />
@@ -327,7 +328,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_helper.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\stub_options.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h" />
@@ -338,6 +338,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
@@ -346,11 +347,20 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer_reader.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\compression.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\load_reporting.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\slice.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\slice_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h" />
@@ -360,6 +370,116 @@
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\health\health.pb.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\thread_pool_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\thread_manager\thread_manager.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\format_request.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\httpcli.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\parser.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\closure.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\combiner.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\error.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\error_internal.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_epoll_linux.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_internal.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_uv.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\port.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\resource_quota.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_uv.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_generic.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_cv.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_pipe.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_uv.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_common.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\b64.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call_test_only.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\event_string.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\init.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\server.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\validate_metadata.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\bdp_estimator.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\error_utils.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\http2_errors.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\service_config.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\status_conversion.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport_impl.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\cpp\client\insecure_credentials.cc">
@@ -398,6 +518,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\async_generic_service.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\channel_argument_option.cc">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\create_default_thread_pool.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.cc">
@@ -432,6 +554,252 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time_cc.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\debug\trace.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\format_request.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\httpcli.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\parser.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\closure.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\combiner.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\error.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_epoll_linux.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resource_quota.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_linux.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_common.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_ifaddrs.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_noifaddrs.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_generic.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix_noop.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_cv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_eventfd.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_nospecial.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_pipe.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_uv.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_reader.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_string.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\b64.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_buffer.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_intern.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\alarm.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\byte_buffer.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\byte_buffer_reader.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call_details.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call_log_batch.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_ping.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\event_string.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\metadata_array.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\server.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\validate_metadata.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\version.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\bdp_estimator.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\error_utils.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\service_config.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\status_conversion.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\transport.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\transport_op_string.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>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
     </ClCompile>
   </ItemGroup>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index c3cef2d4df50935e4171ae84b6d52580207a2ac0..83f869dab36bcdc1f0b2e662ef5bff2028ddffee 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -55,6 +55,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\async_generic_service.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\channel_argument_option.cc">
+      <Filter>src\cpp\server</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\create_default_thread_pool.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
@@ -106,6 +109,375 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time_cc.cc">
       <Filter>src\cpp\util</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
+      <Filter>src\core\lib\compression</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
+      <Filter>src\core\lib\compression</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\debug\trace.c">
+      <Filter>src\core\lib\debug</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\format_request.c">
+      <Filter>src\core\lib\http</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\httpcli.c">
+      <Filter>src\core\lib\http</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\parser.c">
+      <Filter>src\core\lib\http</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\closure.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\combiner.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\error.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_epoll_linux.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resource_quota.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_linux.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_common.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_ifaddrs.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_noifaddrs.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_generic.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix_noop.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_cv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_eventfd.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_nospecial.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_pipe.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_uv.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json.c">
+      <Filter>src\core\lib\json</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_reader.c">
+      <Filter>src\core\lib\json</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_string.c">
+      <Filter>src\core\lib\json</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c">
+      <Filter>src\core\lib\json</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\b64.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_buffer.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_intern.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\alarm.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\byte_buffer.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\byte_buffer_reader.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call_details.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call_log_batch.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_ping.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\event_string.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.cc">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\metadata_array.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\server.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\validate_metadata.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\version.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\bdp_estimator.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\error_utils.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\service_config.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\status_conversion.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\transport.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\transport_op_string.c">
+      <Filter>src\core\lib\transport</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>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
       <Filter>src\cpp\codegen</Filter>
     </ClCompile>
@@ -147,6 +519,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\channel_argument_option.h">
+      <Filter>include\grpc++\impl</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
@@ -318,9 +693,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_helper.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -351,6 +723,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -375,9 +750,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -390,6 +762,36 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer_reader.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\compression.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\load_reporting.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\slice.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\slice_buffer.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h">
@@ -413,6 +815,336 @@
     <ClInclude Include="$(SolutionDir)\..\src\cpp\thread_manager\thread_manager.h">
       <Filter>src\cpp\thread_manager</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h">
+      <Filter>src\core\lib\compression</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h">
+      <Filter>src\core\lib\compression</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h">
+      <Filter>src\core\lib\debug</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\format_request.h">
+      <Filter>src\core\lib\http</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\httpcli.h">
+      <Filter>src\core\lib\http</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\parser.h">
+      <Filter>src\core\lib\http</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\closure.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\combiner.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\error.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\error_internal.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_epoll_linux.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_internal.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_uv.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\port.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\resource_quota.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_uv.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_generic.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_cv.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_pipe.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_uv.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json.h">
+      <Filter>src\core\lib\json</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_common.h">
+      <Filter>src\core\lib\json</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h">
+      <Filter>src\core\lib\json</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h">
+      <Filter>src\core\lib\json</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\b64.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call_test_only.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\event_string.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\init.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\server.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\validate_metadata.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\bdp_estimator.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\error_utils.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\http2_errors.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\service_config.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\status_conversion.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport_impl.h">
+      <Filter>src\core\lib\transport</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>
@@ -455,6 +1187,39 @@
     <Filter Include="src">
       <UniqueIdentifier>{cce6a85d-1111-3834-6825-31e170d93cff}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\core">
+      <UniqueIdentifier>{595f2ea0-aafb-87e5-c938-db3ff0b0c69a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib">
+      <UniqueIdentifier>{cf8fd5d8-ff54-331d-2d20-36d6cae0e14b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\channel">
+      <UniqueIdentifier>{7e0225af-000b-4873-1c16-caffffbfd084}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\compression">
+      <UniqueIdentifier>{0bbdbf56-83ad-bb4b-c4e2-a6d38c342179}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\debug">
+      <UniqueIdentifier>{3875f7d7-ff11-c91d-0f98-810260cb554b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\http">
+      <UniqueIdentifier>{4bd405b9-af65-f0a6-d67a-433f75900668}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\iomgr">
+      <UniqueIdentifier>{f4b146e4-8fba-83a6-1cc1-1262ebb785e8}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\json">
+      <UniqueIdentifier>{b83c8e70-e491-f6f9-a08c-85f632bb61d2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\slice">
+      <UniqueIdentifier>{0d6d88e2-8549-5118-8b78-06e8283dadcb}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\surface">
+      <UniqueIdentifier>{1d59dcef-3358-d0ab-fa42-64da74065785}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\transport">
+      <UniqueIdentifier>{ba865739-5dd9-6731-6772-48c25d45134f}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\cpp">
       <UniqueIdentifier>{1e5fd68c-bd87-e803-42b0-75a7fa19b91d}</UniqueIdentifier>
     </Filter>
@@ -479,6 +1244,12 @@
     <Filter Include="src\cpp\util">
       <UniqueIdentifier>{fb5d9a64-20ca-5119-ed38-04a3cf94923d}</UniqueIdentifier>
     </Filter>
+    <Filter Include="third_party">
+      <UniqueIdentifier>{e911fd76-1313-5d02-3983-cdd0bafe1c6a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\nanopb">
+      <UniqueIdentifier>{1ff41e28-caf4-c4b9-0170-53d36c7dac29}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
 </Project>
 
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index fde60be3e208b4c7725e3f7d536c650519b4c59b..86b5856d68a831ffd4714de7ccc23d58be8d71ee 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -283,6 +283,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
@@ -291,7 +292,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
@@ -303,16 +303,11 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\deadline_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h" />
@@ -335,6 +330,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset.h" />
@@ -349,6 +345,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.h" />
@@ -357,6 +354,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_uv.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.h" />
@@ -376,6 +374,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_common.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\b64.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h" />
@@ -387,6 +386,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\event_string.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\init.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.h" />
@@ -419,12 +419,16 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\hpack_encoder.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\hpack_parser.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\hpack_table.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\http2_settings.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\huffsyms.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\incoming_metadata.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\stream_map.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\varint.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\alpn\alpn.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\http\client\http_client_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\http\message_compress\message_compress_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\http\server\http_server_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\context\security_context.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\credentials\composite\composite_credentials.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\credentials\credentials.h" />
@@ -443,43 +447,48 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\security_connector.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\security_handshaker.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\tsi_error.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\util\b64.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\util\json_util.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\tsi\fake_transport_security.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\tsi\ssl_transport_security.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\tsi\ssl_types.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\tsi\transport_security.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\tsi\transport_security_interface.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_adapter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\transport_security_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\chttp2_server.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel_factory.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\connector.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\http_connect_handshaker.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\http_proxy.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\initial_connect_string.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_factory.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\proxy_mapper.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\proxy_mapper_registry.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_factory.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_registry.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel_index.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\uri_parser.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel_factory.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\connector.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\http_connect_handshaker.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\http_proxy.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy_factory.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy_registry.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\parse_address.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\proxy_mapper.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\proxy_mapper_registry.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver_factory.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver_registry.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\retry_throttle.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\subchannel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\subchannel_index.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\uri_parser.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\deadline\deadline_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\chttp2_connector.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb_channel.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\client_load_reporting_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb_channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb_client_stats.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\load_balancer_api.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.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" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_ev_driver.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\load_reporting\load_reporting.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\load_reporting\load_reporting_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\aggregation.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\base_resources.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\census_interface.h" />
@@ -496,6 +505,8 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\trace_status.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\trace_string.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\tracing.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\max_age\max_age_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\message_size\message_size_filter.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\init.c">
@@ -506,24 +517,14 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\deadline_filter.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
@@ -572,6 +573,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.c">
@@ -594,6 +597,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
@@ -618,6 +623,12 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_posix.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_common.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_ifaddrs.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_noifaddrs.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_uv.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_windows.c">
@@ -662,6 +673,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\b64.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice.c">
@@ -698,9 +711,11 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\event_string.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\metadata_array.c">
     </ClCompile>
@@ -764,6 +779,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\hpack_table.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\http2_settings.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\huffsyms.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\incoming_metadata.c">
@@ -780,6 +797,14 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\alpn\alpn.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\http\client\http_client_filter.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\http\http_filters_plugin.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\http\message_compress\message_compress_filter.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\http\server\http_server_filter.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\httpcli_security_connector.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\context\security_context.c">
@@ -824,63 +849,63 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\tsi_error.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\b64.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\json_util.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\init_secure.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\tsi\fake_transport_security.c">
+    <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\lib\tsi\ssl_transport_security.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\transport_security.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\tsi\transport_security.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\transport_security_adapter.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\chttp2_server.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\secure\secure_channel_create.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\channel_connectivity.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\channel_connectivity.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel_factory.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel_factory.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel_plugin.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel_plugin.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\connector.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\connector.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\default_initial_connect_string.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\http_connect_handshaker.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\http_connect_handshaker.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\http_proxy.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\http_proxy.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\initial_connect_string.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy_factory.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy_registry.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_factory.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\parse_address.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\proxy_mapper.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\proxy_mapper_registry.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\proxy_mapper.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\proxy_mapper_registry.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver_factory.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver_registry.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_factory.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\retry_throttle.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_registry.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\subchannel.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\subchannel_index.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel_index.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\uri_parser.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\uri_parser.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\deadline\deadline_filter.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\chttp2_connector.c">
     </ClCompile>
@@ -892,13 +917,17 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create_posix.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\client_load_reporting_filter.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb_channel_secure.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb_channel_secure.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb_client_stats.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\load_balancer_api.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_common.c">
     </ClCompile>
@@ -906,17 +935,23 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\pick_first\pick_first.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\pick_first\pick_first.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\round_robin\round_robin.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\dns_resolver_ares.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\round_robin\round_robin.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_ev_driver_posix.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\native\dns_resolver.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\sockaddr\sockaddr_resolver.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\native\dns_resolver.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\sockaddr\sockaddr_resolver.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\load_reporting\load_reporting.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\load_reporting\load_reporting_filter.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\base_resources.c">
     </ClCompile>
@@ -946,6 +981,10 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\tracing.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\max_age\max_age_filter.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\message_size\message_size_filter.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\plugin_registry\grpc_plugin_registry.c">
     </ClCompile>
   </ItemGroup>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index 8edbbc22bedc4340c3dd397a9ff27c9df1cc31b2..943ad521f755d7feadea2b4d4f6c360b90f420b1 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -13,15 +13,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\deadline_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
@@ -31,15 +25,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
       <Filter>src\core\lib\compression</Filter>
     </ClCompile>
@@ -112,6 +97,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -145,6 +133,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -181,6 +172,15 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_posix.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_common.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_ifaddrs.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_noifaddrs.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_uv.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -247,6 +247,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c">
       <Filter>src\core\lib\json</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\b64.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.c">
       <Filter>src\core\lib\slice</Filter>
     </ClCompile>
@@ -301,10 +304,13 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.c">
       <Filter>src\core\lib\surface</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\event_string.c">
       <Filter>src\core\lib\surface</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.cc">
       <Filter>src\core\lib\surface</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\metadata_array.c">
@@ -400,6 +406,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\hpack_table.c">
       <Filter>src\core\ext\transport\chttp2\transport</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\http2_settings.c">
+      <Filter>src\core\ext\transport\chttp2\transport</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\huffsyms.c">
       <Filter>src\core\ext\transport\chttp2\transport</Filter>
     </ClCompile>
@@ -424,6 +433,18 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\alpn\alpn.c">
       <Filter>src\core\ext\transport\chttp2\alpn</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\http\client\http_client_filter.c">
+      <Filter>src\core\ext\filters\http\client</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\http\http_filters_plugin.c">
+      <Filter>src\core\ext\filters\http</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\http\message_compress\message_compress_filter.c">
+      <Filter>src\core\ext\filters\http\message_compress</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\http\server\http_server_filter.c">
+      <Filter>src\core\ext\filters\http\server</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\httpcli_security_connector.c">
       <Filter>src\core\lib\http</Filter>
     </ClCompile>
@@ -490,23 +511,23 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\tsi_error.c">
       <Filter>src\core\lib\security\transport</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\b64.c">
-      <Filter>src\core\lib\security\util</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\json_util.c">
       <Filter>src\core\lib\security\util</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\init_secure.c">
       <Filter>src\core\lib\surface</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\tsi\fake_transport_security.c">
-      <Filter>src\core\lib\tsi</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\fake_transport_security.c">
+      <Filter>src\core\tsi</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\tsi\ssl_transport_security.c">
-      <Filter>src\core\lib\tsi</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\ssl_transport_security.c">
+      <Filter>src\core\tsi</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\tsi\transport_security.c">
-      <Filter>src\core\lib\tsi</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\transport_security.c">
+      <Filter>src\core\tsi</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\transport_security_adapter.c">
+      <Filter>src\core\tsi</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\chttp2_server.c">
       <Filter>src\core\ext\transport\chttp2\server</Filter>
@@ -514,68 +535,68 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\secure\secure_channel_create.c">
       <Filter>src\core\ext\transport\chttp2\client\secure</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\channel_connectivity.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\channel_connectivity.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel_factory.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel_factory.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel_plugin.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel_plugin.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\connector.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\connector.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\default_initial_connect_string.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\http_connect_handshaker.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\http_connect_handshaker.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\http_proxy.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\http_proxy.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\initial_connect_string.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy_factory.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy_registry.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_factory.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\parse_address.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\proxy_mapper.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\proxy_mapper_registry.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\proxy_mapper.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\proxy_mapper_registry.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver_factory.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver_registry.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_factory.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\retry_throttle.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_registry.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\subchannel.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\subchannel_index.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel_index.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\uri_parser.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\uri_parser.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\deadline\deadline_filter.c">
+      <Filter>src\core\ext\filters\deadline</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\chttp2_connector.c">
       <Filter>src\core\ext\transport\chttp2\client</Filter>
@@ -592,17 +613,23 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create_posix.c">
       <Filter>src\core\ext\transport\chttp2\client\insecure</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb.c">
-      <Filter>src\core\ext\lb_policy\grpclb</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\client_load_reporting_filter.c">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb.c">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb_channel_secure.c">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb_channel_secure.c">
-      <Filter>src\core\ext\lb_policy\grpclb</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb_client_stats.c">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.c">
-      <Filter>src\core\ext\lb_policy\grpclb</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\load_balancer_api.c">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.c">
-      <Filter>src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.c">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc\lb\v1</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_common.c">
       <Filter>third_party\nanopb</Filter>
@@ -613,23 +640,32 @@
     <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.c">
       <Filter>third_party\nanopb</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\pick_first\pick_first.c">
-      <Filter>src\core\ext\lb_policy\pick_first</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\pick_first\pick_first.c">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\pick_first</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\round_robin\round_robin.c">
-      <Filter>src\core\ext\lb_policy\round_robin</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\round_robin\round_robin.c">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\round_robin</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\native\dns_resolver.c">
-      <Filter>src\core\ext\resolver\dns\native</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\dns_resolver_ares.c">
+      <Filter>src\core\ext\filters\client_channel\resolver\dns\c_ares</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\sockaddr\sockaddr_resolver.c">
-      <Filter>src\core\ext\resolver\sockaddr</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_ev_driver_posix.c">
+      <Filter>src\core\ext\filters\client_channel\resolver\dns\c_ares</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.c">
-      <Filter>src\core\ext\load_reporting</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.c">
+      <Filter>src\core\ext\filters\client_channel\resolver\dns\c_ares</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.c">
-      <Filter>src\core\ext\load_reporting</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\native\dns_resolver.c">
+      <Filter>src\core\ext\filters\client_channel\resolver\dns\native</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\sockaddr\sockaddr_resolver.c">
+      <Filter>src\core\ext\filters\client_channel\resolver\sockaddr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\load_reporting\load_reporting.c">
+      <Filter>src\core\ext\filters\load_reporting</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\load_reporting\load_reporting_filter.c">
+      <Filter>src\core\ext\filters\load_reporting</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\base_resources.c">
       <Filter>src\core\ext\census</Filter>
@@ -673,6 +709,12 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\tracing.c">
       <Filter>src\core\ext\census</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\max_age\max_age_filter.c">
+      <Filter>src\core\ext\filters\max_age</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\message_size\message_size_filter.c">
+      <Filter>src\core\ext\filters\message_size</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\plugin_registry\grpc_plugin_registry.c">
       <Filter>src\core\plugin_registry</Filter>
     </ClCompile>
@@ -726,6 +768,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -750,9 +795,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -782,18 +824,12 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\deadline_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
@@ -803,15 +839,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h">
       <Filter>src\core\lib\compression</Filter>
     </ClInclude>
@@ -878,6 +905,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
@@ -920,6 +950,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
@@ -944,6 +977,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_uv.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
@@ -1001,6 +1037,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h">
       <Filter>src\core\lib\json</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\b64.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h">
       <Filter>src\core\lib\slice</Filter>
     </ClInclude>
@@ -1034,6 +1073,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.h">
       <Filter>src\core\lib\surface</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\event_string.h">
       <Filter>src\core\lib\surface</Filter>
     </ClInclude>
@@ -1130,6 +1172,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\hpack_table.h">
       <Filter>src\core\ext\transport\chttp2\transport</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\http2_settings.h">
+      <Filter>src\core\ext\transport\chttp2\transport</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\huffsyms.h">
       <Filter>src\core\ext\transport\chttp2\transport</Filter>
     </ClInclude>
@@ -1148,6 +1193,15 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\alpn\alpn.h">
       <Filter>src\core\ext\transport\chttp2\alpn</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\http\client\http_client_filter.h">
+      <Filter>src\core\ext\filters\http\client</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\http\message_compress\message_compress_filter.h">
+      <Filter>src\core\ext\filters\http\message_compress</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\http\server\http_server_filter.h">
+      <Filter>src\core\ext\filters\http\server</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\context\security_context.h">
       <Filter>src\core\lib\security\context</Filter>
     </ClInclude>
@@ -1202,98 +1256,107 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\tsi_error.h">
       <Filter>src\core\lib\security\transport</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\util\b64.h">
-      <Filter>src\core\lib\security\util</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\util\json_util.h">
       <Filter>src\core\lib\security\util</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\tsi\fake_transport_security.h">
-      <Filter>src\core\lib\tsi</Filter>
+    <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\lib\tsi\ssl_transport_security.h">
-      <Filter>src\core\lib\tsi</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\ssl_types.h">
+      <Filter>src\core\tsi</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\tsi\ssl_types.h">
-      <Filter>src\core\lib\tsi</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\transport_security.h">
+      <Filter>src\core\tsi</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\tsi\transport_security.h">
-      <Filter>src\core\lib\tsi</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\transport_security_adapter.h">
+      <Filter>src\core\tsi</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\tsi\transport_security_interface.h">
-      <Filter>src\core\lib\tsi</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\transport_security_interface.h">
+      <Filter>src\core\tsi</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\chttp2_server.h">
       <Filter>src\core\ext\transport\chttp2\server</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel_factory.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel_factory.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\connector.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\connector.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\http_connect_handshaker.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\http_connect_handshaker.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\http_proxy.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\http_proxy.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\initial_connect_string.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy_factory.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy_registry.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_factory.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\parse_address.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\proxy_mapper.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\proxy_mapper_registry.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\proxy_mapper.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\proxy_mapper_registry.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver_factory.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver_registry.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_factory.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\retry_throttle.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_registry.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\subchannel.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\subchannel_index.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel_index.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\uri_parser.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\uri_parser.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\deadline\deadline_filter.h">
+      <Filter>src\core\ext\filters\deadline</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\chttp2_connector.h">
       <Filter>src\core\ext\transport\chttp2\client</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb.h">
-      <Filter>src\core\ext\lb_policy\grpclb</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\client_load_reporting_filter.h">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb_channel.h">
-      <Filter>src\core\ext\lb_policy\grpclb</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb.h">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.h">
-      <Filter>src\core\ext\lb_policy\grpclb</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb_channel.h">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.h">
-      <Filter>src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb_client_stats.h">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\load_balancer_api.h">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.h">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc\lb\v1</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb.h">
       <Filter>third_party\nanopb</Filter>
@@ -1307,11 +1370,17 @@
     <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.h">
       <Filter>third_party\nanopb</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.h">
-      <Filter>src\core\ext\load_reporting</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_ev_driver.h">
+      <Filter>src\core\ext\filters\client_channel\resolver\dns\c_ares</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.h">
+      <Filter>src\core\ext\filters\client_channel\resolver\dns\c_ares</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.h">
-      <Filter>src\core\ext\load_reporting</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\load_reporting\load_reporting.h">
+      <Filter>src\core\ext\filters\load_reporting</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\load_reporting\load_reporting_filter.h">
+      <Filter>src\core\ext\filters\load_reporting</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\aggregation.h">
       <Filter>src\core\ext\census</Filter>
@@ -1361,6 +1430,12 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\tracing.h">
       <Filter>src\core\ext\census</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\max_age\max_age_filter.h">
+      <Filter>src\core\ext\filters\max_age</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\message_size\message_size_filter.h">
+      <Filter>src\core\ext\filters\message_size</Filter>
+    </ClInclude>
   </ItemGroup>
 
   <ItemGroup>
@@ -1391,47 +1466,74 @@
     <Filter Include="src\core\ext\census\gen">
       <UniqueIdentifier>{4a14dd37-5868-c656-7333-fa80574cbb07}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\client_channel">
-      <UniqueIdentifier>{36eee53a-cd19-738a-c387-20c44a2bfd07}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters">
+      <UniqueIdentifier>{a7cd279d-e0ec-32d3-4cbe-778aba4a0000}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\lb_policy">
-      <UniqueIdentifier>{030f00ff-6c54-76c8-12df-37e3008335d1}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel">
+      <UniqueIdentifier>{d38c43fd-50e4-fba5-59c5-0d4817159aad}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\lb_policy\grpclb">
-      <UniqueIdentifier>{fe41339e-53fb-39b3-7457-7a0fbb238dbe}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\lb_policy">
+      <UniqueIdentifier>{784368be-88aa-3170-1479-48fdf8fbc7be}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\lb_policy\grpclb\proto">
-      <UniqueIdentifier>{a7c27f6b-6d15-01cf-76d9-c30dddea0990}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\lb_policy\grpclb">
+      <UniqueIdentifier>{82e39ac8-1993-6894-efed-651068234a28}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\lb_policy\grpclb\proto\grpc">
-      <UniqueIdentifier>{bc714e6d-8aba-91df-7db9-7f189f05a6ff}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\lb_policy\grpclb\proto">
+      <UniqueIdentifier>{ff02fee6-7304-df5f-76a6-008b5a1c7d19}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\lb_policy\grpclb\proto\grpc\lb">
-      <UniqueIdentifier>{adf7e553-94ef-14fd-e845-03104f00a06f}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc">
+      <UniqueIdentifier>{953a74cb-cafd-eedd-8d34-038c28daf188}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1">
-      <UniqueIdentifier>{bc357e2d-8ddd-a688-88a3-255228fc0818}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc\lb">
+      <UniqueIdentifier>{595a1701-eb5a-e8af-ffa3-f67c0e380894}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\lb_policy\pick_first">
-      <UniqueIdentifier>{b63ded00-b24f-708e-333f-ce199e421875}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc\lb\v1">
+      <UniqueIdentifier>{af8e2597-93ef-1381-d773-082a85e7eaf1}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\lb_policy\round_robin">
-      <UniqueIdentifier>{2472d352-cf94-f317-646e-72b769cea846}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\lb_policy\pick_first">
+      <UniqueIdentifier>{9a3e8049-bc04-8341-5173-6fe5f8a4465c}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\load_reporting">
-      <UniqueIdentifier>{b6c863cd-a135-32e8-df03-02365f526f0d}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\lb_policy\round_robin">
+      <UniqueIdentifier>{6d3d5842-8257-9c58-7985-75f4d98b7d5c}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\resolver">
-      <UniqueIdentifier>{6bfa6808-9dcb-8990-deed-5cf58a149dda}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\resolver">
+      <UniqueIdentifier>{c9873fec-2f83-0497-6d0a-bd9c1cc63be3}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\resolver\dns">
-      <UniqueIdentifier>{e8fe6413-ab8c-48d5-2c7b-aa79e3db4ab2}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\resolver\dns">
+      <UniqueIdentifier>{91b79502-da45-f80b-933e-c974b089db5c}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\resolver\dns\native">
-      <UniqueIdentifier>{94e34be0-29d2-1731-3c1e-617ec4986acb}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\resolver\dns\c_ares">
+      <UniqueIdentifier>{73d42c09-d1b5-2e4e-ef12-d74d8ee33ac2}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\resolver\sockaddr">
-      <UniqueIdentifier>{98c1ccc2-2c91-a3d2-6040-a2e15993d51a}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\resolver\dns\native">
+      <UniqueIdentifier>{9b2d7e1f-b78a-2e7a-3000-944e46a5fab9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\client_channel\resolver\sockaddr">
+      <UniqueIdentifier>{bd317dd5-323e-5b27-4c05-d85786be36ab}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\deadline">
+      <UniqueIdentifier>{c8dcda4e-dbaa-1ae8-67a9-0dd26046f652}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\http">
+      <UniqueIdentifier>{2e3ab9f3-39ca-db39-cb3e-2196cbc68098}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\http\client">
+      <UniqueIdentifier>{e4f7616b-2b49-7df9-8ca3-eb7848d4609d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\http\message_compress">
+      <UniqueIdentifier>{7b595f5a-c5b5-29fe-74c2-5ec5fd5c94d2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\http\server">
+      <UniqueIdentifier>{a40e82ca-0c04-35b8-898d-7ad5f323d110}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\load_reporting">
+      <UniqueIdentifier>{12559ba7-9445-92ae-0c5a-2d79570d4c9b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\max_age">
+      <UniqueIdentifier>{5369e83c-4625-fc14-cc40-9db5da3a7af4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\message_size">
+      <UniqueIdentifier>{5ca3f38c-539f-3c4f-b68c-38b31ba339ba}</UniqueIdentifier>
     </Filter>
     <Filter Include="src\core\ext\transport">
       <UniqueIdentifier>{e3abfd0a-064e-0f2f-c8e8-7c5a7e98142a}</UniqueIdentifier>
@@ -1532,12 +1634,12 @@
     <Filter Include="src\core\lib\transport">
       <UniqueIdentifier>{e9d0d3fc-c100-f3e6-89b8-649f241155bf}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\lib\tsi">
-      <UniqueIdentifier>{95ad2811-c8d0-7a42-2a73-baf03fcbf699}</UniqueIdentifier>
-    </Filter>
     <Filter Include="src\core\plugin_registry">
       <UniqueIdentifier>{02bec99b-ff39-88d7-9dea-e0ff9f4a2701}</UniqueIdentifier>
     </Filter>
+    <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>
diff --git a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj
index 05165d6fb8015f917d362c21e0e9c0be9584eedf..a3d5b26be47f66c57462ab74dd05bcdcc202ef71 100644
--- a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj
+++ b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj
@@ -163,11 +163,15 @@
     <ClInclude Include="$(SolutionDir)\..\src\compiler\objective_c_generator_helpers.h" />
     <ClInclude Include="$(SolutionDir)\..\src\compiler\php_generator.h" />
     <ClInclude Include="$(SolutionDir)\..\src\compiler\php_generator_helpers.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\compiler\protobuf_plugin.h" />
     <ClInclude Include="$(SolutionDir)\..\src\compiler\python_generator.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\compiler\python_generator_helpers.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\compiler\python_private_generator.h" />
     <ClInclude Include="$(SolutionDir)\..\src\compiler\ruby_generator.h" />
     <ClInclude Include="$(SolutionDir)\..\src\compiler\ruby_generator_helpers-inl.h" />
     <ClInclude Include="$(SolutionDir)\..\src\compiler\ruby_generator_map-inl.h" />
     <ClInclude Include="$(SolutionDir)\..\src\compiler\ruby_generator_string-inl.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\compiler\schema_interface.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\src\compiler\cpp_generator.cc">
diff --git a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters
index c8b893221d3eb3110caf68d1af3a403824ede7f6..8fa3a0fa72c84e2b94fb9c467cdef5464f91db05 100644
--- a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters
@@ -65,9 +65,18 @@
     <ClInclude Include="$(SolutionDir)\..\src\compiler\php_generator_helpers.h">
       <Filter>src\compiler</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\compiler\protobuf_plugin.h">
+      <Filter>src\compiler</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\compiler\python_generator.h">
       <Filter>src\compiler</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\compiler\python_generator_helpers.h">
+      <Filter>src\compiler</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\compiler\python_private_generator.h">
+      <Filter>src\compiler</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\compiler\ruby_generator.h">
       <Filter>src\compiler</Filter>
     </ClInclude>
@@ -80,6 +89,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\compiler\ruby_generator_string-inl.h">
       <Filter>src\compiler</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\compiler\schema_interface.h">
+      <Filter>src\compiler</Filter>
+    </ClInclude>
   </ItemGroup>
 
   <ItemGroup>
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
index d08ceb682875ec3757b92142059fb40eb25c088f..df89932a97c3ea326a36c9817a5c6d99def5cf57 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -163,6 +163,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
@@ -171,7 +172,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
@@ -182,7 +182,7 @@
     <ClInclude Include="$(SolutionDir)\..\test\core\security\oauth2_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fake_resolver.h" />
-    <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy.h" />
+    <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy_fixture.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\iomgr\endpoint_tests.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\util\debugger_macros.h" />
@@ -198,16 +198,11 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\deadline_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h" />
@@ -230,6 +225,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset.h" />
@@ -244,6 +240,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.h" />
@@ -252,6 +249,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_uv.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.h" />
@@ -271,6 +269,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_common.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\b64.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h" />
@@ -282,6 +281,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\event_string.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\init.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.h" />
@@ -317,7 +317,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fake_resolver.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy.c">
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy_fixture.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.c">
     </ClCompile>
@@ -349,24 +349,14 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\deadline_filter.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
@@ -415,6 +405,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.c">
@@ -437,6 +429,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
@@ -461,6 +455,12 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_posix.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_common.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_ifaddrs.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_noifaddrs.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_uv.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_windows.c">
@@ -505,6 +505,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\b64.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice.c">
@@ -541,9 +543,11 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\event_string.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\metadata_array.c">
     </ClCompile>
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 3beaa80994f7a62397bdcce8a7c7a2053dd6e5bc..22cfbe14d4dd5a0ecb635eacb4befdecdb7b8724 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -22,7 +22,7 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fake_resolver.c">
       <Filter>test\core\end2end</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy.c">
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy_fixture.c">
       <Filter>test\core\end2end\fixtures</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.c">
@@ -70,15 +70,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\deadline_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
@@ -88,15 +82,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
       <Filter>src\core\lib\compression</Filter>
     </ClCompile>
@@ -169,6 +154,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -202,6 +190,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -238,6 +229,15 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_posix.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_common.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_ifaddrs.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_noifaddrs.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_uv.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -304,6 +304,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c">
       <Filter>src\core\lib\json</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\b64.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.c">
       <Filter>src\core\lib\slice</Filter>
     </ClCompile>
@@ -358,10 +361,13 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.c">
       <Filter>src\core\lib\surface</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\event_string.c">
       <Filter>src\core\lib\surface</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.cc">
       <Filter>src\core\lib\surface</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\metadata_array.c">
@@ -465,6 +471,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -489,9 +498,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -518,7 +524,7 @@
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fake_resolver.h">
       <Filter>test\core\end2end</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy.h">
+    <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy_fixture.h">
       <Filter>test\core\end2end\fixtures</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.h">
@@ -566,18 +572,12 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\deadline_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
@@ -587,15 +587,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h">
       <Filter>src\core\lib\compression</Filter>
     </ClInclude>
@@ -662,6 +653,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
@@ -704,6 +698,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
@@ -728,6 +725,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_uv.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
@@ -785,6 +785,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h">
       <Filter>src\core\lib\json</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\b64.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h">
       <Filter>src\core\lib\slice</Filter>
     </ClInclude>
@@ -818,6 +821,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.h">
       <Filter>src\core\lib\surface</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\event_string.h">
       <Filter>src\core\lib\surface</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
index 5a58cae83ffc5683a87afa51232557738a42e50c..af13acef45530daf7327cc25b5470990e848fb48 100644
--- a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
@@ -149,7 +149,7 @@
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fake_resolver.h" />
-    <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy.h" />
+    <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy_fixture.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\iomgr\endpoint_tests.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\util\debugger_macros.h" />
@@ -168,7 +168,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fake_resolver.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy.c">
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy_fixture.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.c">
     </ClCompile>
diff --git a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
index 88c875cb011d5f325cf765815f49e0cfe98bca86..4da043ea9080571157114a614c991d9f3e93e079 100644
--- a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
@@ -7,7 +7,7 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fake_resolver.c">
       <Filter>test\core\end2end</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy.c">
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy_fixture.c">
       <Filter>test\core\end2end\fixtures</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.c">
@@ -54,7 +54,7 @@
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fake_resolver.h">
       <Filter>test\core\end2end</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy.h">
+    <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy_fixture.h">
       <Filter>test\core\end2end\fixtures</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.h">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index 22f4740b8fa7e84f3762e3c0ff5e75bc2a4bde9b..2db0ffa692018268a7ea1a4958318658774bf0f1 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -274,6 +274,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
@@ -282,7 +283,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
@@ -293,16 +293,11 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\deadline_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h" />
@@ -325,6 +320,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset.h" />
@@ -339,6 +335,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.h" />
@@ -347,6 +344,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_uv.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.h" />
@@ -366,6 +364,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_common.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\b64.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h" />
@@ -377,6 +376,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\event_string.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\init.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.h" />
@@ -409,38 +409,47 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\hpack_encoder.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\hpack_parser.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\hpack_table.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\http2_settings.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\huffsyms.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\incoming_metadata.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\stream_map.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\varint.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\alpn\alpn.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\http\client\http_client_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\http\message_compress\message_compress_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\http\server\http_server_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\chttp2_server.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\chttp2_connector.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel_factory.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\connector.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\http_connect_handshaker.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\http_proxy.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\initial_connect_string.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_factory.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\proxy_mapper.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\proxy_mapper_registry.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_factory.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_registry.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel_index.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\uri_parser.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb_channel.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel_factory.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\connector.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\http_connect_handshaker.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\http_proxy.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy_factory.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy_registry.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\parse_address.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\proxy_mapper.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\proxy_mapper_registry.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver_factory.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver_registry.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\retry_throttle.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\subchannel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\subchannel_index.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\uri_parser.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\deadline\deadline_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_ev_driver.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\load_reporting\load_reporting.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\load_reporting\load_reporting_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\client_load_reporting_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb_channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb_client_stats.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\load_balancer_api.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.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" />
@@ -461,6 +470,8 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\trace_status.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\trace_string.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\tracing.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\max_age\max_age_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\message_size\message_size_filter.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\init.c">
@@ -473,24 +484,14 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\deadline_filter.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
@@ -539,6 +540,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.c">
@@ -561,6 +564,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
@@ -585,6 +590,12 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_posix.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_common.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_ifaddrs.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_noifaddrs.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_uv.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_windows.c">
@@ -629,6 +640,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\b64.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice.c">
@@ -665,9 +678,11 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\event_string.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\metadata_array.c">
     </ClCompile>
@@ -733,6 +748,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\hpack_table.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\http2_settings.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\huffsyms.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\incoming_metadata.c">
@@ -749,6 +766,14 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\alpn\alpn.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\http\client\http_client_filter.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\http\http_filters_plugin.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\http\message_compress\message_compress_filter.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\http\server\http_server_filter.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\chttp2_server.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create.c">
@@ -757,63 +782,73 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\chttp2_connector.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\channel_connectivity.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\channel_connectivity.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel_factory.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel_factory.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel_plugin.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel_plugin.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\connector.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\connector.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\http_connect_handshaker.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\default_initial_connect_string.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\http_proxy.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\http_connect_handshaker.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\http_proxy.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy_factory.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\initial_connect_string.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy_registry.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\parse_address.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_factory.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\proxy_mapper.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\proxy_mapper_registry.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\proxy_mapper.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver_factory.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\proxy_mapper_registry.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver_registry.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\retry_throttle.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_factory.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\subchannel.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_registry.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\subchannel_index.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\uri_parser.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel_index.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\deadline\deadline_filter.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\uri_parser.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\dns_resolver_ares.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\native\dns_resolver.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_ev_driver_posix.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\sockaddr\sockaddr_resolver.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\native\dns_resolver.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\sockaddr\sockaddr_resolver.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\load_reporting\load_reporting.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb_channel.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\load_reporting\load_reporting_filter.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\client_load_reporting_filter.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb_channel.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb_client_stats.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\load_balancer_api.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_common.c">
     </ClCompile>
@@ -821,9 +856,9 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\pick_first\pick_first.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\pick_first\pick_first.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\round_robin\round_robin.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\round_robin\round_robin.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\base_resources.c">
     </ClCompile>
@@ -853,6 +888,10 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\tracing.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\max_age\max_age_filter.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\message_size\message_size_filter.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\plugin_registry\grpc_unsecure_plugin_registry.c">
     </ClCompile>
   </ItemGroup>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 5021cb47d8df4eb8d29b8fc5e3d58d36af9f9c2e..c7d6670db1b4d22249abc4b4ec51a0a5467a8032 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -16,15 +16,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\deadline_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
@@ -34,15 +28,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
       <Filter>src\core\lib\compression</Filter>
     </ClCompile>
@@ -115,6 +100,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -148,6 +136,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -184,6 +175,15 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_posix.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_common.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_ifaddrs.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix_noifaddrs.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_uv.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -250,6 +250,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c">
       <Filter>src\core\lib\json</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\b64.c">
+      <Filter>src\core\lib\slice</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.c">
       <Filter>src\core\lib\slice</Filter>
     </ClCompile>
@@ -304,10 +307,13 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.c">
       <Filter>src\core\lib\surface</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\event_string.c">
       <Filter>src\core\lib\surface</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.cc">
       <Filter>src\core\lib\surface</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\metadata_array.c">
@@ -406,6 +412,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\hpack_table.c">
       <Filter>src\core\ext\transport\chttp2\transport</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\http2_settings.c">
+      <Filter>src\core\ext\transport\chttp2\transport</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\huffsyms.c">
       <Filter>src\core\ext\transport\chttp2\transport</Filter>
     </ClCompile>
@@ -430,6 +439,18 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\alpn\alpn.c">
       <Filter>src\core\ext\transport\chttp2\alpn</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\http\client\http_client_filter.c">
+      <Filter>src\core\ext\filters\http\client</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\http\http_filters_plugin.c">
+      <Filter>src\core\ext\filters\http</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\http\message_compress\message_compress_filter.c">
+      <Filter>src\core\ext\filters\http\message_compress</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\http\server\http_server_filter.c">
+      <Filter>src\core\ext\filters\http\server</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\chttp2_server.c">
       <Filter>src\core\ext\transport\chttp2\server</Filter>
     </ClCompile>
@@ -442,92 +463,107 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\chttp2_connector.c">
       <Filter>src\core\ext\transport\chttp2\client</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\channel_connectivity.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\channel_connectivity.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel_factory.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel_plugin.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel_factory.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\connector.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel_plugin.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\http_connect_handshaker.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\connector.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\http_proxy.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\default_initial_connect_string.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\http_connect_handshaker.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy_factory.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\http_proxy.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy_registry.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\initial_connect_string.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\parse_address.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\proxy_mapper.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_factory.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\proxy_mapper_registry.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver_factory.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\proxy_mapper.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver_registry.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\proxy_mapper_registry.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\retry_throttle.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\subchannel.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_factory.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\subchannel_index.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_registry.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\uri_parser.c">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\deadline\deadline_filter.c">
+      <Filter>src\core\ext\filters\deadline</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel_index.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\dns_resolver_ares.c">
+      <Filter>src\core\ext\filters\client_channel\resolver\dns\c_ares</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\uri_parser.c">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_ev_driver_posix.c">
+      <Filter>src\core\ext\filters\client_channel\resolver\dns\c_ares</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\native\dns_resolver.c">
-      <Filter>src\core\ext\resolver\dns\native</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.c">
+      <Filter>src\core\ext\filters\client_channel\resolver\dns\c_ares</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\sockaddr\sockaddr_resolver.c">
-      <Filter>src\core\ext\resolver\sockaddr</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\native\dns_resolver.c">
+      <Filter>src\core\ext\filters\client_channel\resolver\dns\native</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.c">
-      <Filter>src\core\ext\load_reporting</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\sockaddr\sockaddr_resolver.c">
+      <Filter>src\core\ext\filters\client_channel\resolver\sockaddr</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.c">
-      <Filter>src\core\ext\load_reporting</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\load_reporting\load_reporting.c">
+      <Filter>src\core\ext\filters\load_reporting</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb.c">
-      <Filter>src\core\ext\lb_policy\grpclb</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\load_reporting\load_reporting_filter.c">
+      <Filter>src\core\ext\filters\load_reporting</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb_channel.c">
-      <Filter>src\core\ext\lb_policy\grpclb</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\client_load_reporting_filter.c">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.c">
-      <Filter>src\core\ext\lb_policy\grpclb</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb.c">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.c">
-      <Filter>src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb_channel.c">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb_client_stats.c">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\load_balancer_api.c">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.c">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc\lb\v1</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_common.c">
       <Filter>third_party\nanopb</Filter>
@@ -538,11 +574,11 @@
     <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.c">
       <Filter>third_party\nanopb</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\pick_first\pick_first.c">
-      <Filter>src\core\ext\lb_policy\pick_first</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\pick_first\pick_first.c">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\pick_first</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\round_robin\round_robin.c">
-      <Filter>src\core\ext\lb_policy\round_robin</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\round_robin\round_robin.c">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\round_robin</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\base_resources.c">
       <Filter>src\core\ext\census</Filter>
@@ -586,6 +622,12 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\tracing.c">
       <Filter>src\core\ext\census</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\max_age\max_age_filter.c">
+      <Filter>src\core\ext\filters\max_age</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\message_size\message_size_filter.c">
+      <Filter>src\core\ext\filters\message_size</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\plugin_registry\grpc_unsecure_plugin_registry.c">
       <Filter>src\core\plugin_registry</Filter>
     </ClCompile>
@@ -639,6 +681,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -663,9 +708,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -692,18 +734,12 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\deadline_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
@@ -713,15 +749,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h">
       <Filter>src\core\lib\compression</Filter>
     </ClInclude>
@@ -788,6 +815,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\lockfree_event.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
@@ -830,6 +860,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_factory_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
@@ -854,6 +887,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_utils_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_uv.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
@@ -911,6 +947,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h">
       <Filter>src\core\lib\json</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\b64.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h">
       <Filter>src\core\lib\slice</Filter>
     </ClInclude>
@@ -944,6 +983,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.h">
       <Filter>src\core\lib\surface</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue_factory.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\event_string.h">
       <Filter>src\core\lib\surface</Filter>
     </ClInclude>
@@ -1040,6 +1082,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\hpack_table.h">
       <Filter>src\core\ext\transport\chttp2\transport</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\http2_settings.h">
+      <Filter>src\core\ext\transport\chttp2\transport</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\huffsyms.h">
       <Filter>src\core\ext\transport\chttp2\transport</Filter>
     </ClInclude>
@@ -1058,83 +1103,107 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\alpn\alpn.h">
       <Filter>src\core\ext\transport\chttp2\alpn</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\http\client\http_client_filter.h">
+      <Filter>src\core\ext\filters\http\client</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\http\message_compress\message_compress_filter.h">
+      <Filter>src\core\ext\filters\http\message_compress</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\http\server\http_server_filter.h">
+      <Filter>src\core\ext\filters\http\server</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\chttp2_server.h">
       <Filter>src\core\ext\transport\chttp2\server</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\chttp2_connector.h">
       <Filter>src\core\ext\transport\chttp2\client</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\client_channel_factory.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel_factory.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\connector.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\connector.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\http_connect_handshaker.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\http_connect_handshaker.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\http_proxy.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\http_proxy.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\initial_connect_string.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy_factory.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy_registry.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_factory.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\parse_address.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\proxy_mapper.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\proxy_mapper_registry.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\proxy_mapper.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\proxy_mapper_registry.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver_factory.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver_registry.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_factory.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\retry_throttle.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_registry.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\subchannel.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\subchannel_index.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel_index.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\uri_parser.h">
+      <Filter>src\core\ext\filters\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\uri_parser.h">
-      <Filter>src\core\ext\client_channel</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\deadline\deadline_filter.h">
+      <Filter>src\core\ext\filters\deadline</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.h">
-      <Filter>src\core\ext\load_reporting</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_ev_driver.h">
+      <Filter>src\core\ext\filters\client_channel\resolver\dns\c_ares</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.h">
-      <Filter>src\core\ext\load_reporting</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.h">
+      <Filter>src\core\ext\filters\client_channel\resolver\dns\c_ares</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb.h">
-      <Filter>src\core\ext\lb_policy\grpclb</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\load_reporting\load_reporting.h">
+      <Filter>src\core\ext\filters\load_reporting</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb_channel.h">
-      <Filter>src\core\ext\lb_policy\grpclb</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\load_reporting\load_reporting_filter.h">
+      <Filter>src\core\ext\filters\load_reporting</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.h">
-      <Filter>src\core\ext\lb_policy\grpclb</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\client_load_reporting_filter.h">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.h">
-      <Filter>src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1</Filter>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb.h">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb_channel.h">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\grpclb_client_stats.h">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\load_balancer_api.h">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.h">
+      <Filter>src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc\lb\v1</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb.h">
       <Filter>third_party\nanopb</Filter>
@@ -1196,6 +1265,12 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\tracing.h">
       <Filter>src\core\ext\census</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\max_age\max_age_filter.h">
+      <Filter>src\core\ext\filters\max_age</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\message_size\message_size_filter.h">
+      <Filter>src\core\ext\filters\message_size</Filter>
+    </ClInclude>
   </ItemGroup>
 
   <ItemGroup>
@@ -1226,47 +1301,74 @@
     <Filter Include="src\core\ext\census\gen">
       <UniqueIdentifier>{dfe53168-57b0-3ac4-d8ba-07fd958cc8f5}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\client_channel">
-      <UniqueIdentifier>{2edd1aad-34cf-0c66-e03e-b1b2dd81d9a8}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters">
+      <UniqueIdentifier>{5e37012e-a374-e285-bbda-b0dbe6327663}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\client_channel">
+      <UniqueIdentifier>{bb0de45a-745e-8822-7ad5-453f9e060f8c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\client_channel\lb_policy">
+      <UniqueIdentifier>{2ac0872e-12dc-0b08-68e0-66829ce8c268}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\client_channel\lb_policy\grpclb">
+      <UniqueIdentifier>{6cc603b0-7272-0a9f-59c2-5561c1856a6a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\client_channel\lb_policy\grpclb\proto">
+      <UniqueIdentifier>{0d3bc4ed-1eea-8b17-c26f-7d87c3dd2220}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc">
+      <UniqueIdentifier>{32d37957-d122-e649-b9c1-3f13f6674479}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc\lb">
+      <UniqueIdentifier>{153a159f-1ba7-aea7-ebed-4f2d9e2e7bb9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\client_channel\lb_policy\grpclb\proto\grpc\lb\v1">
+      <UniqueIdentifier>{f8747b87-02f9-df6c-0eeb-27ab1d037d0c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\client_channel\lb_policy\pick_first">
+      <UniqueIdentifier>{4df776ac-ebeb-4933-554e-749a0399ff51}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\ext\filters\client_channel\lb_policy\round_robin">
+      <UniqueIdentifier>{5244539b-6cec-80c7-61dc-df51e531bedd}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\lb_policy">
-      <UniqueIdentifier>{a23781d2-27e4-7cb0-12cd-59782ecb21ce}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\resolver">
+      <UniqueIdentifier>{663be499-ce6c-8afd-db98-674f26be1149}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\lb_policy\grpclb">
-      <UniqueIdentifier>{25a465c8-d1e8-6248-c005-bb2062206472}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\resolver\dns">
+      <UniqueIdentifier>{f6bf03da-fa0d-0c24-bba2-17dc5a3c8fe0}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\lb_policy\grpclb\proto">
-      <UniqueIdentifier>{40fc2615-d244-0d36-4486-ba6f0fa468bb}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\resolver\dns\c_ares">
+      <UniqueIdentifier>{54bc0ac2-39c8-dbfd-c5dd-b9fb597dd820}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\lb_policy\grpclb\proto\grpc">
-      <UniqueIdentifier>{1d129f24-a399-12ef-68de-023aff7dde52}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\resolver\dns\native">
+      <UniqueIdentifier>{55f499bd-ae18-5210-81e1-385c85e60875}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\lb_policy\grpclb\proto\grpc\lb">
-      <UniqueIdentifier>{21858d9d-30b5-8847-5882-6b47df0fa293}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\client_channel\resolver\sockaddr">
+      <UniqueIdentifier>{99210f5e-b2a0-ecd1-024f-fc152db68a11}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1">
-      <UniqueIdentifier>{e9256e96-ea3d-c1fd-6426-9d53d9f08f66}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\deadline">
+      <UniqueIdentifier>{ac374be1-7a3f-14a8-69fe-badac2d9f9ec}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\lb_policy\pick_first">
-      <UniqueIdentifier>{e27f9ecf-97bb-1a2e-3135-a41f732dcf55}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\http">
+      <UniqueIdentifier>{33287f7d-739b-d30d-a9f3-b338103456b0}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\lb_policy\round_robin">
-      <UniqueIdentifier>{e5fc1091-5d60-404f-775b-686ef4b3266f}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\http\client">
+      <UniqueIdentifier>{95cd5972-7339-6f09-2332-e6769b3cba3f}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\load_reporting">
-      <UniqueIdentifier>{2d6e3879-24c7-06e2-b415-40ab18a3b918}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\http\message_compress">
+      <UniqueIdentifier>{cf8cb886-3020-e143-317e-730ff9bbddc3}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\resolver">
-      <UniqueIdentifier>{88c78e27-267a-95df-07c5-50e5fbc2f40c}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\http\server">
+      <UniqueIdentifier>{2c1e7897-6f69-f8b9-0b90-5c3fae59a48f}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\resolver\dns">
-      <UniqueIdentifier>{2e0a9b4f-6394-7c0e-6e5a-0f8b3ee29b41}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\load_reporting">
+      <UniqueIdentifier>{0aef07b4-39d2-f862-15ac-65b4bf00dabb}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\resolver\dns\native">
-      <UniqueIdentifier>{3d5398c8-928b-9096-8eb7-f8c40ee68c4d}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\max_age">
+      <UniqueIdentifier>{d3bc80c1-5f2d-e842-42ac-43d8a6ada8de}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\resolver\sockaddr">
-      <UniqueIdentifier>{71686ed0-fbf9-02a4-d65a-a73f7dc4e2be}</UniqueIdentifier>
+    <Filter Include="src\core\ext\filters\message_size">
+      <UniqueIdentifier>{8cbe7444-caac-49dc-be89-d4c4d1c7966a}</UniqueIdentifier>
     </Filter>
     <Filter Include="src\core\ext\transport">
       <UniqueIdentifier>{967c89fe-c97c-27e2-aac0-9ba5854cb5fa}</UniqueIdentifier>
diff --git a/vsprojects/vcxproj/qps/qps.vcxproj b/vsprojects/vcxproj/qps/qps.vcxproj
index 2d7892683a85d911d42239a173451e2f10d4daa8..6e290f4557d72d55665019dbe734686ac6435211 100644
--- a/vsprojects/vcxproj/qps/qps.vcxproj
+++ b/vsprojects/vcxproj/qps/qps.vcxproj
@@ -147,6 +147,7 @@
   </ItemDefinitionGroup>
 
   <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\benchmark_config.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\client.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\driver.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\histogram.h" />
@@ -157,7 +158,6 @@
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\server.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\stats.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\usage_timer.h" />
-    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\benchmark_config.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.pb.cc">
@@ -200,6 +200,8 @@
     </ClCompile>
     <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\services.grpc.pb.h">
     </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\benchmark_config.cc">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\client_async.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\client_sync.cc">
@@ -218,8 +220,6 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\usage_timer.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\benchmark_config.cc">
-    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
diff --git a/vsprojects/vcxproj/qps/qps.vcxproj.filters b/vsprojects/vcxproj/qps/qps.vcxproj.filters
index f25be9af191a02a4d50aa86939acafa668cb45f0..a7d6c127e8ae57cd51b6dbada04d4205b393db64 100644
--- a/vsprojects/vcxproj/qps/qps.vcxproj.filters
+++ b/vsprojects/vcxproj/qps/qps.vcxproj.filters
@@ -16,6 +16,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\services.proto">
       <Filter>src\proto\grpc\testing</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\benchmark_config.cc">
+      <Filter>test\cpp\qps</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\client_async.cc">
       <Filter>test\cpp\qps</Filter>
     </ClCompile>
@@ -43,11 +46,11 @@
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\usage_timer.cc">
       <Filter>test\cpp\qps</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\benchmark_config.cc">
-      <Filter>test\cpp\util</Filter>
-    </ClCompile>
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\benchmark_config.h">
+      <Filter>test\cpp\qps</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\client.h">
       <Filter>test\cpp\qps</Filter>
     </ClInclude>
@@ -78,9 +81,6 @@
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\usage_timer.h">
       <Filter>test\cpp\qps</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\benchmark_config.h">
-      <Filter>test\cpp\util</Filter>
-    </ClInclude>
   </ItemGroup>
 
   <ItemGroup>
@@ -105,9 +105,6 @@
     <Filter Include="test\cpp\qps">
       <UniqueIdentifier>{b57fa0e4-f88d-fe46-8885-956fc582de3d}</UniqueIdentifier>
     </Filter>
-    <Filter Include="test\cpp\util">
-      <UniqueIdentifier>{9042d134-6d5a-a907-799e-01768a475055}</UniqueIdentifier>
-    </Filter>
   </ItemGroup>
 </Project>
 
diff --git a/vsprojects/vcxproj/test/arena_test/arena_test.vcxproj b/vsprojects/vcxproj/test/arena_test/arena_test.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..5ae2f8e483c485b19cd43d4a170d15bf661b14c9
--- /dev/null
+++ b/vsprojects/vcxproj/test/arena_test/arena_test.vcxproj
@@ -0,0 +1,193 @@
+<?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>{D85AC722-A88F-4280-F62E-672F571787FF}</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>arena_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>arena_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\support\arena_test.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <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/arena_test/arena_test.vcxproj.filters b/vsprojects/vcxproj/test/arena_test/arena_test.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..c470f17527240f82d49876e7e9a62d6c268ef462
--- /dev/null
+++ b/vsprojects/vcxproj/test/arena_test/arena_test.vcxproj.filters
@@ -0,0 +1,21 @@
+<?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\arena_test.c">
+      <Filter>test\core\support</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{130788b2-eacc-90df-a4f6-f5102a7d3370}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{5c3e1753-6fdb-9476-f98c-a3a394fac54a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\support">
+      <UniqueIdentifier>{1d3d2cc8-4e69-8b2e-6ceb-6569fcb19a86}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
index 986217baba6eeb0a7deefcdf5515f43801b9cc0d..ccb0b521efff09b527b8035bcd8472c87ebbd52b 100644
--- a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
+++ b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
@@ -185,7 +185,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_helper.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\stub_options.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h" />
@@ -196,6 +195,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
@@ -204,7 +204,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
diff --git a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
index b48fe4fceeecf1a2216c2057aa67556025622d7c..18b331ccb1e11b5c8c0236ed23185781300e06e3 100644
--- a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
+++ b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
@@ -96,9 +96,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_helper.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -129,6 +126,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -153,9 +153,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
index fd014fdc098c8ca9a3385d58389e7fd41fcdab18..d4ac0fbc975578c4fc46836684e7a185cfb4dade 100644
--- a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
+++ b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
@@ -185,7 +185,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_helper.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\stub_options.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h" />
@@ -196,6 +195,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
@@ -204,7 +204,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
@@ -256,6 +255,14 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
     </ClCompile>
   </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</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>
diff --git a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
index 176204fac179f7031944d53571a219027e50299f..31680cdc41384ab4c142ef96b7431eec5fe11ab1 100644
--- a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
+++ b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
@@ -99,9 +99,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_helper.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -132,6 +129,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -156,9 +156,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
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 08b3acd03cdce5b1c10b844083e38b12708c6d10..e3adf793d63f936ebb393c3e24bc61c4a2298801 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
@@ -159,6 +159,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\bad_hostname.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\bad_ping.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\binary_metadata.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\cancel_after_accept.c">
@@ -207,6 +209,10 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_concurrent_streams.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_connection_age.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_connection_idle.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_message_length.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\negative_deadline.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 3a8670c1fae35832ae4f6c3a452a89f1c6f31f1b..cfb8d043baf4a9369c606f38f9106ccaa20e675e 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
@@ -13,6 +13,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\bad_hostname.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\bad_ping.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\binary_metadata.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
@@ -85,6 +88,12 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_concurrent_streams.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_connection_age.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_connection_idle.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_message_length.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 96418c3ca543a402fe4642f162471f784749576a..a67f509e25564929b76bcb05ca11995372aadb69 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
@@ -159,6 +159,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\bad_hostname.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\bad_ping.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\binary_metadata.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\call_creds.c">
@@ -209,6 +211,10 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_concurrent_streams.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_connection_age.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_connection_idle.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_message_length.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\negative_deadline.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 cf40abef436b9aaccff25f31d316bce9deeafbcb..97ba77a42e12a70ed9ce1a8d9cae758d5b50b45d 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
@@ -13,6 +13,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\bad_hostname.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\bad_ping.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\binary_metadata.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
@@ -88,6 +91,12 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_concurrent_streams.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_connection_age.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_connection_idle.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_message_length.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
diff --git a/vsprojects/vcxproj/test/error_details_test/error_details_test.vcxproj b/vsprojects/vcxproj/test/error_details_test/error_details_test.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..e146d9c8d219000b8a93e0778e7c1fe2a746019e
--- /dev/null
+++ b/vsprojects/vcxproj/test/error_details_test/error_details_test.vcxproj
@@ -0,0 +1,203 @@
+<?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>{2DE1AE9E-D53C-5854-9122-317E34F90C31}</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\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>error_details_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>error_details_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)\..\src\proto\grpc\testing\echo_messages.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\error_details_test.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_error_details\grpc++_error_details.vcxproj">
+      <Project>{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
+      <Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</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/error_details_test/error_details_test.vcxproj.filters b/vsprojects/vcxproj/test/error_details_test/error_details_test.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..c83e0ae0d769160c278fd70b09f8896e9bb2bae7
--- /dev/null
+++ b/vsprojects/vcxproj/test/error_details_test/error_details_test.vcxproj.filters
@@ -0,0 +1,36 @@
+<?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\testing\echo_messages.proto">
+      <Filter>src\proto\grpc\testing</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\error_details_test.cc">
+      <Filter>test\cpp\util</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="src">
+      <UniqueIdentifier>{35c957dd-436b-c57a-791d-2737bc179e41}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto">
+      <UniqueIdentifier>{c8721123-0390-f97d-5aad-0dd4979d5030}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc">
+      <UniqueIdentifier>{6dbad4a6-6b97-b25a-4f89-6edb20a1e7e0}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc\testing">
+      <UniqueIdentifier>{5f343032-7701-4924-a1d2-06f46d52d1b3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test">
+      <UniqueIdentifier>{688e4f7d-b9aa-342c-ffa7-2ee3ca51cd42}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp">
+      <UniqueIdentifier>{a4e0ed0a-c1bb-60d6-003b-91c3989f6e6e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\util">
+      <UniqueIdentifier>{60a99fd3-4904-d29f-b456-7f601092d055}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/error_test/error_test.vcxproj b/vsprojects/vcxproj/test/error_test/error_test.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..c7d0e5a1000bb15eb0ea93aafeae0606678a24ca
--- /dev/null
+++ b/vsprojects/vcxproj/test/error_test/error_test.vcxproj
@@ -0,0 +1,199 @@
+<?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>{42720233-A6D4-66BC-CCA2-06B57261D0B3}</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>error_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>error_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\iomgr\error_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/error_test/error_test.vcxproj.filters b/vsprojects/vcxproj/test/error_test/error_test.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..d2bb372482fa51531cb17f8c9e2eebc0125cc838
--- /dev/null
+++ b/vsprojects/vcxproj/test/error_test/error_test.vcxproj.filters
@@ -0,0 +1,21 @@
+<?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\iomgr\error_test.c">
+      <Filter>test\core\iomgr</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{3226d467-9fe9-12e9-8b53-f24f5a4c34c0}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{3d86bf5c-b8eb-36f4-efe2-7e8596188481}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\iomgr">
+      <UniqueIdentifier>{91f383bc-92fa-7058-d971-20189eadc0ad}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/set_initial_connect_string_test/set_initial_connect_string_test.vcxproj b/vsprojects/vcxproj/test/fake_resolver_test/fake_resolver_test.vcxproj
similarity index 96%
rename from vsprojects/vcxproj/test/set_initial_connect_string_test/set_initial_connect_string_test.vcxproj
rename to vsprojects/vcxproj/test/fake_resolver_test/fake_resolver_test.vcxproj
index a438391f252036844e2ed462cf75c5716f619789..8ea721dd7b47a3ed4cfe809b4c575f00f92b2910 100644
--- a/vsprojects/vcxproj/test/set_initial_connect_string_test/set_initial_connect_string_test.vcxproj
+++ b/vsprojects/vcxproj/test/fake_resolver_test/fake_resolver_test.vcxproj
@@ -20,7 +20,7 @@
     </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
-    <ProjectGuid>{4A48E5A5-2E69-ED6D-063C-C297180A54D0}</ProjectGuid>
+    <ProjectGuid>{2F59EB2E-CEF9-A291-9480-1F737C3E5E57}</ProjectGuid>
     <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
     <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
   </PropertyGroup>
@@ -60,14 +60,14 @@
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)'=='Debug'">
-    <TargetName>set_initial_connect_string_test</TargetName>
+    <TargetName>fake_resolver_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>set_initial_connect_string_test</TargetName>
+    <TargetName>fake_resolver_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,13 +158,10 @@
   </ItemDefinitionGroup>
 
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\core\client_channel\set_initial_connect_string_test.c">
+    <ClCompile Include="$(SolutionDir)\..\test\core\client_channel\resolvers\fake_resolver_test.c">
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\test_tcp_server\test_tcp_server.vcxproj">
-      <Project>{E3110C46-A148-FF65-08FD-3324829BE7FE}</Project>
-    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
       <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
     </ProjectReference>
diff --git a/vsprojects/vcxproj/test/fake_resolver_test/fake_resolver_test.vcxproj.filters b/vsprojects/vcxproj/test/fake_resolver_test/fake_resolver_test.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..353cae2b078debb5606baa1bee20cbf4e93a30cd
--- /dev/null
+++ b/vsprojects/vcxproj/test/fake_resolver_test/fake_resolver_test.vcxproj.filters
@@ -0,0 +1,24 @@
+<?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\client_channel\resolvers\fake_resolver_test.c">
+      <Filter>test\core\client_channel\resolvers</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{05f58640-4b7c-c233-bf86-f119fe270ba1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{caeef88d-baf6-603c-83b0-84b1009be480}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\client_channel">
+      <UniqueIdentifier>{c5bba556-fd85-f7b4-99b7-8b1eeb4dfcb2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\client_channel\resolvers">
+      <UniqueIdentifier>{eff74a86-6a4c-b68c-0330-6901d992c5c7}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/grpc_b64_test/grpc_b64_test.vcxproj b/vsprojects/vcxproj/test/grpc_b64_test/grpc_b64_test.vcxproj
index 7e6b4df961a34ba81752ecedae61287230acce2b..33a1d9daf1e2a715186d9b868b7dbd3750b881d3 100644
--- a/vsprojects/vcxproj/test/grpc_b64_test/grpc_b64_test.vcxproj
+++ b/vsprojects/vcxproj/test/grpc_b64_test/grpc_b64_test.vcxproj
@@ -158,7 +158,7 @@
   </ItemDefinitionGroup>
 
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\core\security\b64_test.c">
+    <ClCompile Include="$(SolutionDir)\..\test\core\slice\b64_test.c">
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
diff --git a/vsprojects/vcxproj/test/grpc_b64_test/grpc_b64_test.vcxproj.filters b/vsprojects/vcxproj/test/grpc_b64_test/grpc_b64_test.vcxproj.filters
index 4335011fe35776bb2a4161770767b7099db39a26..db2b009bb2a264174a69365d19e15b1e9a96da1e 100644
--- a/vsprojects/vcxproj/test/grpc_b64_test/grpc_b64_test.vcxproj.filters
+++ b/vsprojects/vcxproj/test/grpc_b64_test/grpc_b64_test.vcxproj.filters
@@ -1,8 +1,8 @@
 <?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\b64_test.c">
-      <Filter>test\core\security</Filter>
+    <ClCompile Include="$(SolutionDir)\..\test\core\slice\b64_test.c">
+      <Filter>test\core\slice</Filter>
     </ClCompile>
   </ItemGroup>
 
@@ -13,8 +13,8 @@
     <Filter Include="test\core">
       <UniqueIdentifier>{409b4a57-584c-1dc5-db72-1e8d4c462e9d}</UniqueIdentifier>
     </Filter>
-    <Filter Include="test\core\security">
-      <UniqueIdentifier>{0cb2c3ef-ed46-78ae-140c-29f21dc6fdb1}</UniqueIdentifier>
+    <Filter Include="test\core\slice">
+      <UniqueIdentifier>{786c8515-5a25-ca02-9df6-3ba75e55423f}</UniqueIdentifier>
     </Filter>
   </ItemGroup>
 </Project>
diff --git a/vsprojects/vcxproj/test/grpc_benchmark/grpc_benchmark.vcxproj b/vsprojects/vcxproj/test/grpc_benchmark/grpc_benchmark.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..58586f0cb8d1bebcd170c0b95e1bba543ea2aeca
--- /dev/null
+++ b/vsprojects/vcxproj/test/grpc_benchmark/grpc_benchmark.vcxproj
@@ -0,0 +1,206 @@
+<?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>{31FCED31-7D88-BE3D-2D61-0840F08E0850}</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\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_benchmark</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_benchmark</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>Windows</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>Windows</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>Windows</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>Windows</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\microbenchmarks\fullstack_context_mutators.h" />
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\microbenchmarks\fullstack_fixtures.h" />
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\microbenchmarks\helpers.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\microbenchmarks\helpers.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\benchmark\benchmark.vcxproj">
+      <Project>{07978586-E47C-8709-A63E-895FBF3C3C7D}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
+      <Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</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>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</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/grpc_benchmark/grpc_benchmark.vcxproj.filters b/vsprojects/vcxproj/test/grpc_benchmark/grpc_benchmark.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..8e865bcc1bb6ab6f24aa67be460a935473117e86
--- /dev/null
+++ b/vsprojects/vcxproj/test/grpc_benchmark/grpc_benchmark.vcxproj.filters
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\microbenchmarks\helpers.cc">
+      <Filter>test\cpp\microbenchmarks</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\microbenchmarks\fullstack_context_mutators.h">
+      <Filter>test\cpp\microbenchmarks</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\microbenchmarks\fullstack_fixtures.h">
+      <Filter>test\cpp\microbenchmarks</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\microbenchmarks\helpers.h">
+      <Filter>test\cpp\microbenchmarks</Filter>
+    </ClInclude>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{46d1162d-13b8-d144-8b76-77a6d982a9f1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp">
+      <UniqueIdentifier>{1d2b47d7-8fc3-a5b6-cc85-47e31600e9d7}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\microbenchmarks">
+      <UniqueIdentifier>{2a1ac913-6c7b-fbd2-6e8f-1215e92b4af8}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
index e5d4f0be9310893481e8239b70fba9e1d8248840..6133d7e29010262ff257809e58bfd917d07d5143 100644
--- a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
+++ b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
@@ -186,7 +186,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_helper.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\stub_options.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h" />
@@ -197,6 +196,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
@@ -205,7 +205,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
diff --git a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
index 5cba594b4803772a190e0cca36252636d70b305e..08ea8e9dae44194d6284f2623300fd875a065da0 100644
--- a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
+++ b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
@@ -90,9 +90,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_helper.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -123,6 +120,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -147,9 +147,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/grpclb_end2end_test/grpclb_end2end_test.vcxproj b/vsprojects/vcxproj/test/grpclb_end2end_test/grpclb_end2end_test.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..0a10fc60e98d1c8cbbc713865b2d0ca32d1e4db4
--- /dev/null
+++ b/vsprojects/vcxproj/test/grpclb_end2end_test/grpclb_end2end_test.vcxproj
@@ -0,0 +1,215 @@
+<?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>{15BCAA4C-F569-D5B8-50CF-F442CBC71902}</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\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>grpclb_end2end_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>grpclb_end2end_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)\..\src\proto\grpc\lb\v1\load_balancer.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\lb\v1\load_balancer.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\lb\v1\load_balancer.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\lb\v1\load_balancer.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\end2end\grpclb_end2end_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" />
+  </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/grpclb_end2end_test/grpclb_end2end_test.vcxproj.filters b/vsprojects/vcxproj/test/grpclb_end2end_test/grpclb_end2end_test.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..7b1ef956e08e4081d4b2d38adca45809207adcfb
--- /dev/null
+++ b/vsprojects/vcxproj/test/grpclb_end2end_test/grpclb_end2end_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\v1\load_balancer.proto">
+      <Filter>src\proto\grpc\lb\v1</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\end2end\grpclb_end2end_test.cc">
+      <Filter>test\cpp\end2end</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="src">
+      <UniqueIdentifier>{5ffc769b-475b-67a1-b131-2af6f6103043}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto">
+      <UniqueIdentifier>{165c6d96-aac0-d0b0-a1b4-9470159d683e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc">
+      <UniqueIdentifier>{0b3a7ccc-ea48-092f-75f1-866995a4ed04}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc\lb">
+      <UniqueIdentifier>{8f4e5440-acec-c6e3-4a3d-c8ff6ed84e11}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc\lb\v1">
+      <UniqueIdentifier>{191ccb8f-33fe-b990-20c1-87c04d15a7c2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test">
+      <UniqueIdentifier>{f501dace-533d-819c-ca99-9e0359bb67ef}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp">
+      <UniqueIdentifier>{fcbf6f3b-2707-4605-d76e-f32b545c6531}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\end2end">
+      <UniqueIdentifier>{f70e20f4-442c-b400-758d-f13abf182438}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/memory_test/memory_test.vcxproj b/vsprojects/vcxproj/test/memory_test/memory_test.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..1f4c1136ec8d7a2d0f22d48b1d61a1811552d78e
--- /dev/null
+++ b/vsprojects/vcxproj/test/memory_test/memory_test.vcxproj
@@ -0,0 +1,204 @@
+<?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>{0B674E04-7F49-A76B-3FF6-989D751B9AA4}</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\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>memory_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>memory_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\support\memory_test.cc">
+    </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>{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" />
+  </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/memory_test/memory_test.vcxproj.filters b/vsprojects/vcxproj/test/memory_test/memory_test.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..01a89346d2f3b8e1d280b0ec6a1144492dbc97f0
--- /dev/null
+++ b/vsprojects/vcxproj/test/memory_test/memory_test.vcxproj.filters
@@ -0,0 +1,21 @@
+<?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\memory_test.cc">
+      <Filter>test\core\support</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{80245c10-56a8-a6ec-0abc-8125f4271d38}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{eb61342c-1b95-756a-8b70-42aeb2a55f59}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\support">
+      <UniqueIdentifier>{8c8dfaee-c0b7-e843-c50e-427448fe1eb9}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/minimal_stack_is_minimal_test/minimal_stack_is_minimal_test.vcxproj b/vsprojects/vcxproj/test/minimal_stack_is_minimal_test/minimal_stack_is_minimal_test.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..0473fa954575bade944eed6a846888b1a926cd52
--- /dev/null
+++ b/vsprojects/vcxproj/test/minimal_stack_is_minimal_test/minimal_stack_is_minimal_test.vcxproj
@@ -0,0 +1,199 @@
+<?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>{68A54124-DFA3-4FF3-081F-70356222C977}</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>minimal_stack_is_minimal_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>minimal_stack_is_minimal_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\channel\minimal_stack_is_minimal_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/minimal_stack_is_minimal_test/minimal_stack_is_minimal_test.vcxproj.filters b/vsprojects/vcxproj/test/minimal_stack_is_minimal_test/minimal_stack_is_minimal_test.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..7eb2ba551f5a85f616d2afbf4dc89bf9a5f73fbb
--- /dev/null
+++ b/vsprojects/vcxproj/test/minimal_stack_is_minimal_test/minimal_stack_is_minimal_test.vcxproj.filters
@@ -0,0 +1,21 @@
+<?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\channel\minimal_stack_is_minimal_test.c">
+      <Filter>test\core\channel</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{52e0de0c-9f7d-1497-1339-b0ed30ed41f8}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{2cd01454-1131-89cc-68a2-10365fa32bb0}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\channel">
+      <UniqueIdentifier>{f473b99d-5602-d2df-2d85-99648d00ba4f}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/mock_test/mock_test.vcxproj b/vsprojects/vcxproj/test/mock_test/mock_test.vcxproj
index 8c840fd5be902b345e94febc95a0db1a4dd2958e..bc1cae591172401fa349dd588892a3ee4d7482e8 100644
--- a/vsprojects/vcxproj/test/mock_test/mock_test.vcxproj
+++ b/vsprojects/vcxproj/test/mock_test/mock_test.vcxproj
@@ -159,6 +159,9 @@
     </Link>
   </ItemDefinitionGroup>
 
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\test\mock_stream.h" />
+  </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\end2end\mock_test.cc">
     </ClCompile>
diff --git a/vsprojects/vcxproj/test/mock_test/mock_test.vcxproj.filters b/vsprojects/vcxproj/test/mock_test/mock_test.vcxproj.filters
index 1b3b773b08fc1227c64bc47056306a4190e39902..6db61c9037b783eea98eaa24d63d411735033a57 100644
--- a/vsprojects/vcxproj/test/mock_test/mock_test.vcxproj.filters
+++ b/vsprojects/vcxproj/test/mock_test/mock_test.vcxproj.filters
@@ -5,8 +5,22 @@
       <Filter>test\cpp\end2end</Filter>
     </ClCompile>
   </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\test\mock_stream.h">
+      <Filter>include\grpc++\test</Filter>
+    </ClInclude>
+  </ItemGroup>
 
   <ItemGroup>
+    <Filter Include="include">
+      <UniqueIdentifier>{b827d6d2-cfa5-2dd4-6ebc-afcccd5e8e0c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++">
+      <UniqueIdentifier>{28289e8f-b68e-b9f5-7680-c15d77b574a5}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++\test">
+      <UniqueIdentifier>{4a7b43be-c730-6221-d190-e394521f9ae7}</UniqueIdentifier>
+    </Filter>
     <Filter Include="test">
       <UniqueIdentifier>{69c257a2-3e4c-a86e-ce0d-1a97b237d294}</UniqueIdentifier>
     </Filter>
diff --git a/vsprojects/vcxproj/test/parse_address_test/parse_address_test.vcxproj b/vsprojects/vcxproj/test/parse_address_test/parse_address_test.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..17046708f9244e7f432771ca2294395b7f2231f2
--- /dev/null
+++ b/vsprojects/vcxproj/test/parse_address_test/parse_address_test.vcxproj
@@ -0,0 +1,199 @@
+<?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>{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}</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>parse_address_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>parse_address_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\client_channel\parse_address_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/set_initial_connect_string_test/set_initial_connect_string_test.vcxproj.filters b/vsprojects/vcxproj/test/parse_address_test/parse_address_test.vcxproj.filters
similarity index 69%
rename from vsprojects/vcxproj/test/set_initial_connect_string_test/set_initial_connect_string_test.vcxproj.filters
rename to vsprojects/vcxproj/test/parse_address_test/parse_address_test.vcxproj.filters
index 4422a3e79256dc80ec53cb633619854786a2f381..e4e446da99734591da4044250fb11383a6f71624 100644
--- a/vsprojects/vcxproj/test/set_initial_connect_string_test/set_initial_connect_string_test.vcxproj.filters
+++ b/vsprojects/vcxproj/test/parse_address_test/parse_address_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\client_channel\set_initial_connect_string_test.c">
+    <ClCompile Include="$(SolutionDir)\..\test\core\client_channel\parse_address_test.c">
       <Filter>test\core\client_channel</Filter>
     </ClCompile>
   </ItemGroup>
 
   <ItemGroup>
     <Filter Include="test">
-      <UniqueIdentifier>{413358e4-3165-f09d-071c-ee4f2ca0b826}</UniqueIdentifier>
+      <UniqueIdentifier>{1613c595-3fdf-b7ab-6d5f-667bbd7eefc7}</UniqueIdentifier>
     </Filter>
     <Filter Include="test\core">
-      <UniqueIdentifier>{a554b5ef-0c80-ac03-1848-bccd947a06a6}</UniqueIdentifier>
+      <UniqueIdentifier>{cdfde21c-75c2-08ee-3d98-8ca67b5c31e0}</UniqueIdentifier>
     </Filter>
     <Filter Include="test\core\client_channel">
-      <UniqueIdentifier>{4726253c-a562-0ace-2798-996807381208}</UniqueIdentifier>
+      <UniqueIdentifier>{60d8328d-ca06-b3cf-cf1d-889b6677def1}</UniqueIdentifier>
     </Filter>
   </ItemGroup>
 </Project>
diff --git a/vsprojects/vcxproj/test/proto_utils_test/proto_utils_test.vcxproj b/vsprojects/vcxproj/test/proto_utils_test/proto_utils_test.vcxproj
index fc2355624f8097fe896fe0010118f6ffc1c1d481..397e7b6901f89b21d5bed7aa202c386dcfa1df68 100644
--- a/vsprojects/vcxproj/test/proto_utils_test/proto_utils_test.vcxproj
+++ b/vsprojects/vcxproj/test/proto_utils_test/proto_utils_test.vcxproj
@@ -185,7 +185,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_helper.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\stub_options.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h" />
@@ -196,6 +195,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
@@ -204,7 +204,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
diff --git a/vsprojects/vcxproj/test/proto_utils_test/proto_utils_test.vcxproj.filters b/vsprojects/vcxproj/test/proto_utils_test/proto_utils_test.vcxproj.filters
index e6b4a924589e69650de045401155c924a806b219..2f5a2a065f3d1491ca62a84f2a24adde0d19540c 100644
--- a/vsprojects/vcxproj/test/proto_utils_test/proto_utils_test.vcxproj.filters
+++ b/vsprojects/vcxproj/test/proto_utils_test/proto_utils_test.vcxproj.filters
@@ -81,9 +81,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_helper.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -114,6 +111,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -138,9 +138,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/server_builder_test/server_builder_test.vcxproj b/vsprojects/vcxproj/test/server_builder_test/server_builder_test.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..ebbfd59f3d3c0f748b25dc3c0a3efa27de0fe7b1
--- /dev/null
+++ b/vsprojects/vcxproj/test/server_builder_test/server_builder_test.vcxproj
@@ -0,0 +1,223 @@
+<?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>{60523734-00BD-765B-5A5B-19E19A2E31B8}</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\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>server_builder_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>server_builder_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)\..\src\proto\grpc\testing\echo_messages.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\server\server_builder_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\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</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\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/server_builder_test/server_builder_test.vcxproj.filters b/vsprojects/vcxproj/test/server_builder_test/server_builder_test.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..c323b7a673121124133d8e7dbaf0d4454c127cdd
--- /dev/null
+++ b/vsprojects/vcxproj/test/server_builder_test/server_builder_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\testing\echo_messages.proto">
+      <Filter>src\proto\grpc\testing</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.proto">
+      <Filter>src\proto\grpc\testing</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\server\server_builder_test.cc">
+      <Filter>test\cpp\server</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="src">
+      <UniqueIdentifier>{828e0ffc-a89a-de93-ae06-706d522188a1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto">
+      <UniqueIdentifier>{538db689-e85f-c369-7020-8d78e0ee5049}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc">
+      <UniqueIdentifier>{351168ef-9b4f-6165-ff4f-0e13781910db}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc\testing">
+      <UniqueIdentifier>{530a1a67-0a37-50f8-42d0-7ccf0ec34cfc}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test">
+      <UniqueIdentifier>{67afe178-6a18-fd24-bbe6-656fee5a5f10}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp">
+      <UniqueIdentifier>{aaa8777b-1bc3-abaa-5e6d-28040c5aa213}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\server">
+      <UniqueIdentifier>{af770080-f515-c773-3ae0-243d5929bbd0}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/slice_hash_table_test/slice_hash_table_test.vcxproj b/vsprojects/vcxproj/test/slice_hash_table_test/slice_hash_table_test.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..0fccfdcaa5607878b0bf4a9c19979bdc56d4a302
--- /dev/null
+++ b/vsprojects/vcxproj/test/slice_hash_table_test/slice_hash_table_test.vcxproj
@@ -0,0 +1,199 @@
+<?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>{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}</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>slice_hash_table_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>slice_hash_table_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\slice\slice_hash_table_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/slice_hash_table_test/slice_hash_table_test.vcxproj.filters b/vsprojects/vcxproj/test/slice_hash_table_test/slice_hash_table_test.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..19738526781103dec73cd1f2e3206180981cb221
--- /dev/null
+++ b/vsprojects/vcxproj/test/slice_hash_table_test/slice_hash_table_test.vcxproj.filters
@@ -0,0 +1,21 @@
+<?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\slice\slice_hash_table_test.c">
+      <Filter>test\core\slice</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{e11f5007-84da-0229-9118-2a2bb17f956c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{a11f4770-5e13-eb1a-a848-8667dde98812}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\slice">
+      <UniqueIdentifier>{fb1262a8-0a70-bc85-579a-6ebfffbf25b5}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/stream_owned_slice_test/stream_owned_slice_test.vcxproj b/vsprojects/vcxproj/test/stream_owned_slice_test/stream_owned_slice_test.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..09279e325daf9a4fba8ced6956ad69572fba90ce
--- /dev/null
+++ b/vsprojects/vcxproj/test/stream_owned_slice_test/stream_owned_slice_test.vcxproj
@@ -0,0 +1,199 @@
+<?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>{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}</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>stream_owned_slice_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>stream_owned_slice_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\transport\stream_owned_slice_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/stream_owned_slice_test/stream_owned_slice_test.vcxproj.filters b/vsprojects/vcxproj/test/stream_owned_slice_test/stream_owned_slice_test.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..9a412021972fd8512e2fc2fcc0de31de1299e6ae
--- /dev/null
+++ b/vsprojects/vcxproj/test/stream_owned_slice_test/stream_owned_slice_test.vcxproj.filters
@@ -0,0 +1,21 @@
+<?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\transport\stream_owned_slice_test.c">
+      <Filter>test\core\transport</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{5606d0c3-ce6d-0d92-aaa6-4cba3360af30}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{c89700dc-cc90-bd03-00e7-36ee75d20c07}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\transport">
+      <UniqueIdentifier>{faebe48f-9338-a5a4-439d-9f307d0b843b}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/stress_test/stress_test.vcxproj b/vsprojects/vcxproj/test/stress_test/stress_test.vcxproj
index fed916f50a966eaee18137052ac0cff859ff336f..2944a31c4835a4157ba1377426fbe0d954272325 100644
--- a/vsprojects/vcxproj/test/stress_test/stress_test.vcxproj
+++ b/vsprojects/vcxproj/test/stress_test/stress_test.vcxproj
@@ -205,8 +205,6 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\interop\stress_test.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\create_test_channel.cc">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\metrics_server.cc">
     </ClCompile>
   </ItemGroup>
diff --git a/vsprojects/vcxproj/test/stress_test/stress_test.vcxproj.filters b/vsprojects/vcxproj/test/stress_test/stress_test.vcxproj.filters
index 9339621c8d1940def4e4c6b16f14a97c79fba194..83dc09a1d4beccd07ae41be33104079f6f418435 100644
--- a/vsprojects/vcxproj/test/stress_test/stress_test.vcxproj.filters
+++ b/vsprojects/vcxproj/test/stress_test/stress_test.vcxproj.filters
@@ -22,9 +22,6 @@
     <ClCompile Include="$(SolutionDir)\..\test\cpp\interop\stress_test.cc">
       <Filter>test\cpp\interop</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\create_test_channel.cc">
-      <Filter>test\cpp\util</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\metrics_server.cc">
       <Filter>test\cpp\util</Filter>
     </ClCompile>